1 package cmd
2
3 import (
4 "bytes"
5 "context"
6 "encoding/base64"
7 "fmt"
8 "io"
9 "os"
10 "strings"
11 "testing"
12
13 "github.com/linkerd/linkerd2/cli/flag"
14 charts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
15 flagspkg "github.com/linkerd/linkerd2/pkg/flags"
16 "github.com/linkerd/linkerd2/pkg/k8s"
17 "github.com/linkerd/linkerd2/pkg/tls"
18 "github.com/spf13/pflag"
19 valuespkg "helm.sh/helm/v3/pkg/cli/values"
20 corev1 "k8s.io/api/core/v1"
21 )
22
23 const (
24 upgradeProxyVersion = "UPGRADE-PROXY-VERSION"
25 upgradeControlPlaneVersion = "UPGRADE-CONTROL-PLANE-VERSION"
26 upgradeDebugVersion = "UPGRADE-DEBUG-VERSION"
27 overridesSecret = "Secret/linkerd-config-overrides"
28 linkerdConfigMap = "ConfigMap/linkerd-config"
29 )
30
31 type (
32 issuerCerts struct {
33 caFile string
34 ca string
35 crtFile string
36 crt string
37 keyFile string
38 key string
39 }
40
41 flagOptions struct {
42 flags []flag.Flag
43 flagSet *pflag.FlagSet
44 templateOptions *valuespkg.Options
45 }
46 )
47
48
49
50
55
56 func TestUpgradeDefault(t *testing.T) {
57 installOpts, upgradeOpts := testOptions(t)
58 install, upgrade, err := renderInstallAndUpgrade(t, installOpts, upgradeOpts.flags, *upgradeOpts.templateOptions)
59 if err != nil {
60 t.Fatal(err)
61 }
62
63 expected := replaceVersions(install.String())
64 expectedManifests := parseManifestList(expected)
65 upgradeManifests := parseManifestList(upgrade.String())
66 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
67 for _, diff := range diffs {
68 if ignorableDiff(id, diff) {
69 continue
70 }
71 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
72 }
73 }
74 }
75
76 func TestUpgradeHA(t *testing.T) {
77 installOpts, upgradeOpts := testOptions(t)
78 installOpts.HighAvailability = true
79 install, upgrade, err := renderInstallAndUpgrade(t, installOpts, upgradeOpts.flags, *upgradeOpts.templateOptions)
80 if err != nil {
81 t.Fatal(err)
82 }
83
84 expected := replaceVersions(install.String())
85 expectedManifests := parseManifestList(expected)
86 upgradeManifests := parseManifestList(upgrade.String())
87 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
88 for _, diff := range diffs {
89 if ignorableDiff(id, diff) {
90 continue
91 }
92 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
93 }
94 }
95 }
96
97 func TestUpgradeExternalIssuer(t *testing.T) {
98 installOpts, err := testInstallOptionsNoCerts(false)
99 if err != nil {
100 t.Fatalf("failed to create install options: %s", err)
101 }
102
103 upgradeOpts, err := testUpgradeOptions()
104 if err != nil {
105 t.Fatalf("failed to create upgrade options: %s", err)
106 }
107
108 issuer := generateIssuerCerts(t, true)
109 defer issuer.cleanup()
110
111 installOpts.Identity.Issuer.Scheme = string(corev1.SecretTypeTLS)
112 ca, err := base64.StdEncoding.DecodeString(issuer.ca)
113 if err != nil {
114 t.Fatal(err)
115 }
116 installOpts.IdentityTrustAnchorsPEM = string(ca)
117 install := renderInstall(t, installOpts)
118 upgrade, err := renderUpgrade(install.String()+externalIssuerSecret(issuer), upgradeOpts.flags, *upgradeOpts.templateOptions)
119
120 if err != nil {
121 t.Fatal(err)
122 }
123
124 expected := replaceVersions(install.String())
125 expectedManifests := parseManifestList(expected)
126 upgradeManifests := parseManifestList(upgrade.String())
127 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
128 for _, diff := range diffs {
129 if ignorableDiff(id, diff) {
130 continue
131 }
132 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
133 }
134 }
135 }
136
137 func TestUpgradeIssuerWithExternalIssuerFails(t *testing.T) {
138 installOpts, upgradeOpts := testOptions(t)
139
140 issuer := generateIssuerCerts(t, true)
141 defer issuer.cleanup()
142
143 installOpts.IdentityTrustDomain = "cluster.local"
144 installOpts.IdentityTrustDomain = issuer.ca
145 installOpts.Identity.Issuer.Scheme = string(corev1.SecretTypeTLS)
146 installOpts.Identity.Issuer.TLS.CrtPEM = issuer.crt
147 installOpts.Identity.Issuer.TLS.KeyPEM = issuer.key
148 install := renderInstall(t, installOpts)
149
150 upgradedIssuer := generateIssuerCerts(t, true)
151 defer upgradedIssuer.cleanup()
152
153 upgradeOpts.flagSet.Set("identity-trust-anchors-file", upgradedIssuer.caFile)
154 upgradeOpts.flagSet.Set("identity-issuer-certificate-file", upgradedIssuer.crtFile)
155 upgradeOpts.flagSet.Set("identity-issuer-key-file", upgradedIssuer.keyFile)
156
157 _, err := renderUpgrade(install.String()+externalIssuerSecret(issuer), upgradeOpts.flags, *upgradeOpts.templateOptions)
158
159 expectedErr := "cannot update issuer certificates if you are using external cert management solution"
160
161 if err == nil || err.Error() != expectedErr {
162 t.Errorf("Expected error: %s but got %s", expectedErr, err)
163 }
164 }
165
166 func TestUpgradeOverwriteIssuer(t *testing.T) {
167 installOpts, upgradeOpts := testOptions(t)
168
169 issuerCerts := generateIssuerCerts(t, true)
170 defer issuerCerts.cleanup()
171
172 upgradeOpts.flagSet.Set("identity-trust-anchors-file", issuerCerts.caFile)
173 upgradeOpts.flagSet.Set("identity-issuer-certificate-file", issuerCerts.crtFile)
174 upgradeOpts.flagSet.Set("identity-issuer-key-file", issuerCerts.keyFile)
175
176 install, upgrade, err := renderInstallAndUpgrade(t, installOpts, upgradeOpts.flags, *upgradeOpts.templateOptions)
177 if err != nil {
178 t.Fatal(err)
179 }
180
181
182
183 expected := replaceVersions(install.String())
184 expectedManifests := parseManifestList(expected)
185 upgradeManifests := parseManifestList(upgrade.String())
186 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
187 for _, diff := range diffs {
188 if ignorableDiff(id, diff) {
189 continue
190 }
191 if isProxyEnvDiff(diff.path) {
192
193 continue
194 }
195
196 if id == "Deployment/linkerd-identity" || id == "Deployment/linkerd-proxy-injector" {
197 if pathMatch(diff.path, []string{"spec", "template", "spec", "containers", "*", "env", "*", "value"}) && diff.b.(string) == issuerCerts.ca {
198 continue
199 }
200 if pathMatch(diff.path, []string{"spec", "template", "metadata", "annotations", "linkerd.io/trust-root-sha256"}) {
201 continue
202 }
203 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
204 }
205 if id == "Deployment/linkerd-destination" {
206 if pathMatch(diff.path, []string{"spec", "template", "metadata", "annotations", "linkerd.io/trust-root-sha256"}) {
207 continue
208 }
209 }
210
211 if id == "Secret/linkerd-identity-issuer" {
212 if pathMatch(diff.path, []string{"data", "crt.pem"}) {
213 if diff.b.(string) != issuerCerts.crt {
214 diff.a = issuerCerts.crt
215 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
216 }
217 } else if pathMatch(diff.path, []string{"data", "key.pem"}) {
218 if diff.b.(string) != issuerCerts.key {
219 diff.a = issuerCerts.key
220 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
221 }
222 } else {
223 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
224 }
225 continue
226 }
227
228 if id == "ConfigMap/linkerd-identity-trust-roots" {
229 if pathMatch(diff.path, []string{"data", "ca-bundle.crt"}) {
230 ca, err := base64.StdEncoding.DecodeString(issuerCerts.ca)
231 if err != nil {
232 t.Fatal(err)
233 }
234 if diff.b.(string) != string(ca) {
235 diff.a = string(ca)
236 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
237 }
238 } else {
239 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
240 }
241 continue
242 }
243
244 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
245 }
246 }
247 }
248
249 func TestUpgradeFailsWithOnlyIssuerCert(t *testing.T) {
250 installOpts, upgradeOpts := testOptions(t)
251
252 issuerCerts := generateIssuerCerts(t, true)
253 defer issuerCerts.cleanup()
254
255 upgradeOpts.flagSet.Set("identity-trust-anchors-file", issuerCerts.caFile)
256 upgradeOpts.flagSet.Set("identity-issuer-certificate-file", issuerCerts.crtFile)
257
258 _, _, err := renderInstallAndUpgrade(t, installOpts, upgradeOpts.flags, *upgradeOpts.templateOptions)
259
260 expectedErr := "failed to validate issuer credentials: failed to read CA: tls: Public and private key do not match"
261
262 if err == nil || err.Error() != expectedErr {
263 t.Errorf("Expected error: %s but got %s", expectedErr, err)
264 }
265 }
266
267 func TestUpgradeFailsWithOnlyIssuerKey(t *testing.T) {
268 installOpts, upgradeOpts := testOptions(t)
269
270 issuerCerts := generateIssuerCerts(t, false)
271 defer issuerCerts.cleanup()
272
273 upgradeOpts.flagSet.Set("identity-trust-anchors-file", issuerCerts.caFile)
274 upgradeOpts.flagSet.Set("identity-issuer-certificate-file", issuerCerts.crtFile)
275
276 _, _, err := renderInstallAndUpgrade(t, installOpts, upgradeOpts.flags, *upgradeOpts.templateOptions)
277
278 expectedErr := "failed to validate issuer credentials: failed to read CA: tls: Public and private key do not match"
279
280 if err == nil || err.Error() != expectedErr {
281 t.Errorf("Expected error: %s but got %s", expectedErr, err)
282 }
283 }
284
285 func TestUpgradeRootFailsWithOldPods(t *testing.T) {
286 installOpts, upgradeOpts := testOptions(t)
287
288 oldIssuer := generateIssuerCerts(t, false)
289 defer oldIssuer.cleanup()
290
291 install := renderInstall(t, installOpts)
292
293 issuerCerts := generateIssuerCerts(t, true)
294 defer issuerCerts.cleanup()
295
296 upgradeOpts.flagSet.Set("identity-trust-anchors-file", issuerCerts.caFile)
297 upgradeOpts.flagSet.Set("identity-issuer-certificate-file", issuerCerts.crtFile)
298 upgradeOpts.flagSet.Set("identity-issuer-key-file", issuerCerts.keyFile)
299
300 _, err := renderUpgrade(install.String()+podWithSidecar(oldIssuer), upgradeOpts.flags, *upgradeOpts.templateOptions)
301
302 expectedErr := "You are attempting to use an issuer certificate which does not validate against the trust anchors of the following pods"
303 if err == nil || !strings.HasPrefix(err.Error(), expectedErr) {
304 t.Errorf("Expected error: %s but got %s", expectedErr, err)
305 }
306 }
307
308
309 func TestUpgradeWebhookCrtsNameChange(t *testing.T) {
310 installOpts, upgradeOpts := testOptions(t)
311
312 injectorCerts := generateCerts(t, "linkerd-proxy-injector.linkerd.svc", false)
313 defer injectorCerts.cleanup()
314 installOpts.ProxyInjector.TLS = &charts.TLS{
315 ExternalSecret: true,
316 CaBundle: injectorCerts.ca,
317 }
318
319 validatorCerts := generateCerts(t, "linkerd-sp-validator.linkerd.svc", false)
320 defer validatorCerts.cleanup()
321 installOpts.ProfileValidator.TLS = &charts.TLS{
322 ExternalSecret: true,
323 CaBundle: validatorCerts.ca,
324 }
325
326 rendered := renderInstall(t, installOpts)
327 expected := replaceVersions(rendered.String())
328
329
330 install := replaceK8sSecrets(expected)
331
332 upgrade, err := renderUpgrade(install, upgradeOpts.flags, *upgradeOpts.templateOptions)
333 if err != nil {
334 t.Fatal(err)
335 }
336 expectedManifests := parseManifestList(expected)
337 upgradeManifests := parseManifestList(upgrade.String())
338 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
339 for _, diff := range diffs {
340 if ignorableDiff(id, diff) {
341 continue
342 }
343 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
344 }
345 }
346 }
347
348 func replaceK8sSecrets(input string) string {
349 manifest := strings.ReplaceAll(input, "kubernetes.io/tls", "Opaque")
350 manifest = strings.ReplaceAll(manifest, "tls.key", "key.pem")
351 manifest = strings.ReplaceAll(manifest, "tls.crt", "crt.pem")
352 manifest = strings.ReplaceAll(manifest, "linkerd-proxy-injector-k8s-tls", "linkerd-proxy-injector-tls")
353 manifest = strings.ReplaceAll(manifest, "linkerd-tap-k8s-tls", "linkerd-tap-tls")
354 manifest = strings.ReplaceAll(manifest, "linkerd-sp-validator-k8s-tls", "linkerd-sp-validator-tls")
355 manifest = strings.ReplaceAll(manifest, "linkerd-policy-validator-k8s-tls", "linkerd-policy-validator-tls")
356 return manifest
357 }
358
359 func TestUpgradeTwoLevelWebhookCrts(t *testing.T) {
360 installOpts, upgradeOpts := testOptions(t)
361
362
363 injectorCerts := generateCerts(t, "linkerd-proxy-injector.linkerd.svc", false)
364 defer injectorCerts.cleanup()
365 installOpts.ProxyInjector.TLS = &charts.TLS{
366 ExternalSecret: true,
367 CaBundle: injectorCerts.ca,
368 }
369
370 validatorCerts := generateCerts(t, "linkerd-sp-validator.linkerd.svc", false)
371 defer validatorCerts.cleanup()
372 installOpts.ProfileValidator.TLS = &charts.TLS{
373 ExternalSecret: true,
374 CaBundle: validatorCerts.ca,
375 }
376
377 install := renderInstall(t, installOpts)
378 upgrade, err := renderUpgrade(install.String(), upgradeOpts.flags, *upgradeOpts.templateOptions)
379 if err != nil {
380 t.Fatal(err)
381 }
382 expected := replaceVersions(install.String())
383 expectedManifests := parseManifestList(expected)
384 upgradeManifests := parseManifestList(upgrade.String())
385 for id, diffs := range diffManifestLists(expectedManifests, upgradeManifests) {
386 for _, diff := range diffs {
387 if ignorableDiff(id, diff) {
388 continue
389 }
390 t.Errorf("Unexpected diff in %s:\n%s", id, diff.String())
391 }
392 }
393 }
394
395
396
397 func testUpgradeOptions() (flagOptions, error) {
398 defaults, err := charts.NewValues()
399 if err != nil {
400 return flagOptions{}, err
401 }
402
403 installUpgradeFlags, installUpgradeFlagSet, err := makeInstallUpgradeFlags(defaults)
404 if err != nil {
405 return flagOptions{}, err
406 }
407 proxyFlags, proxyFlagSet := makeProxyFlags(defaults)
408 upgradeFlagSet := makeUpgradeFlags()
409
410 flags := flattenFlags(installUpgradeFlags, proxyFlags)
411 flagSet := pflag.NewFlagSet("upgrade", pflag.ExitOnError)
412 flagSet.AddFlagSet(installUpgradeFlagSet)
413 flagSet.AddFlagSet(proxyFlagSet)
414 flagSet.AddFlagSet(upgradeFlagSet)
415
416
417 templateOpts := &valuespkg.Options{}
418 flagspkg.AddValueOptionsFlags(flagSet, templateOpts)
419 flagSet.Set("set", fmt.Sprintf("policyController.image.version=%[1]s,linkerdVersion=%[1]s", upgradeControlPlaneVersion))
420
421 flagSet.Set("set", fmt.Sprintf("proxy.image.version=%s", upgradeProxyVersion))
422
423 return flagOptions{flags, flagSet, templateOpts}, nil
424 }
425
426 func testOptions(t *testing.T) (*charts.Values, flagOptions) {
427 t.Helper()
428 installValues, err := testInstallOptions()
429 if err != nil {
430 t.Fatalf("failed to create install options: %s", err)
431 }
432 flagOpts, err := testUpgradeOptions()
433 if err != nil {
434 t.Fatalf("failed to create upgrade options: %s", err)
435 }
436
437 return installValues, flagOpts
438 }
439
440 func replaceVersions(manifest string) string {
441 manifest = strings.ReplaceAll(manifest, installProxyVersion, upgradeProxyVersion)
442 manifest = strings.ReplaceAll(manifest, installControlPlaneVersion, upgradeControlPlaneVersion)
443 manifest = strings.ReplaceAll(manifest, installDebugVersion, upgradeDebugVersion)
444 return manifest
445 }
446
447 func generateIssuerCerts(t *testing.T, b64encode bool) issuerCerts {
448 t.Helper()
449 return generateCerts(t, "identity.linkerd.cluster.local", b64encode)
450 }
451
452 func generateCerts(t *testing.T, name string, b64encode bool) issuerCerts {
453 t.Helper()
454 ca, err := tls.GenerateRootCAWithDefaults("test")
455 if err != nil {
456 t.Fatal(err)
457 }
458 issuer, err := ca.GenerateCA(name, -1)
459 if err != nil {
460 t.Fatal(err)
461 }
462 caPem := strings.TrimSpace(issuer.Cred.EncodePEM())
463 keyPem := strings.TrimSpace(issuer.Cred.EncodePrivateKeyPEM())
464 crtPem := strings.TrimSpace(issuer.Cred.EncodeCertificatePEM())
465
466 caFile, err := os.CreateTemp("", "ca.*.pem")
467 if err != nil {
468 t.Fatal(err)
469 }
470 crtFile, err := os.CreateTemp("", "crt.*.pem")
471 if err != nil {
472 t.Fatal(err)
473 }
474 keyFile, err := os.CreateTemp("", "key.*.pem")
475 if err != nil {
476 t.Fatal(err)
477 }
478
479 _, err = caFile.Write([]byte(caPem))
480 if err != nil {
481 t.Fatal(err)
482 }
483 _, err = crtFile.Write([]byte(crtPem))
484 if err != nil {
485 t.Fatal(err)
486 }
487 _, err = keyFile.Write([]byte(keyPem))
488 if err != nil {
489 t.Fatal(err)
490 }
491
492 if b64encode {
493 caPem = base64.StdEncoding.EncodeToString([]byte(caPem))
494 crtPem = base64.StdEncoding.EncodeToString([]byte(crtPem))
495 keyPem = base64.StdEncoding.EncodeToString([]byte(keyPem))
496 }
497
498 return issuerCerts{
499 caFile: caFile.Name(),
500 ca: caPem,
501 crtFile: crtFile.Name(),
502 crt: crtPem,
503 keyFile: keyFile.Name(),
504 key: keyPem,
505 }
506 }
507
508 func (ic issuerCerts) cleanup() {
509 os.Remove(ic.caFile)
510 os.Remove(ic.crtFile)
511 os.Remove(ic.keyFile)
512 }
513
514 func externalIssuerSecret(certs issuerCerts) string {
515 return fmt.Sprintf(`---
516 apiVersion: v1
517 kind: Secret
518 metadata:
519 name: linkerd-identity-issuer
520 namespace: linkerd
521 data:
522 tls.crt: %s
523 tls.key: %s
524 ca.crt: %s
525 type: kubernetes.io/tls
526 `, certs.crt, certs.key, certs.ca)
527 }
528
529 func indentLines(s string, prefix string) string {
530 lines := strings.Split(s, "\n")
531 for i, line := range lines {
532 lines[i] = prefix + line
533 }
534 return strings.Join(lines, "\n")
535 }
536
537 func podWithSidecar(certs issuerCerts) string {
538 return fmt.Sprintf(`---
539 apiVersion: v1
540 kind: Pod
541 metadata:
542 annotations:
543 linkerd.io/created-by: linkerd/cli some-version
544 linkerd.io/proxy-version: some-version
545 labels:
546 linkerd.io/control-plane-ns: linkerd
547 name: backend-wrong-anchors
548 namespace: some-namespace
549 spec:
550 containers:
551 - env:
552 - name: LINKERD2_PROXY_IDENTITY_TRUST_ANCHORS
553 value: |
554 %s
555 image: cr.l5d.io/linkerd/proxy:some-version
556 name: linkerd-proxy
557 `, indentLines(certs.ca, " "))
558 }
559
560 func isProxyEnvDiff(path []string) bool {
561 template := []string{"spec", "template", "spec", "containers", "*", "env", "*", "value"}
562 return pathMatch(path, template)
563 }
564
565 func pathMatch(path []string, template []string) bool {
566 if len(path) != len(template) {
567 return false
568 }
569 for i, elem := range template {
570 if elem != "*" && elem != path[i] {
571 return false
572 }
573 }
574 return true
575 }
576
577 func renderInstall(t *testing.T, values *charts.Values) *bytes.Buffer {
578 t.Helper()
579 var buf bytes.Buffer
580 if err := renderCRDs(&buf, valuespkg.Options{}); err != nil {
581 t.Fatalf("could not render install manifests: %s", err)
582 }
583 buf.WriteString("---\n")
584 if err := renderControlPlane(&buf, values, nil); err != nil {
585 t.Fatalf("could not render install manifests: %s", err)
586 }
587 return &buf
588 }
589
590 func renderUpgrade(installManifest string, upgradeOpts []flag.Flag, templateOpts valuespkg.Options) (*bytes.Buffer, error) {
591 k, err := k8s.NewFakeAPIFromManifests([]io.Reader{strings.NewReader(installManifest)})
592 if err != nil {
593 return nil, fmt.Errorf("failed to initialize fake API: %w\n\n%s", err, installManifest)
594 }
595 buf := upgradeCRDs(valuespkg.Options{})
596 buf.WriteString("---\n")
597 cpbuf, err := upgradeControlPlane(context.Background(), k, upgradeOpts, templateOpts)
598 if err != nil {
599 return nil, err
600 }
601 buf.Write(cpbuf.Bytes())
602 return buf, nil
603 }
604
605 func renderInstallAndUpgrade(t *testing.T, installOpts *charts.Values, upgradeOpts []flag.Flag, templateOpts valuespkg.Options) (*bytes.Buffer, *bytes.Buffer, error) {
606 t.Helper()
607 err := validateValues(context.Background(), nil, installOpts)
608 if err != nil {
609 return nil, nil, fmt.Errorf("failed to validate values: %w", err)
610 }
611 installBuf := renderInstall(t, installOpts)
612 upgradeBuf, err := renderUpgrade(installBuf.String(), upgradeOpts, templateOpts)
613 return installBuf, upgradeBuf, err
614 }
615
616
617
618 func ignorableDiff(id string, diff diff) bool {
619 if id == overridesSecret {
620
621
622 return true
623 }
624 if id == linkerdConfigMap {
625
626
627 return true
628 }
629 if (strings.HasPrefix(id, "MutatingWebhookConfiguration") || strings.HasPrefix(id, "ValidatingWebhookConfiguration")) &&
630 pathMatch(diff.path, []string{"webhooks", "*", "clientConfig", "caBundle"}) {
631
632
633 return true
634 }
635 if strings.HasPrefix(id, "APIService") &&
636 pathMatch(diff.path, []string{"spec", "caBundle"}) {
637
638
639 return true
640 }
641
642 if (id == "Deployment/linkerd-sp-validator" || id == "Deployment/linkerd-proxy-injector" || id == "Deployment/linkerd-tap" || id == "Deployment/linkerd-destination") &&
643 pathMatch(diff.path, []string{"spec", "template", "metadata", "annotations", "checksum/config"}) {
644
645
646 return true
647 }
648
649 if id == "Secret/linkerd-proxy-injector-tls" || id == "Secret/linkerd-sp-validator-tls" ||
650 id == "Secret/linkerd-tap-tls" || id == "Secret/linkerd-sp-validator-k8s-tls" ||
651 id == "Secret/linkerd-proxy-injector-k8s-tls" || id == "Secret/linkerd-tap-k8s-tls" ||
652 id == "Secret/linkerd-policy-validator-tls" || id == "Secret/linkerd-policy-validator-k8s-tls" {
653
654 return true
655 }
656 return false
657 }
658
View as plain text