github.com/kiali/kiali@v1.84.0/business/checkers/destinationrules/traffic_policy_checker_test.go (about)

     1  package destinationrules
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
     8  
     9  	"github.com/kiali/kiali/kubernetes"
    10  	"github.com/kiali/kiali/models"
    11  	"github.com/kiali/kiali/tests/data"
    12  	"github.com/kiali/kiali/tests/testutils/validations"
    13  )
    14  
    15  // Context: MeshPolicy Enabling mTLS
    16  // Context: DestinationRule doesn't specify trafficPolicy
    17  // It returns a validation
    18  func TestMTLSMeshWideEnabledDRWithoutTrafficPolicy(t *testing.T) {
    19  	mTLSDetails := kubernetes.MTLSDetails{
    20  		DestinationRules: []*networking_v1beta1.DestinationRule{
    21  			// Mesh-wide DR enabling mTLS communication
    22  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    23  				data.CreateEmptyDestinationRule("istio-system", "default", "*.local")),
    24  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    25  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.bookinfo.svc.cluster.local")),
    26  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    27  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    28  		},
    29  	}
    30  
    31  	destinationRules := []*networking_v1beta1.DestinationRule{
    32  		// Subject DR that doesn't specify any trafficPolicy
    33  		data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews"),
    34  	}
    35  
    36  	validation := testValidationAdded(t, destinationRules, mTLSDetails)
    37  	presentReferences(t, *validation, "istio-system", []string{"default"})
    38  	presentReferences(t, *validation, "bookinfo", []string{"default"})
    39  }
    40  
    41  // Context: MeshPolicy Enabling mTLS
    42  // Context: DestinationRule doesn't specify mTLS options
    43  // It returns a validation
    44  func TestMTLSMeshWideEnabledDRWithoutmTLSOptions(t *testing.T) {
    45  	mTLSDetails := kubernetes.MTLSDetails{
    46  		DestinationRules: []*networking_v1beta1.DestinationRule{
    47  			// Mesh-wide DR enabling mTLS communication
    48  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    49  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.local")),
    50  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    51  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    52  		},
    53  	}
    54  
    55  	destinationRules := []*networking_v1beta1.DestinationRule{
    56  		// Subject DR that specify trafficPolicy but no mTLS options
    57  		data.AddTrafficPolicyToDestinationRule(data.CreateLoadBalancerTrafficPolicyForDestinationRules(),
    58  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    59  	}
    60  
    61  	testValidationAdded(t, destinationRules, mTLSDetails)
    62  }
    63  
    64  // Context: MeshPolicy Enabling mTLS
    65  // Context: DestinationRule doesn't specify port-level mTLS options
    66  // It returns a validation
    67  func TestMTLSMeshWideEnabledDRWithoutPortLevelmTLSOptions(t *testing.T) {
    68  	mTLSDetails := kubernetes.MTLSDetails{
    69  		DestinationRules: []*networking_v1beta1.DestinationRule{
    70  			// Mesh-wide DR enabling mTLS communication
    71  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    72  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.local")),
    73  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    74  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    75  		},
    76  	}
    77  
    78  	destinationRules := []*networking_v1beta1.DestinationRule{
    79  		// Subject DR that specify trafficPolicy but no mTLS options
    80  		data.AddTrafficPolicyToDestinationRule(data.CreatePortLevelTrafficPolicyForDestinationRules(),
    81  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    82  	}
    83  
    84  	testValidationAdded(t, destinationRules, mTLSDetails)
    85  }
    86  
    87  // Context: MeshPolicy Enabling mTLS
    88  // Context: DestinationRule does specify trafficPolicy and mTLS options
    89  // It doesn't return any validation
    90  func TestMTLSMeshWideEnabledDRWithTrafficPolicy(t *testing.T) {
    91  	mTLSDetails := kubernetes.MTLSDetails{
    92  		DestinationRules: []*networking_v1beta1.DestinationRule{
    93  			// Mesh-wide DR enabling mTLS communication
    94  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    95  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.local")),
    96  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
    97  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
    98  		},
    99  	}
   100  
   101  	destinationRules := []*networking_v1beta1.DestinationRule{
   102  		// Subject DR that specify TrafficPolicy
   103  		data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   104  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   105  	}
   106  
   107  	testValidationsNotAdded(t, destinationRules, mTLSDetails)
   108  }
   109  
   110  // Context: MeshPolicy Enabling mTLS
   111  // Context: DestinationRule does specify trafficPolicy and TLS options
   112  // It doesn't return any validation
   113  func TestMTLSMeshWideEnabledDRWithPortLevelTLSTrafficPolicy(t *testing.T) {
   114  	mTLSDetails := kubernetes.MTLSDetails{
   115  		DestinationRules: []*networking_v1beta1.DestinationRule{
   116  			// Mesh-wide DR enabling mTLS communication
   117  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   118  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.local")),
   119  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   120  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   121  		},
   122  	}
   123  
   124  	destinationRules := []*networking_v1beta1.DestinationRule{
   125  		// Subject DR that specify TrafficPolicy
   126  		data.AddTrafficPolicyToDestinationRule(data.CreateTLSPortLevelTrafficPolicyForDestinationRules(),
   127  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   128  	}
   129  
   130  	testValidationsNotAdded(t, destinationRules, mTLSDetails)
   131  }
   132  
   133  // Context: Namespace-wide mTLS enabled
   134  // Context: DestinationRule doesn't specify trafficPolicy
   135  // It returns a validation
   136  func TestNamespacemTLSEnabledDRWithoutTrafficPolicy(t *testing.T) {
   137  	mTLSDetails := kubernetes.MTLSDetails{
   138  		DestinationRules: []*networking_v1beta1.DestinationRule{
   139  			// Namespace-wide DR enabling mTLS communication
   140  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   141  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.bookinfo.svc.cluster.local")),
   142  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   143  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   144  		},
   145  	}
   146  
   147  	destinationRules := []*networking_v1beta1.DestinationRule{
   148  		// Subject DR that doesn't specify any trafficPolicy
   149  		data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews"),
   150  	}
   151  
   152  	testValidationAdded(t, destinationRules, mTLSDetails)
   153  }
   154  
   155  // Context: Namespace-wide mTLS enabled
   156  // Context: DestinationRule doesn't specify mTLS options
   157  // It returns a validation
   158  func TestNamespacemTLSEnabledDRWithoutmTLSOptions(t *testing.T) {
   159  	mTLSDetails := kubernetes.MTLSDetails{
   160  		DestinationRules: []*networking_v1beta1.DestinationRule{
   161  			// Namespace-wide DR enabling mTLS communication
   162  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   163  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.bookinfo.svc.cluster.local")),
   164  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   165  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   166  		},
   167  	}
   168  
   169  	destinationRules := []*networking_v1beta1.DestinationRule{
   170  		// Subject DR that specify trafficPolicy but no mTLS options
   171  		data.AddTrafficPolicyToDestinationRule(data.CreateLoadBalancerTrafficPolicyForDestinationRules(),
   172  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   173  	}
   174  
   175  	testValidationAdded(t, destinationRules, mTLSDetails)
   176  }
   177  
   178  // Context: Namespace-wide mTLS enabled
   179  // Context: DestinationRule does specify trafficPolicy
   180  // It doesn't return any validation
   181  func TestNamespacemTLSEnabledDRWithTrafficPolicy(t *testing.T) {
   182  	mTLSDetails := kubernetes.MTLSDetails{
   183  		DestinationRules: []*networking_v1beta1.DestinationRule{
   184  			// Namespace-wide DR enabling mTLS communication
   185  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   186  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.local")),
   187  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   188  				data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   189  		},
   190  	}
   191  
   192  	destinationRules := []*networking_v1beta1.DestinationRule{
   193  		// Subject DR that specify trafficPolicy and mTLS options
   194  		data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   195  			data.CreateEmptyDestinationRule("bookinfo", "reviews", "reviews")),
   196  	}
   197  
   198  	testValidationsNotAdded(t, destinationRules, mTLSDetails)
   199  }
   200  
   201  // Context: Namespace-wide mTLS enabled
   202  // Context: DestinationRule doesn't specify trafficPolicy and host is from other namespace
   203  // It doesn't return any validation
   204  func TestCrossNamespaceProtection(t *testing.T) {
   205  	mTLSDetails := kubernetes.MTLSDetails{
   206  		DestinationRules: []*networking_v1beta1.DestinationRule{
   207  			// Namespace-wide DR enabling mTLS communication
   208  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   209  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.bookinfo.svc.cluster.local")),
   210  		},
   211  	}
   212  
   213  	destinationRules := []*networking_v1beta1.DestinationRule{
   214  		data.AddTrafficPolicyToDestinationRule(data.CreateLoadBalancerTrafficPolicyForDestinationRules(),
   215  			data.CreateEmptyDestinationRule("other", "reviews", "reviews.other.svc.cluster.local")),
   216  	}
   217  
   218  	testValidationsNotAdded(t, destinationRules, mTLSDetails)
   219  }
   220  
   221  // Context: Namespace-wide mTLS enabled
   222  // Context: DestinationRule doesn't specify trafficPolicy and host is from a ServiceEntry
   223  // It doesn't return any validation
   224  func TestCrossNamespaceServiceEntryProtection(t *testing.T) {
   225  	mTLSDetails := kubernetes.MTLSDetails{
   226  		DestinationRules: []*networking_v1beta1.DestinationRule{
   227  			// Namespace-wide DR enabling mTLS communication
   228  			data.AddTrafficPolicyToDestinationRule(data.CreateMTLSTrafficPolicyForDestinationRules(),
   229  				data.CreateEmptyDestinationRule("bookinfo", "default", "*.bookinfo.svc.cluster.local")),
   230  		},
   231  	}
   232  
   233  	destinationRules := []*networking_v1beta1.DestinationRule{
   234  		// Subject DR that specify trafficPolicy and mTLS options
   235  		data.AddTrafficPolicyToDestinationRule(data.CreateLoadBalancerTrafficPolicyForDestinationRules(),
   236  			data.CreateEmptyDestinationRule("other", "service-entry-dr", "wikipedia.org")),
   237  	}
   238  
   239  	testValidationsNotAdded(t, destinationRules, mTLSDetails)
   240  }
   241  
   242  func testValidationAdded(t *testing.T, destinationRules []*networking_v1beta1.DestinationRule, mTLSDetails kubernetes.MTLSDetails) *models.IstioValidation {
   243  	assert := assert.New(t)
   244  
   245  	vals := TrafficPolicyChecker{
   246  		DestinationRules: destinationRules,
   247  		MTLSDetails:      mTLSDetails,
   248  	}.Check()
   249  
   250  	assert.NotEmpty(vals)
   251  	assert.Equal(1, len(vals))
   252  
   253  	validation, ok := vals[models.BuildKey(DestinationRulesCheckerType, "reviews", "bookinfo")]
   254  	assert.True(ok)
   255  	assert.True(validation.Valid)
   256  
   257  	assert.NotEmpty(validation.Checks)
   258  	assert.Equal(models.WarningSeverity, validation.Checks[0].Severity)
   259  	assert.Equal("spec/trafficPolicy", validation.Checks[0].Path)
   260  	assert.NoError(validations.ConfirmIstioCheckMessage("destinationrules.trafficpolicy.notlssettings", validation.Checks[0]))
   261  
   262  	assert.True(len(validation.References) > 0)
   263  	return validation
   264  }
   265  
   266  func testValidationsNotAdded(t *testing.T, destinationRules []*networking_v1beta1.DestinationRule, mTLSDetails kubernetes.MTLSDetails) {
   267  	assert := assert.New(t)
   268  
   269  	vals := TrafficPolicyChecker{
   270  		DestinationRules: destinationRules,
   271  		MTLSDetails:      mTLSDetails,
   272  	}.Check()
   273  
   274  	assert.Empty(vals)
   275  	validation, ok := vals[models.BuildKey(DestinationRulesCheckerType, "reviews", "bookinfo")]
   276  
   277  	assert.False(ok)
   278  	assert.Nil(validation)
   279  }
   280  
   281  func presentReferences(t *testing.T, validation models.IstioValidation, ns string, serviceNames []string) {
   282  	assert := assert.New(t)
   283  	assert.True(len(validation.References) > 0)
   284  
   285  	for _, sn := range serviceNames {
   286  		refKey := models.IstioValidationKey{ObjectType: "destinationrule", Namespace: ns, Name: sn}
   287  		assert.Contains(validation.References, refKey)
   288  	}
   289  }