istio

Форк
0
328 строк · 13.5 Кб
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 helmupgrade
19

20
import (
21
	"context"
22
	"fmt"
23
	"path/filepath"
24
	"strings"
25

26
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27

28
	"istio.io/api/label"
29
	"istio.io/istio/pkg/test/framework"
30
	"istio.io/istio/pkg/test/framework/components/cluster"
31
	kubecluster "istio.io/istio/pkg/test/framework/components/cluster/kube"
32
	"istio.io/istio/pkg/test/helm"
33
	kubetest "istio.io/istio/pkg/test/kube"
34
	"istio.io/istio/pkg/test/scopes"
35
	"istio.io/istio/pkg/test/shell"
36
	"istio.io/istio/pkg/test/util/retry"
37
	helmtest "istio.io/istio/tests/integration/helm"
38
	"istio.io/istio/tests/util/sanitycheck"
39
)
40

41
const (
42
	gcrHub            = "gcr.io/istio-release"
43
	prodTag           = "prod"
44
	canaryTag         = "canary"
45
	latestRevisionTag = "latest"
46
)
47

48
// upgradeCharts upgrades Istio using Helm charts with the provided
49
// override values file to the latest charts in $ISTIO_SRC/manifests
50
func upgradeCharts(ctx framework.TestContext, h *helm.Helm, overrideValuesFile string, isAmbient bool) {
51
	execCmd := fmt.Sprintf(
52
		"kubectl apply -n %v -f %v",
53
		helmtest.IstioNamespace,
54
		filepath.Join(helmtest.ManifestsChartPath, helmtest.BaseChart, helmtest.CRDsFolder))
55
	_, err := shell.Execute(false, execCmd)
56
	if err != nil {
57
		ctx.Fatalf("couldn't run kubectl apply on crds folder: %v", err)
58
	}
59

60
	// Upgrade base chart
61
	err = h.UpgradeChart(helmtest.BaseReleaseName, filepath.Join(helmtest.ManifestsChartPath, helmtest.BaseChart),
62
		helmtest.IstioNamespace, overrideValuesFile, helmtest.Timeout, "--skip-crds")
63
	if err != nil {
64
		ctx.Fatalf("failed to upgrade istio %s chart", helmtest.BaseReleaseName)
65
	}
66

67
	// Upgrade discovery chart
68
	err = h.UpgradeChart(helmtest.IstiodReleaseName, filepath.Join(helmtest.ManifestsChartPath, helmtest.ControlChartsDir, helmtest.DiscoveryChartsDir),
69
		helmtest.IstioNamespace, overrideValuesFile, helmtest.Timeout)
70
	if err != nil {
71
		ctx.Fatalf("failed to upgrade istio %s chart", helmtest.IstiodReleaseName)
72
	}
73

74
	if isAmbient {
75
		// Upgrade istio-cni chart
76
		err = h.UpgradeChart(helmtest.CniReleaseName, filepath.Join(helmtest.ManifestsChartPath, helmtest.CniChartsDir),
77
			helmtest.IstioNamespace, overrideValuesFile, helmtest.Timeout)
78
		if err != nil {
79
			ctx.Fatalf("failed to upgrade istio %s chart", helmtest.CniReleaseName)
80
		}
81
		// Upgrade ztunnel chart
82
		err = h.UpgradeChart(helmtest.ZtunnelReleaseName, filepath.Join(helmtest.ManifestsChartPath, helmtest.ZtunnelChartsDir),
83
			helmtest.IstioNamespace, overrideValuesFile, helmtest.Timeout)
84
		if err != nil {
85
			ctx.Fatalf("failed to upgrade istio %s chart", helmtest.ZtunnelReleaseName)
86
		}
87
	}
88

89
	// Upgrade ingress gateway chart
90
	err = h.UpgradeChart(helmtest.IngressReleaseName, filepath.Join(helmtest.ManifestsChartPath, helmtest.GatewayChartsDir),
91
		helmtest.IstioNamespace, overrideValuesFile, helmtest.Timeout)
92
	if err != nil {
93
		ctx.Fatalf("failed to upgrade istio %s chart", helmtest.IngressReleaseName)
94
	}
95
}
96

97
// deleteIstio deletes installed Istio Helm charts and resources
98
func deleteIstio(cs cluster.Cluster, h *helm.Helm, gatewayChartInstalled bool) error {
99
	scopes.Framework.Infof("cleaning up resources")
100
	if gatewayChartInstalled {
101
		if err := h.DeleteChart(helmtest.IngressReleaseName, helmtest.IstioNamespace); err != nil {
102
			return fmt.Errorf("failed to delete %s release", helmtest.IngressReleaseName)
103
		}
104
	}
105

106
	if err := h.DeleteChart(helmtest.IstiodReleaseName, helmtest.IstioNamespace); err != nil {
107
		return fmt.Errorf("failed to delete %s release", helmtest.IstiodReleaseName)
108
	}
109

110
	return cleanupIstio(cs, h)
111
}
112

113
func cleanupIstio(cs cluster.Cluster, h *helm.Helm) error {
114
	if err := h.DeleteChart(helmtest.BaseReleaseName, helmtest.IstioNamespace); err != nil {
115
		return fmt.Errorf("failed to delete %s release", helmtest.BaseReleaseName)
116
	}
117
	if err := cs.Kube().CoreV1().Namespaces().Delete(context.TODO(), helmtest.IstioNamespace, metav1.DeleteOptions{}); err != nil {
118
		return fmt.Errorf("failed to delete istio namespace: %v", err)
119
	}
120
	if err := kubetest.WaitForNamespaceDeletion(cs.Kube(), helmtest.IstioNamespace, retry.Timeout(helmtest.RetryTimeOut)); err != nil {
121
		return fmt.Errorf("waiting for istio namespace to be deleted: %v", err)
122
	}
123
	return nil
124
}
125

126
// deleteIstioCanary deletes installed Istio Helm charts and resources
127
func deleteIstioRevision(h *helm.Helm, revision string) error {
128
	scopes.Framework.Infof("cleaning up revision resources (%s)", revision)
129
	name := helmtest.IstiodReleaseName + "-" + strings.ReplaceAll(revision, ".", "-")
130
	if err := h.DeleteChart(name, helmtest.IstioNamespace); err != nil {
131
		return fmt.Errorf("failed to delete revision (%s)", name)
132
	}
133

134
	return nil
135
}
136

137
// performInPlaceUpgradeFunc returns the provided function necessary to run inside an integration test
138
// for upgrade capability
139
func performInPlaceUpgradeFunc(previousVersion string, isAmbient bool) func(framework.TestContext) {
140
	return func(t framework.TestContext) {
141
		cs := t.Clusters().Default().(*kubecluster.Cluster)
142
		h := helm.New(cs.Filename())
143

144
		t.CleanupConditionally(func() {
145
			// only need to do call this once as helm doesn't need to remove
146
			// all versions
147
			helmtest.DeleteIstio(t, h, cs, isAmbient)
148
		})
149
		overrideValuesFile := helmtest.GetValuesOverrides(t, gcrHub, previousVersion, "", isAmbient)
150
		helmtest.InstallIstio(t, cs, h, overrideValuesFile, previousVersion, true, isAmbient)
151
		helmtest.VerifyInstallation(t, cs, true, isAmbient)
152

153
		_, oldClient, oldServer := sanitycheck.SetupTrafficTest(t, t, "")
154
		sanitycheck.RunTrafficTestClientServer(t, oldClient, oldServer)
155

156
		s := t.Settings()
157
		overrideValuesFile = helmtest.GetValuesOverrides(t, s.Image.Hub, s.Image.Tag, "", isAmbient)
158
		upgradeCharts(t, h, overrideValuesFile, isAmbient)
159
		helmtest.VerifyInstallation(t, cs, true, isAmbient)
160

161
		_, newClient, newServer := sanitycheck.SetupTrafficTest(t, t, "")
162
		sanitycheck.RunTrafficTestClientServer(t, newClient, newServer)
163

164
		// now check that we are compatible with N-1 proxy with N proxy
165
		sanitycheck.RunTrafficTestClientServer(t, oldClient, newServer)
166
	}
167
}
168

169
// performCanaryUpgradeFunc returns the provided function necessary to run inside an integration test
170
// for upgrade capability with revisions
171
func performCanaryUpgradeFunc(previousVersion string) func(framework.TestContext) {
172
	return func(t framework.TestContext) {
173
		cs := t.Clusters().Default().(*kubecluster.Cluster)
174
		h := helm.New(cs.Filename())
175
		t.CleanupConditionally(func() {
176
			err := deleteIstioRevision(h, canaryTag)
177
			if err != nil {
178
				t.Fatalf("could not delete istio: %v", err)
179
			}
180
			err = deleteIstio(cs, h, false)
181
			if err != nil {
182
				t.Fatalf("could not delete istio: %v", err)
183
			}
184
		})
185

186
		overrideValuesFile := helmtest.GetValuesOverrides(t, gcrHub, previousVersion, "", false)
187
		helmtest.InstallIstio(t, cs, h, overrideValuesFile, previousVersion, false, false)
188
		helmtest.VerifyInstallation(t, cs, false, false)
189

190
		_, oldClient, oldServer := sanitycheck.SetupTrafficTest(t, t, "")
191
		sanitycheck.RunTrafficTestClientServer(t, oldClient, oldServer)
192

193
		s := t.Settings()
194
		overrideValuesFile = helmtest.GetValuesOverrides(t, s.Image.Hub, s.Image.Tag, canaryTag, false)
195
		helmtest.InstallIstioWithRevision(t, cs, h, "", canaryTag, overrideValuesFile, true, false)
196
		helmtest.VerifyInstallation(t, cs, false, false)
197

198
		// now that we've installed with a revision we have a new mutating webhook
199
		helmtest.VerifyMutatingWebhookConfigurations(t, cs, []string{
200
			"istio-sidecar-injector",
201
			"istio-sidecar-injector-canary",
202
		})
203

204
		_, newClient, newServer := sanitycheck.SetupTrafficTest(t, t, canaryTag)
205
		sanitycheck.RunTrafficTestClientServer(t, newClient, newServer)
206

207
		// now check that we are compatible with N-1 proxy with N proxy
208
		sanitycheck.RunTrafficTestClientServer(t, oldClient, newServer)
209
	}
210
}
211

212
// performRevisionTagsUpgradeFunc returns the provided function necessary to run inside an integration test
213
// for upgrade capability with stable label revision upgrades
214
func performRevisionTagsUpgradeFunc(previousVersion string) func(framework.TestContext) {
215
	return func(t framework.TestContext) {
216
		cs := t.Clusters().Default().(*kubecluster.Cluster)
217
		h := helm.New(cs.Filename())
218
		t.CleanupConditionally(func() {
219
			err := deleteIstioRevision(h, latestRevisionTag)
220
			if err != nil {
221
				t.Fatalf("could not delete istio revision (%v): %v", latestRevisionTag, err)
222
			}
223
			err = deleteIstioRevision(h, previousVersion)
224
			if err != nil {
225
				t.Fatalf("could not delete istio revision (%v): %v", previousVersion, err)
226
			}
227

228
			err = cleanupIstio(cs, h)
229
			if err != nil {
230
				t.Fatalf("could not cleanup istio: %v", err)
231
			}
232
		})
233

234
		// install MAJOR.MINOR.PATCH charts with revision set to "MAJOR-MINOR-PATCH" name. For example,
235
		// helm install istio-base istio/base --version 1.15.0 --namespace istio-system -f values.yaml
236
		// helm install istiod-1-15 istio/istiod --version 1.15.0 -f values.yaml
237
		previousRevision := strings.ReplaceAll(previousVersion, ".", "-")
238
		overrideValuesFile := helmtest.GetValuesOverrides(t, gcrHub, previousVersion, previousRevision, false)
239
		helmtest.InstallIstioWithRevision(t, cs, h, previousVersion, previousRevision, overrideValuesFile, false, true)
240
		helmtest.VerifyInstallation(t, cs, false, false)
241

242
		// helm template istiod-1-15-0 istio/istiod --version 1.15.0 -s templates/revision-tags.yaml --set revision=1-15-0 --set revisionTags={prod}
243
		helmtest.SetRevisionTagWithVersion(t, h, previousRevision, prodTag, previousVersion)
244
		helmtest.VerifyMutatingWebhookConfigurations(t, cs, []string{
245
			"istio-revision-tag-prod",
246
			fmt.Sprintf("istio-sidecar-injector-%s", previousRevision),
247
		})
248

249
		// setup istio.io/rev=1-15-0 for the default-1 namespace
250
		oldNs, oldClient, oldServer := sanitycheck.SetupTrafficTest(t, t, previousRevision)
251
		sanitycheck.RunTrafficTestClientServer(t, oldClient, oldServer)
252

253
		// install the charts from this branch with revision set to "latest"
254
		// helm upgrade istio-base ../manifests/charts/base --namespace istio-system -f values.yaml
255
		// helm install istiod-latest ../manifests/charts/istio-control/istio-discovery -f values.yaml
256
		s := t.Settings()
257
		overrideValuesFile = helmtest.GetValuesOverrides(t, s.Image.Hub, s.Image.Tag, latestRevisionTag, false)
258
		helmtest.InstallIstioWithRevision(t, cs, h, "", latestRevisionTag, overrideValuesFile, true, false)
259
		helmtest.VerifyInstallation(t, cs, false, false)
260

261
		// helm template istiod-latest ../manifests/charts/istio-control/istio-discovery --namespace istio-system
262
		//    -s templates/revision-tags.yaml --set revision=latest --set revisionTags={canary}
263
		helmtest.SetRevisionTag(t, h, "", latestRevisionTag, canaryTag, helmtest.ManifestsChartPath, "")
264
		helmtest.VerifyMutatingWebhookConfigurations(t, cs, []string{
265
			"istio-revision-tag-prod",
266
			fmt.Sprintf("istio-sidecar-injector-%v", previousRevision),
267
			"istio-revision-tag-canary",
268
			"istio-sidecar-injector-latest",
269
		})
270

271
		// setup istio.io/rev=latest for the default-2 namespace
272
		_, newClient, newServer := sanitycheck.SetupTrafficTest(t, t, latestRevisionTag)
273
		sanitycheck.RunTrafficTestClientServer(t, newClient, newServer)
274

275
		// now check that we are compatible with N-1 proxy with N proxy between a client
276
		// in default-1 namespace and a server in the default-2 namespace, respectively
277
		sanitycheck.RunTrafficTestClientServer(t, oldClient, newServer)
278

279
		// change the mutating webhook configuration to use the latest revision (istiod-latest service in istio-system)
280
		// helm template istiod-latest ../manifests/charts/istio-control/istio-discovery --namespace istio-system
281
		//    -s templates/revision-tags.yaml --set revision=latest --set revisionTags={prod}
282
		helmtest.SetRevisionTag(t, h, "", latestRevisionTag, prodTag, helmtest.ManifestsChartPath, "")
283

284
		// change the old namespace that was pointing to the old prod (1-15-0) to point to the
285
		// 'latest' revision by setting the `istio.io/rev=prod` label on the namespace
286
		err := oldNs.SetLabel(label.IoIstioRev.Name, prodTag)
287
		if err != nil {
288
			t.Fatal("could not remove istio.io/rev from old namespace")
289
		}
290

291
		err = oldClient.Restart()
292
		if err != nil {
293
			t.Fatal("could not restart old client")
294
		}
295
		err = oldServer.Restart()
296
		if err != nil {
297
			t.Fatal("could not restart old server")
298
		}
299

300
		// make sure the restarted pods in default-1 namespace do not use
301
		// the previous version (check for the previousVersion in the image string)
302
		err = checkVersion(t, oldNs.Name(), previousVersion)
303
		if err != nil {
304
			t.Fatalf("found a pod in namespace (%s) with the previous version: %v", oldNs.Name(), err)
305
		}
306

307
		// now check traffic still works between the proxies
308
		sanitycheck.RunTrafficTestClientServer(t, oldClient, newServer)
309
	}
310
}
311

312
func checkVersion(t framework.TestContext, namespace, version string) error {
313
	// func NewPodFetch(a istioKube.CLIClient, namespace string, selectors ...string) PodFetchFunc {
314
	fetch := kubetest.NewPodFetch(t.Clusters().Default(), namespace)
315
	pods, err := kubetest.CheckPodsAreReady(fetch)
316
	if err != nil {
317
		return fmt.Errorf("failed to retrieve pods: %v", err)
318
	}
319
	for _, p := range pods {
320
		for _, c := range p.Spec.Containers {
321
			if strings.Contains(c.Image, version) {
322
				return fmt.Errorf("expected container image to not include version %q, got %q", version, c.Image)
323
			}
324
		}
325
	}
326

327
	return nil
328
}
329

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.