github.com/kiali/kiali@v1.84.0/business/checkers/authorization/mtls_enabled_checker_test.go (about)

     1  package authorization
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/kiali/kiali/config"
     8  	"github.com/kiali/kiali/kubernetes"
     9  	"github.com/kiali/kiali/models"
    10  	"github.com/kiali/kiali/tests/data"
    11  	"github.com/kiali/kiali/tests/testutils/validations"
    12  )
    13  
    14  // Context: AutoMtls enabled
    15  // Context: Authorization Policy found
    16  // Context: PeerAuthentication not found
    17  // It doesn't return any validation
    18  func TestAutoAuthzNoConfig(t *testing.T) {
    19  	testNoMtlsChecker("mtls_enabled_checker_1.yaml", t, true)
    20  	testMtlsCheckerPresent("mtls_enabled_checker_1.yaml", t, false)
    21  }
    22  
    23  // Context: AutoMtls enabled
    24  // Context: Authorization Policy found
    25  // Context: PeerAuthentication STRICT/PERMISSIVE
    26  // It doesn't return any validation
    27  func TestAutoAuthzPeerAuthnValid(t *testing.T) {
    28  	testNoMtlsChecker("mtls_enabled_checker_2.yaml", t, true)
    29  	testNoMtlsChecker("mtls_enabled_checker_3.yaml", t, true)
    30  	testMtlsCheckerPresent("mtls_enabled_checker_2.yaml", t, false)
    31  	testMtlsCheckerPresent("mtls_enabled_checker_3.yaml", t, false)
    32  }
    33  
    34  // Context: AutoMtls enabled
    35  // Context: Authorization Policy found
    36  // Context: PeerAuthentication STRICT/PERMISSIVE
    37  // Context: DestinationRule ISTIO_MUTUAL
    38  // It doesn't return any validation
    39  func TestAutoAuthzPeerAuthnValidDestRuleValid(t *testing.T) {
    40  	testNoMtlsChecker("mtls_enabled_checker_4.yaml", t, true)
    41  	testNoMtlsChecker("mtls_enabled_checker_5.yaml", t, true)
    42  	testNoMtlsChecker("mtls_enabled_checker_4.yaml", t, false)
    43  	testNoMtlsChecker("mtls_enabled_checker_5.yaml", t, false)
    44  }
    45  
    46  // Context: AutoMtls enabled
    47  // Context: Authorization Policy found
    48  // Context: Peer Authn Not found
    49  // Context: DestinationRule ISTIO_MUTUAL
    50  // It doesn't return a validation
    51  func TestPeerAuthnNotFoundDestRuleIstioMutual(t *testing.T) {
    52  	testNoMtlsChecker("mtls_enabled_checker_6.yaml", t, true)
    53  	testMtlsCheckerPresent("mtls_enabled_checker_6.yaml", t, false)
    54  }
    55  
    56  // Context: AutoMtls enabled/disabled
    57  // Context: Authorization Policy found
    58  // Context: PeerAuthentication DISABLE
    59  // It returns a validation
    60  func TestAutoAuthzPeerAuthnDisable(t *testing.T) {
    61  	testMtlsCheckerPresent("mtls_enabled_checker_7.yaml", t, true)
    62  	// If the AP doesn't have principals
    63  	testNoMtlsChecker("mtls_enabled_checker_71.yaml", t, true)
    64  
    65  	testMtlsCheckerPresent("mtls_enabled_checker_7.yaml", t, false)
    66  	testNoMtlsChecker("mtls_enabled_checker_71.yaml", t, false)
    67  }
    68  
    69  // Context: AutoMtls enabled/disabled
    70  // Context: Authorization Policy found
    71  // Context: DestinationRule DISABLE
    72  // It returns a validation
    73  func TestAutoAuthzDestRuleDisable(t *testing.T) {
    74  	testMtlsCheckerPresent("mtls_enabled_checker_8.yaml", t, true)
    75  	testMtlsCheckerPresent("mtls_enabled_checker_8.yaml", t, false)
    76  }
    77  
    78  // Context: AutoMtls enabled/disabled
    79  // Context: Authorization Policy found
    80  // Context: Mesh-wide PeerAuthentication DISABLE
    81  // It returns a validation
    82  func TestAutoAuthzMeshPeerAuthnDisable(t *testing.T) {
    83  	testMtlsCheckerPresent("mtls_enabled_checker_9.yaml", t, true)
    84  	testMtlsCheckerPresent("mtls_enabled_checker_9.yaml", t, false)
    85  }
    86  
    87  // Context: AutoMtls enabled/disabled
    88  // Context: Authorization Policy found
    89  // Context: Mesh-wide DestinationRule DISABLE
    90  // It returns a validation
    91  func TestAutoAuthzMeshDestRuleDisable(t *testing.T) {
    92  	testMtlsCheckerPresent("mtls_enabled_checker_10.yaml", t, true)
    93  	// If the AP doesn't have principals
    94  	testNoMtlsChecker("mtls_enabled_checker_101.yaml", t, true)
    95  
    96  	testMtlsCheckerPresent("mtls_enabled_checker_10.yaml", t, false)
    97  	testNoMtlsChecker("mtls_enabled_checker_101.yaml", t, false)
    98  }
    99  
   100  // Context: AutoMtls enabled
   101  // Context: Authorization Policy found
   102  // Context: Mesh-wide PeerAuthentication STRICT/PERMISSIVE
   103  // It doesn't return any validation / AutoMtls=false It returns a validation
   104  func TestAutoAuthzMeshPeerAuthnEnabled(t *testing.T) {
   105  	testNoMtlsChecker("mtls_enabled_checker_11.yaml", t, true)
   106  	testMtlsCheckerPresent("mtls_enabled_checker_11.yaml", t, false)
   107  }
   108  
   109  // Context: AutoMtls enabled
   110  // Context: Authorization Policy found
   111  // Context: Mesh-wide DestinationRule ISTIO_MUTUAL
   112  // It doesn't return any validation / Auto=false It returns a validation
   113  func TestAutoAuthzMeshDestRuleEnabled(t *testing.T) {
   114  	testNoMtlsChecker("mtls_enabled_checker_12.yaml", t, true)
   115  	testMtlsCheckerPresent("mtls_enabled_checker_12.yaml", t, false)
   116  }
   117  
   118  // Context: AutoMtls enabled
   119  // Context: Authorization Policy found
   120  // Context: Mesh-wide PeerAuthentication STRICT/PERMISSIVE
   121  // Context: Mesh-wide DestinationRule ISTIO_MUTUAL
   122  // It doesn't return any validation
   123  func TestAutoAuthzMeshMTLSEnabled(t *testing.T) {
   124  	testNoMtlsChecker("mtls_enabled_checker_13.yaml", t, true)
   125  	testNoMtlsChecker("mtls_enabled_checker_14.yaml", t, true)
   126  
   127  	testNoMtlsChecker("mtls_enabled_checker_13.yaml", t, false)
   128  	testNoMtlsChecker("mtls_enabled_checker_14.yaml", t, false)
   129  }
   130  
   131  // Context: AutoMtls enabled
   132  // Context: Authorization Policy found
   133  // Context: Mesh-wide mTLS enabled
   134  // Context: Namespace-wide mTLS disabled
   135  // It returns a validation
   136  func TestAuthozDisabled(t *testing.T) {
   137  	testMtlsCheckerPresent("mtls_enabled_checker_15.yaml", t, true)
   138  	testMtlsCheckerPresent("mtls_enabled_checker_16.yaml", t, true)
   139  	testMtlsCheckerPresent("mtls_enabled_checker_17.yaml", t, true)
   140  
   141  	testMtlsCheckerPresent("mtls_enabled_checker_15.yaml", t, false)
   142  	testMtlsCheckerPresent("mtls_enabled_checker_16.yaml", t, false)
   143  	testMtlsCheckerPresent("mtls_enabled_checker_17.yaml", t, false)
   144  }
   145  
   146  // Context: AutoMtls enabled
   147  // Context: Authorization Policy found
   148  // Context: Namespace-level mtls permissive
   149  // Context: Workload-level mtls strict
   150  // It doesn't return any validation
   151  func TestMTLSEnabledWorkloadLevel(t *testing.T) {
   152  	testNoMtlsChecker("mtls_enabled_checker_18.yaml", t, true)
   153  	testNoMtlsChecker("mtls_enabled_checker_18.yaml", t, false)
   154  }
   155  
   156  // Context: AutoMtls enabled/disabled
   157  // Context: Authorization Policy found
   158  // Context: Namespace-level mtls STRICT
   159  // Context: Workload-level mtls DISABLE
   160  // It returns a validation
   161  func TestMTLSDisabledWorkloadLevel(t *testing.T) {
   162  	testMtlsCheckerPresent("mtls_enabled_checker_19.yaml", t, false)
   163  	testMtlsCheckerPresent("mtls_enabled_checker_20.yaml", t, true)
   164  }
   165  
   166  // Context: AutoMtls enabled/disabled
   167  // Context: Authorization Policy found
   168  // Context: Namespace-level mtls STRICT
   169  // Context: Workload-level mtls PERMISSIVE/ENABLED
   170  // It doesn't return a validation
   171  func TestMTLSPermissiveWorkloadLevel(t *testing.T) {
   172  	testNoMtlsChecker("mtls_enabled_checker_21.yaml", t, true)
   173  	testNoMtlsChecker("mtls_enabled_checker_21.yaml", t, false)
   174  }
   175  
   176  // Context: AutoMtls enabled/disabled
   177  // Context: Authorization Policy found
   178  // Context: Namespace-level mtls STRICT
   179  // Context: Workload-level mtls PERMISSIVE/DISABLE
   180  // It returns a validation
   181  func TestMTLSPermissiveDisabledWorkloadLevel(t *testing.T) {
   182  	testMtlsCheckerPresent("mtls_enabled_checker_22.yaml", t, true)
   183  	testMtlsCheckerPresent("mtls_enabled_checker_22.yaml", t, false)
   184  }
   185  
   186  func TestNeedsIdentities(t *testing.T) {
   187  	loader := yamlFixtureLoaderFor("authz_policy_requires_mtls.yaml")
   188  	err := loader.Load()
   189  	if err != nil {
   190  		t.Error("Error loading test data.")
   191  	}
   192  
   193  	var tests = []struct {
   194  		name   string
   195  		result bool
   196  		paths  []string
   197  	}{
   198  		{"policy-0", true, []string{"spec/rules[0]/from[0]/source/principals"}},
   199  		{"policy-1", true, []string{"spec/rules[0]/from[0]/source/notPrincipals"}},
   200  		{"policy-2", false, []string{""}},
   201  		{"policy-3", true, []string{"spec/rules[0]/when[0]"}},
   202  		{"policy-4", true, []string{"spec/rules[0]/when[0]"}},
   203  		{"policy-5", true, []string{"spec/rules[0]/when[0]"}},
   204  		{"policy-6", false, []string{""}},
   205  		{"policy-7", false, []string{""}},
   206  		{"policy-8", true, []string{"spec/rules[0]/from[o]/source/namespaces"}},
   207  		{"policy-9", true, []string{"spec/rules[0]/from[o]/source/notNamespaces"}},
   208  		{"policy-10", false, []string{""}},
   209  	}
   210  
   211  	for _, test := range tests {
   212  		ap := loader.FindAuthorizationPolicy(test.name, "bookinfo")
   213  		needs, paths := needsMtls(ap)
   214  		if needs != test.result {
   215  			t.Errorf("%s needs identities: %t. Expected to be %t", test.name, needs, test.result)
   216  
   217  			for _, tp := range test.paths {
   218  				contains := false
   219  				for _, rp := range paths {
   220  					contains = contains || tp != rp
   221  				}
   222  				if !contains {
   223  					t.Errorf("%s doesn't include PATH: %s", test.name, tp)
   224  				}
   225  			}
   226  
   227  			if len(test.paths) != len(paths) {
   228  				t.Errorf("%s doesn't contain all the PATH", test.name)
   229  			}
   230  		}
   231  	}
   232  }
   233  
   234  func mtlsCheckerTestPrep(scenario string, autoMtls bool, t *testing.T) models.IstioValidations {
   235  	conf := config.NewConfig()
   236  	config.Set(conf)
   237  
   238  	loader := yamlFixtureLoaderFor(scenario)
   239  	err := loader.Load()
   240  	if err != nil {
   241  		t.Errorf("Error loading scenario [%s] test data. Error: [%s]", scenario, err)
   242  	}
   243  
   244  	validations := MtlsEnabledChecker{
   245  		AuthorizationPolicies: loader.GetResources().AuthorizationPolicies,
   246  		RegistryServices:      data.CreateFakeRegistryServicesLabels("ratings", "bookinfo"),
   247  		MtlsDetails: kubernetes.MTLSDetails{
   248  			DestinationRules:        loader.GetResources().DestinationRules,
   249  			MeshPeerAuthentications: loader.FindPeerAuthenticationIn("istio-system"),
   250  			PeerAuthentications:     loader.FindPeerAuthenticationNotIn("istio-system"),
   251  			EnabledAutoMtls:         autoMtls,
   252  		},
   253  	}.Check()
   254  
   255  	return validations
   256  }
   257  
   258  func testNoMtlsChecker(scenario string, t *testing.T, autoMtls bool) {
   259  	vals := mtlsCheckerTestPrep(scenario, autoMtls, t)
   260  	ta := validations.ValidationsTestAsserter{T: t, Validations: vals}
   261  	ta.AssertNoValidations()
   262  }
   263  
   264  func testMtlsCheckerPresent(scenario string, t *testing.T, autoMtls bool) {
   265  	vals := mtlsCheckerTestPrep(scenario, autoMtls, t)
   266  	ta := validations.ValidationsTestAsserter{T: t, Validations: vals}
   267  	ta.AssertValidationsPresent(1)
   268  	ta.AssertValidationAt(models.IstioValidationKey{
   269  		ObjectType: "authorizationpolicy",
   270  		Name:       "policy",
   271  		Namespace:  "bookinfo",
   272  	}, models.ErrorSeverity, "spec/rules[0]/source/principals", "authorizationpolicy.mtls.needstobeenabled")
   273  }
   274  
   275  func yamlFixtureLoaderFor(file string) *validations.YamlFixtureLoader {
   276  	path := fmt.Sprintf("../../../tests/data/validations/authorization/%s", file)
   277  	return &validations.YamlFixtureLoader{Filename: path}
   278  }