Skip to content

Commit

Permalink
Update TestYttRebaseRule to work for k8s v1.24.0+
Browse files Browse the repository at this point in the history
Starting with Kubernetes v1.24.0, the service account controller no longer adds a service token secret to a service account
  • Loading branch information
praveenrewar committed Jun 23, 2022
1 parent e5a3e17 commit 837b77f
Showing 1 changed file with 85 additions and 37 deletions.
122 changes: 85 additions & 37 deletions test/e2e/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,15 @@ data:
}

func TestYttRebaseRule_ServiceAccountRebaseTokenSecret(t *testing.T) {
minorVersion, err := getServerMinorVersion()
require.NoErrorf(t, err, "Error getting k8s server minor version")

env := BuildEnv(t)
logger := Logger{}
kapp := Kapp{t, env.Namespace, env.KappBinaryPath, logger}
kubectl := Kubectl{t, env.Namespace, logger}

// ServiceAccount controller appends secret named '${metadata.name}-token-${rand}'
// ServiceAccount controller in k8s v1.24.0+ appends secret named '${metadata.name}-token-${rand}'
yaml1 := `
---
apiVersion: v1
Expand Down Expand Up @@ -191,15 +194,20 @@ secrets:
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml1)})

secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 2, "Expected one set and one generated secret")
if minorVersion < 24 {
require.Len(t, secrets, 2, "Expected one set and one generated secret")
generatedSecretName = secrets[1].(map[string]interface{})["name"].(string)
require.True(t, strings.HasPrefix(generatedSecretName, "test-sa-with-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
} else {
require.Len(t, secrets, 1, "Expected one set secret")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0: %#v", secrets[0])

generatedSecretName = secrets[1].(map[string]interface{})["name"].(string)
require.True(t, strings.HasPrefix(generatedSecretName, "test-sa-with-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])

secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 1, "Expected one set and one generated secret")
require.True(t, strings.HasPrefix(secrets[0].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx0: %#v", secrets[0])
if minorVersion < 24 {
secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 1, "Expected one generated secret")
require.True(t, strings.HasPrefix(secrets[0].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx0: %#v", secrets[0])
}
})

ensureDeploysWithNoChanges := func(yamlContent string) {
Expand All @@ -224,10 +232,15 @@ secrets:
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml2)})

secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 3, "Expected one set and one generated secret")
if minorVersion < 24 {
require.Len(t, secrets, 3, "Expected two set and one generated secret")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[2], "Expected previous generated secret at idx2")
} else {
require.Len(t, secrets, 2, "Expected two set secrets")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0")
require.Exactlyf(t, map[string]interface{}{"name": "new-some-secret"}, secrets[1], "Expected provided secret at idx1")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[2], "Expected previous generated secret at idx2")

})

ensureDeploysWithNoChanges(yaml2)
Expand All @@ -236,20 +249,29 @@ secrets:
kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", name, "-c"},
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml3)})

secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 1, "Expected one set and one generated secret")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[0], "Expected previous generated secret at idx0")
if minorVersion < 24 {
secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 1, "Expected one generated secret")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[0], "Expected previous generated secret at idx0")
}

secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 2, "Expected one set and one generated secret")
secrets := NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
if minorVersion < 24 {
require.Len(t, secrets, 2, "Expected one set and one generated secret")
require.True(t, strings.HasPrefix(secrets[1].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
} else {
require.Len(t, secrets, 1, "Expected one set secret")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0")
require.True(t, strings.HasPrefix(secrets[1].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
})

ensureDeploysWithNoChanges(yaml3)
}

func TestYttRebaseRule_ServiceAccountRebaseTokenSecret_Openshift(t *testing.T) {
minorVersion, err := getServerMinorVersion()
require.NoErrorf(t, err, "Error getting k8s server minor version")

env := BuildEnv(t)
logger := Logger{}
kapp := Kapp{t, env.Namespace, env.KappBinaryPath, logger}
Expand Down Expand Up @@ -313,28 +335,42 @@ secrets:
kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", name},
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml1)})

serviceAccount := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl)

secrets := serviceAccount.RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 2, "Expected one set and two generated secrets")
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0: %#v", secrets[0])

generatedSecretName = secrets[1].(map[string]interface{})["name"].(string)
require.True(t, strings.HasPrefix(generatedSecretName, "test-sa-with-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])

secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 1, "Expected one set and one generated secret")
require.True(t, strings.HasPrefix(secrets[0].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx0: %#v", secrets[0])

patchSAWithSecrets := `[{ "op": "add", "path": "/imagePullSecrets", "value": [{ "name": "test-sa-with-secrets-dockercfg-<rand>"}]},
{ "op": "add", "path": "/secrets/-", "value": { "name": "test-sa-with-secrets-dockercfg-<rand>"}}]`
{ "op": "add", "path": "/secrets/-", "value": { "name": "test-sa-with-secrets-dockercfg-<rand>"}}]`

patchSAWithoutSecrets := `[{ "op": "add", "path": "/imagePullSecrets", "value": [{ "name": "test-sa-without-secrets-dockercfg-<rand>"}]},
{ "op": "add", "path": "/secrets/-", "value": { "name": "test-sa-without-secrets-dockercfg-<rand>"}}]`
{ "op": "add", "path": "/secrets/-", "value": { "name": "test-sa-without-secrets-dockercfg-<rand>"}}]`

if minorVersion >= 24 {
patchSAWithoutSecrets = `[{ "op": "add", "path": "/imagePullSecrets", "value": [{ "name": "test-sa-without-secrets-dockercfg-<rand>"}]},
{ "op": "add", "path": "/secrets", "value": [{ "name": "test-sa-without-secrets-dockercfg-<rand>"}]}]`
}

// Mock Openshift behaviour by adding aditional secrets and image pull secrets
PatchClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, strings.ReplaceAll(patchSAWithSecrets, "<rand>", RandomString(5)), kubectl)
PatchClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, strings.ReplaceAll(patchSAWithoutSecrets, "<rand>", RandomString(5)), kubectl)

serviceAccount := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl)

secrets := serviceAccount.RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
if minorVersion < 24 {
require.Len(t, secrets, 3, "Expected one set and two generated secrets")
generatedSecretName = secrets[1].(map[string]interface{})["name"].(string)
require.True(t, strings.HasPrefix(generatedSecretName, "test-sa-with-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
} else {
require.Len(t, secrets, 2, "Expected one set and one generated secrets")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0: %#v", secrets[0])

secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
if minorVersion < 24 {
require.Len(t, secrets, 2, "Expected two generated secrets")
require.True(t, strings.HasPrefix(secrets[0].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx0: %#v", secrets[0])
require.True(t, strings.HasPrefix(secrets[1].(map[string]interface{})["name"].(string), "test-sa-without-secrets-dockercfg-"), "Expected generated secret at idx0: %#v", secrets[1])
} else {
require.Len(t, secrets, 1, "Expected one generated secret")
require.True(t, strings.HasPrefix(secrets[0].(map[string]interface{})["name"].(string), "test-sa-without-secrets-dockercfg-"), "Expected generated secret at idx0: %#v", secrets[0])
}
})

ensureDeploysWithNoChanges := func(yamlContent string) {
Expand All @@ -359,10 +395,14 @@ secrets:
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml2)})

secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 4, "Expected one set and one generated secret")
if minorVersion < 24 {
require.Len(t, secrets, 4, "Expected two set and two generated secret")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[2], "Expected previous generated secret at idx2")
} else {
require.Len(t, secrets, 3, "Expected two set and one generated secret")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0")
require.Exactlyf(t, map[string]interface{}{"name": "new-some-secret"}, secrets[1], "Expected provided secret at idx1")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[2], "Expected previous generated secret at idx2")
})

ensureDeploysWithNoChanges(yaml2)
Expand All @@ -372,13 +412,21 @@ secrets:
RunOpts{IntoNs: true, StdinReader: strings.NewReader(yaml3)})

secrets := NewPresentClusterResource("serviceaccount", "test-sa-with-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 2, "Expected one set and one generated secret")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[0], "Expected previous generated secret at idx0")
if minorVersion < 24 {
require.Len(t, secrets, 2, "Expected two generated secrets")
require.Exactlyf(t, map[string]interface{}{"name": generatedSecretName}, secrets[0], "Expected previous generated secret at idx0")
} else {
require.Len(t, secrets, 1, "Expected one generated secret")
}

secrets = NewPresentClusterResource("serviceaccount", "test-sa-without-secrets", env.Namespace, kubectl).RawPath(ctlres.NewPathFromStrings([]string{"secrets"})).([]interface{})
require.Len(t, secrets, 3, "Expected one set and one generated secret")
if minorVersion < 24 {
require.Len(t, secrets, 3, "Expected one set and two generated secrets")
require.True(t, strings.HasPrefix(secrets[1].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
} else {
require.Len(t, secrets, 2, "Expected one set and one generated secrets")
}
require.Exactlyf(t, map[string]interface{}{"name": "some-secret"}, secrets[0], "Expected provided secret at idx0")
require.True(t, strings.HasPrefix(secrets[1].(map[string]interface{})["name"].(string), "test-sa-without-secrets-token-"), "Expected generated secret at idx1: %#v", secrets[1])
})

ensureDeploysWithNoChanges(yaml3)
Expand Down

0 comments on commit 837b77f

Please sign in to comment.