istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/integration/helm/install_test.go (about) 1 //go:build integ 2 // +build integ 3 4 // Copyright Istio Authors 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package helm 19 20 import ( 21 "fmt" 22 "os" 23 "path/filepath" 24 "strings" 25 "testing" 26 27 "k8s.io/apimachinery/pkg/types" 28 29 "istio.io/istio/pkg/test/framework" 30 kubecluster "istio.io/istio/pkg/test/framework/components/cluster/kube" 31 "istio.io/istio/pkg/test/framework/components/namespace" 32 "istio.io/istio/pkg/test/helm" 33 "istio.io/istio/tests/util/sanitycheck" 34 ) 35 36 // TestDefaultInstall tests Istio installation using Helm with default options 37 func TestDefaultInstall(t *testing.T) { 38 overrideValuesStr := ` 39 global: 40 hub: %s 41 tag: %s 42 variant: %q 43 ` 44 framework. 45 NewTest(t). 46 Run(setupInstallation(overrideValuesStr, false, DefaultNamespaceConfig, "")) 47 } 48 49 // TestAmbientInstall tests Istio ambient profile installation using Helm 50 func TestAmbientInstall(t *testing.T) { 51 framework. 52 NewTest(t). 53 Run(setupInstallation(ambientProfileOverride, true, DefaultNamespaceConfig, "")) 54 } 55 56 func TestAmbientInstallMultiNamespace(t *testing.T) { 57 tests := []struct { 58 name string 59 nsConfig NamespaceConfig 60 }{{ 61 name: "isolated-istio-cni", 62 nsConfig: NewNamespaceConfig(types.NamespacedName{ 63 Name: CniReleaseName, Namespace: "istio-cni", 64 }), 65 }, { 66 name: "isolated-istio-cni-and-ztunnel", 67 nsConfig: NewNamespaceConfig(types.NamespacedName{ 68 Name: CniReleaseName, Namespace: "istio-cni", 69 }, types.NamespacedName{ 70 Name: ZtunnelReleaseName, Namespace: "kube-system", 71 }), 72 }, { 73 name: "isolated-istio-cni-ztunnel-and-gateway", 74 nsConfig: NewNamespaceConfig(types.NamespacedName{ 75 Name: CniReleaseName, Namespace: "istio-cni", 76 }, types.NamespacedName{ 77 Name: ZtunnelReleaseName, Namespace: "ztunnel", 78 }, types.NamespacedName{ 79 Name: IngressReleaseName, Namespace: "ingress-release", 80 }), 81 }} 82 for _, tt := range tests { 83 t.Run(tt.name, func(t *testing.T) { 84 framework. 85 NewTest(t). 86 Run(setupInstallation(ambientProfileOverride, true, tt.nsConfig, "")) 87 }) 88 } 89 } 90 91 // TestReleaseChannels tests that non-stable CRDs and fields get blocked 92 // by the default ValidatingAdmissionPolicy 93 func TestReleaseChannels(t *testing.T) { 94 overrideValuesStr := ` 95 global: 96 hub: %s 97 tag: %s 98 variant: %q 99 profile: stable 100 ` 101 102 framework. 103 NewTest(t). 104 RequireKubernetesMinorVersion(30). 105 Run(setupInstallationWithCustomCheck(overrideValuesStr, false, DefaultNamespaceConfig, func(t framework.TestContext) { 106 // Try to apply an EnvoyFilter (it should be rejected) 107 expectedErrorPrefix := `%s "sample" is forbidden: ValidatingAdmissionPolicy 'stable-channel-default-policy.istio.io' ` + 108 `with binding 'stable-channel-default-policy-binding.istio.io' denied request` 109 err := t.ConfigIstio().Eval("default", nil, sampleEnvoyFilter).Apply() 110 if err == nil { 111 t.Errorf("Did not receive an error while applying sample EnvoyFilter with stable admission policy") 112 } else { 113 msg := fmt.Sprintf(expectedErrorPrefix, "envoyfilters.networking.istio.io") 114 if !strings.Contains(err.Error(), msg) { 115 t.Errorf("Expected error %q to contain %q", err.Error(), msg) 116 } 117 } 118 119 // Now test field-level blocks with Telemetry 120 err = t.ConfigIstio().Eval("default", nil, extendedTelemetry).Apply() 121 if err == nil { 122 t.Error("Did not receive an error while applying extended Telemetry resource with stable admission policy") 123 } else { 124 msg := fmt.Sprintf(expectedErrorPrefix, "telemetries.telemetry.istio.io") 125 if !strings.Contains(err.Error(), msg) { 126 t.Errorf("Expected error %q to contain %q", err.Error(), msg) 127 } 128 } 129 }, "")) 130 } 131 132 // TestRevisionedReleaseChannels tests that non-stable CRDs and fields get blocked 133 // by the revisioned ValidatingAdmissionPolicy 134 func TestRevisionedReleaseChannels(t *testing.T) { 135 overrideValuesStr := ` 136 global: 137 hub: %s 138 tag: %s 139 variant: %q 140 profile: stable 141 revision: 1-x 142 defaultRevision: "" 143 ` 144 revision := "1-x" 145 framework. 146 NewTest(t). 147 RequireKubernetesMinorVersion(30). 148 Run(setupInstallationWithCustomCheck(overrideValuesStr, false, DefaultNamespaceConfig, func(t framework.TestContext) { 149 // Try to apply an EnvoyFilter (it should be rejected) 150 expectedErrorPrefix := `%s "sample" is forbidden: ValidatingAdmissionPolicy 'stable-channel-policy-1-x-istio-system.istio.io' ` + 151 `with binding 'stable-channel-policy-binding-1-x-istio-system.istio.io' denied request` 152 err := t.ConfigIstio().Eval("default", nil, fmt.Sprintf(revisionedSampleEnvoyFilter, revision)).Apply() 153 if err == nil { 154 t.Errorf("Did not receive an error while applying sample EnvoyFilter with stable admission policy") 155 } else { 156 msg := fmt.Sprintf(expectedErrorPrefix, "envoyfilters.networking.istio.io") 157 if !strings.Contains(err.Error(), msg) { 158 t.Errorf("Expected error %q to contain %q", err.Error(), msg) 159 } 160 } 161 162 // Now test field-level blocks with Telemetry 163 err = t.ConfigIstio().Eval("default", nil, fmt.Sprintf(revisionedExtendedTelemetry, revision)).Apply() 164 if err == nil { 165 t.Error("Did not receive an error while applying extended Telemetry resource with stable admission policy") 166 } else { 167 msg := fmt.Sprintf(expectedErrorPrefix, "telemetries.telemetry.istio.io") 168 if !strings.Contains(err.Error(), msg) { 169 t.Errorf("Expected error %q to contain %q", err.Error(), msg) 170 } 171 } 172 }, revision)) 173 } 174 175 func setupInstallation(overrideValuesStr string, isAmbient bool, config NamespaceConfig, revision string) func(t framework.TestContext) { 176 return baseSetup(overrideValuesStr, isAmbient, config, func(t framework.TestContext) { 177 sanitycheck.RunTrafficTest(t, t) 178 }, revision) 179 } 180 181 func setupInstallationWithCustomCheck(overrideValuesStr string, isAmbient bool, config NamespaceConfig, 182 check func(t framework.TestContext), revision string, 183 ) func(t framework.TestContext) { 184 return baseSetup(overrideValuesStr, isAmbient, config, check, revision) 185 } 186 187 func baseSetup(overrideValuesStr string, isAmbient bool, config NamespaceConfig, 188 check func(t framework.TestContext), revision string, 189 ) func(t framework.TestContext) { 190 return func(t framework.TestContext) { 191 workDir, err := t.CreateTmpDirectory("helm-install-test") 192 if err != nil { 193 t.Fatal("failed to create test directory") 194 } 195 cs := t.Clusters().Default().(*kubecluster.Cluster) 196 h := helm.New(cs.Filename()) 197 s := t.Settings() 198 199 // Some templates contain a tag definition, in which we just replace %s it with the tag value, 200 // others just contain a %s placeholder for the whole tag: line 201 tag := s.Image.Tag 202 if !strings.Contains(overrideValuesStr, "tag: ") { 203 tag = "tag: " + tag 204 } 205 overrideValues := fmt.Sprintf(overrideValuesStr, s.Image.Hub, tag, s.Image.Variant) 206 overrideValues = adjustValuesForOpenShift(t, overrideValues) 207 208 overrideValuesFile := filepath.Join(workDir, "values.yaml") 209 if err := os.WriteFile(overrideValuesFile, []byte(overrideValues), os.ModePerm); err != nil { 210 t.Fatalf("failed to write iop cr file: %v", err) 211 } 212 t.Cleanup(func() { 213 if !t.Failed() { 214 return 215 } 216 if t.Settings().CIMode { 217 for _, ns := range config.AllNamespaces() { 218 namespace.Dump(t, ns) 219 } 220 } 221 }) 222 223 InstallIstio(t, cs, h, overrideValuesFile, "", true, isAmbient, config) 224 225 VerifyInstallation(t, cs, config, true, isAmbient, revision) 226 verifyValidation(t, revision) 227 228 check(t) 229 t.Cleanup(func() { 230 DeleteIstio(t, h, cs, config, isAmbient) 231 }) 232 } 233 }