From ada5d6f131c5c7bd295fd24927a5efe5b3e83ad5 Mon Sep 17 00:00:00 2001 From: Ruslan Aliev Date: Thu, 24 Jun 2021 10:58:45 -0500 Subject: [PATCH] Remove cluster resetsatoken subcommand This command is outdated and no longer needed, according to the design call it should be removed. Change-Id: I7c96fdd8cbc21c56ad9d0d6291ea9b6c6626735d Signed-off-by: Ruslan Aliev Relates-To: #588 --- cmd/cluster/cluster.go | 2 - cmd/cluster/resetsatoken/resetsatoken.go | 76 -------- cmd/cluster/resetsatoken/resetsatoken_test.go | 36 ---- .../reset-with-help.golden | 23 --- .../cluster-cmd-with-help.golden | 9 +- .../source/cli/cluster/airshipctl_cluster.rst | 1 - docs/source/cli/cluster/index.rst | 1 - pkg/cluster/resetsatoken/command.go | 60 ------- pkg/cluster/resetsatoken/command_test.go | 85 --------- pkg/cluster/resetsatoken/errors.go | 46 ----- pkg/cluster/resetsatoken/resetsatoken.go | 139 --------------- pkg/cluster/resetsatoken/resetsatoken_test.go | 166 ------------------ .../resetsatoken/testdata/airshipconfig.yaml | 21 --- .../resetsatoken/testdata/kubeconfig.yaml | 19 -- pkg/cluster/resetsatoken/testdata/pod.yaml | 25 --- pkg/cluster/resetsatoken/testdata/secret.yaml | 6 - 16 files changed, 4 insertions(+), 711 deletions(-) delete mode 100644 cmd/cluster/resetsatoken/resetsatoken.go delete mode 100644 cmd/cluster/resetsatoken/resetsatoken_test.go delete mode 100644 cmd/cluster/resetsatoken/testdata/TestResetTokenGoldenOutput/reset-with-help.golden delete mode 100644 pkg/cluster/resetsatoken/command.go delete mode 100644 pkg/cluster/resetsatoken/command_test.go delete mode 100644 pkg/cluster/resetsatoken/errors.go delete mode 100644 pkg/cluster/resetsatoken/resetsatoken.go delete mode 100644 pkg/cluster/resetsatoken/resetsatoken_test.go delete mode 100644 pkg/cluster/resetsatoken/testdata/airshipconfig.yaml delete mode 100644 pkg/cluster/resetsatoken/testdata/kubeconfig.yaml delete mode 100644 pkg/cluster/resetsatoken/testdata/pod.yaml delete mode 100644 pkg/cluster/resetsatoken/testdata/secret.yaml diff --git a/cmd/cluster/cluster.go b/cmd/cluster/cluster.go index e5db9ca0e..855334c82 100644 --- a/cmd/cluster/cluster.go +++ b/cmd/cluster/cluster.go @@ -17,7 +17,6 @@ package cluster import ( "github.com/spf13/cobra" - "opendev.org/airship/airshipctl/cmd/cluster/resetsatoken" "opendev.org/airship/airshipctl/pkg/config" ) @@ -38,7 +37,6 @@ func NewClusterCommand(cfgFactory config.Factory) *cobra.Command { } clusterRootCmd.AddCommand(NewStatusCommand(cfgFactory)) - clusterRootCmd.AddCommand(resetsatoken.NewResetCommand(cfgFactory)) clusterRootCmd.AddCommand(NewGetKubeconfigCommand(cfgFactory)) clusterRootCmd.AddCommand(NewListCommand(cfgFactory)) diff --git a/cmd/cluster/resetsatoken/resetsatoken.go b/cmd/cluster/resetsatoken/resetsatoken.go deleted file mode 100644 index 6a1c4b3b0..000000000 --- a/cmd/cluster/resetsatoken/resetsatoken.go +++ /dev/null @@ -1,76 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken - -import ( - "github.com/spf13/cobra" - - "opendev.org/airship/airshipctl/pkg/cluster/resetsatoken" - "opendev.org/airship/airshipctl/pkg/config" - "opendev.org/airship/airshipctl/pkg/log" -) - -const ( - resetLong = ` -Reset/rotate the Service Account(SA) tokens and additionally restart the corresponding pods to get the latest -token data reflected in the pod spec. - -Secret-namespace is a mandatory flag and secret-name is optional. If a secret-name is not specified, all of the SA -tokens in the specified namespace are rotated, else only the specified secret-name. -` - - resetExample = ` -To rotate a particular SA token -# airshipctl cluster rotate-sa-token -n cert-manager -s cert-manager-token-vvn9p - -To rotate all the SA tokens in cert-manager namespace -# airshipctl cluster rotate-sa-token -n cert-manager -` -) - -// NewResetCommand creates a new command for generating secret information -func NewResetCommand(cfgFactory config.Factory) *cobra.Command { - r := &resetsatoken.ResetCommand{ - Options: resetsatoken.ResetFlags{}, - CfgFactory: cfgFactory, - } - - resetCmd := &cobra.Command{ - Use: "rotate-sa-token", - Short: "Airshipctl command to rotate tokens of Service Account(s)", - Long: resetLong[1:], - Example: resetExample, - RunE: func(cmd *cobra.Command, args []string) error { - return r.RunE() - }, - } - - resetCmd.Flags().StringVarP(&r.Options.Namespace, "secret-namespace", "n", "", - "namespace of the Service Account Token") - resetCmd.Flags().StringVarP(&r.Options.SecretName, "secret-name", "s", "", - "name of the secret containing Service Account Token") - resetCmd.Flags().StringVar(&r.Options.Kubeconfig, "kubeconfig", "", - "path to kubeconfig associated with cluster being managed") - - err := resetCmd.MarkFlagRequired("secret-namespace") - if err != nil { - log.Fatal(err) - } - err = resetCmd.MarkFlagRequired("kubeconfig") - if err != nil { - log.Fatalf("marking kubeconfig flag required failed: %v", err) - } - return resetCmd -} diff --git a/cmd/cluster/resetsatoken/resetsatoken_test.go b/cmd/cluster/resetsatoken/resetsatoken_test.go deleted file mode 100644 index 994552a58..000000000 --- a/cmd/cluster/resetsatoken/resetsatoken_test.go +++ /dev/null @@ -1,36 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken_test - -import ( - "testing" - - "opendev.org/airship/airshipctl/cmd/cluster/resetsatoken" - "opendev.org/airship/airshipctl/testutil" -) - -func TestResetToken(t *testing.T) { - cmdTests := []*testutil.CmdTest{ - { - Name: "reset-with-help", - CmdLine: "--help", - Cmd: resetsatoken.NewResetCommand(nil), - }, - } - - for _, tt := range cmdTests { - testutil.RunTest(t, tt) - } -} diff --git a/cmd/cluster/resetsatoken/testdata/TestResetTokenGoldenOutput/reset-with-help.golden b/cmd/cluster/resetsatoken/testdata/TestResetTokenGoldenOutput/reset-with-help.golden deleted file mode 100644 index 2fc10e0c5..000000000 --- a/cmd/cluster/resetsatoken/testdata/TestResetTokenGoldenOutput/reset-with-help.golden +++ /dev/null @@ -1,23 +0,0 @@ -Reset/rotate the Service Account(SA) tokens and additionally restart the corresponding pods to get the latest -token data reflected in the pod spec. - -Secret-namespace is a mandatory flag and secret-name is optional. If a secret-name is not specified, all of the SA -tokens in the specified namespace are rotated, else only the specified secret-name. - -Usage: - rotate-sa-token [flags] - -Examples: - -To rotate a particular SA token -# airshipctl cluster rotate-sa-token -n cert-manager -s cert-manager-token-vvn9p - -To rotate all the SA tokens in cert-manager namespace -# airshipctl cluster rotate-sa-token -n cert-manager - - -Flags: - -h, --help help for rotate-sa-token - --kubeconfig string path to kubeconfig associated with cluster being managed - -s, --secret-name string name of the secret containing Service Account Token - -n, --secret-namespace string namespace of the Service Account Token diff --git a/cmd/cluster/testdata/TestNewClusterCommandGoldenOutput/cluster-cmd-with-help.golden b/cmd/cluster/testdata/TestNewClusterCommandGoldenOutput/cluster-cmd-with-help.golden index 11ab4760e..df9aac4ed 100644 --- a/cmd/cluster/testdata/TestNewClusterCommandGoldenOutput/cluster-cmd-with-help.golden +++ b/cmd/cluster/testdata/TestNewClusterCommandGoldenOutput/cluster-cmd-with-help.golden @@ -5,11 +5,10 @@ Usage: cluster [command] Available Commands: - get-kubeconfig Airshipctl command to retrieve kubeconfig for a desired cluster - help Help about any command - list Airshipctl command to get and list defined clusters - rotate-sa-token Airshipctl command to rotate tokens of Service Account(s) - status Retrieve statuses of deployed cluster components + get-kubeconfig Airshipctl command to retrieve kubeconfig for a desired cluster + help Help about any command + list Airshipctl command to get and list defined clusters + status Retrieve statuses of deployed cluster components Flags: -h, --help help for cluster diff --git a/docs/source/cli/cluster/airshipctl_cluster.rst b/docs/source/cli/cluster/airshipctl_cluster.rst index 71947307c..4c46ea64e 100644 --- a/docs/source/cli/cluster/airshipctl_cluster.rst +++ b/docs/source/cli/cluster/airshipctl_cluster.rst @@ -34,6 +34,5 @@ SEE ALSO * :ref:`airshipctl ` - A unified command line tool for management of end-to-end kubernetes cluster deployment on cloud infrastructure environments. * :ref:`airshipctl cluster get-kubeconfig ` - Airshipctl command to retrieve kubeconfig for a desired cluster * :ref:`airshipctl cluster list ` - Airshipctl command to get and list defined clusters -* :ref:`airshipctl cluster rotate-sa-token ` - Airshipctl command to rotate tokens of Service Account(s) * :ref:`airshipctl cluster status ` - Retrieve statuses of deployed cluster components diff --git a/docs/source/cli/cluster/index.rst b/docs/source/cli/cluster/index.rst index a6b5347de..5c9b63e4c 100644 --- a/docs/source/cli/cluster/index.rst +++ b/docs/source/cli/cluster/index.rst @@ -8,5 +8,4 @@ cluster airshipctl_cluster airshipctl_cluster_get-kubeconfig airshipctl_cluster_list - airshipctl_cluster_rotate-sa-token airshipctl_cluster_status diff --git a/pkg/cluster/resetsatoken/command.go b/pkg/cluster/resetsatoken/command.go deleted file mode 100644 index c75118555..000000000 --- a/pkg/cluster/resetsatoken/command.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken - -import ( - "opendev.org/airship/airshipctl/pkg/config" - "opendev.org/airship/airshipctl/pkg/k8s/client" - "opendev.org/airship/airshipctl/pkg/log" -) - -// ResetFlags flags for reset command -type ResetFlags struct { - Namespace string - SecretName string - Kubeconfig string -} - -// ResetCommand for reset command -type ResetCommand struct { - Options ResetFlags - CfgFactory config.Factory -} - -// RunE implements the functionality for resetsatoken -func (c *ResetCommand) RunE() error { - airshipconfig, err := c.CfgFactory() - if err != nil { - return err - } - - factory := client.DefaultClient - - kclient, err := factory(airshipconfig.LoadedConfigPath(), c.Options.Kubeconfig) - if err != nil { - return err - } - - manager, err := NewTokenManager(kclient.ClientSet()) - if err != nil { - return err - } - - log.Printf("Starting Token Rotation") - - err = manager.RotateToken(c.Options.Namespace, c.Options.SecretName) - if err != nil { - return ErrRotateTokenFail{Err: err.Error()} - } - return nil -} diff --git a/pkg/cluster/resetsatoken/command_test.go b/pkg/cluster/resetsatoken/command_test.go deleted file mode 100644 index 31fc3ba1f..000000000 --- a/pkg/cluster/resetsatoken/command_test.go +++ /dev/null @@ -1,85 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - - "opendev.org/airship/airshipctl/pkg/cluster/resetsatoken" - "opendev.org/airship/airshipctl/pkg/config" - "opendev.org/airship/airshipctl/pkg/k8s/client" - "opendev.org/airship/airshipctl/pkg/k8s/client/fake" -) - -func TestRunE(t *testing.T) { - airshipConfigPath := "testdata/airshipconfig.yaml" - kubeConfigPath := "testdata/kubeconfig.yaml" - - tests := []struct { - testCaseName string - testErr string - resetFlags resetsatoken.ResetFlags - cfgFactory config.Factory - }{ - { - testCaseName: "invalid config factory", - cfgFactory: func() (*config.Config, error) { - return nil, fmt.Errorf("test config error") - }, - resetFlags: resetsatoken.ResetFlags{}, - testErr: "test config error", - }, - { - testCaseName: "valid config factory", - cfgFactory: config.CreateFactory(&airshipConfigPath), - resetFlags: resetsatoken.ResetFlags{ - SecretName: "test-secret", - Namespace: "test-namespace", - }, - testErr: "", - }, - } - - for _, tt := range tests { - t.Run(tt.testCaseName, func(t *testing.T) { - command := resetsatoken.ResetCommand{ - Options: tt.resetFlags, - CfgFactory: tt.cfgFactory, - } - err := command.RunE() - if tt.testErr != "" { - assert.Contains(t, err.Error(), tt.testErr) - } else { - fakeConfig, err := command.CfgFactory() - assert.NoError(t, err) - - factory := client.DefaultClient - _, err = factory(fakeConfig.LoadedConfigPath(), kubeConfigPath) - assert.NoError(t, err) - - fakeClient := fake.NewClient() - assert.NotEmpty(t, fakeClient) - - clientset := fakeClient.ClientSet() - fakeManager, err := resetsatoken.NewTokenManager(clientset) - assert.NoError(t, err) - - err = fakeManager.RotateToken(command.Options.Namespace, command.Options.SecretName) - assert.Error(t, err) - } - }) - } -} diff --git a/pkg/cluster/resetsatoken/errors.go b/pkg/cluster/resetsatoken/errors.go deleted file mode 100644 index e0e706853..000000000 --- a/pkg/cluster/resetsatoken/errors.go +++ /dev/null @@ -1,46 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken - -import ( - "fmt" -) - -// ErrNoSATokenFound is returned if there are no SA tokens found in the provided namespace -type ErrNoSATokenFound struct { - namespace string -} - -// ErrNotSAToken is returned if the user input is not an SA token -type ErrNotSAToken struct { - secretName string -} - -// ErrRotateTokenFail is called when there is a failure in rotating the SA token -type ErrRotateTokenFail struct { - Err string -} - -func (e ErrNoSATokenFound) Error() string { - return fmt.Sprintf("no service account tokens found in namespace %s", e.namespace) -} - -func (e ErrNotSAToken) Error() string { - return fmt.Sprintf("%s is not a Service Account Token", e.secretName) -} - -func (e ErrRotateTokenFail) Error() string { - return fmt.Sprintf("failed to rotate token: %s", e.Err) -} diff --git a/pkg/cluster/resetsatoken/resetsatoken.go b/pkg/cluster/resetsatoken/resetsatoken.go deleted file mode 100644 index 4b48c557d..000000000 --- a/pkg/cluster/resetsatoken/resetsatoken.go +++ /dev/null @@ -1,139 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken - -import ( - "fmt" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - - "opendev.org/airship/airshipctl/pkg/log" -) - -const ( - replicaSetKind = "ReplicaSet" -) - -// TokenManager manages service account rotation -type TokenManager struct { - kclient kubernetes.Interface -} - -// NewTokenManager returns an instance of a TokenManager -func NewTokenManager(kclient kubernetes.Interface) (*TokenManager, error) { - return &TokenManager{ - kclient: kclient, - }, nil -} - -// RotateToken - rotates token > 1. Deletes the secret and 2. Deletes its pod -// Deleting the SA Secret recreates a new secret with a new token information -// However, the pods referencing to the old secret needs to be refreshed -// manually and hence deleting the pod to allow it to get recreated with new -// secret reference -func (manager TokenManager) RotateToken(ns string, secretName string) error { - if secretName == "" { - return manager.rotateAllTokens(ns) - } - return manager.rotateSingleToken(ns, secretName) -} - -// deleteSecret- deletes the secret -func (manager TokenManager) deleteSecret(secretName string, ns string) error { - return manager.kclient.CoreV1().Secrets(ns).Delete(secretName, &metav1.DeleteOptions{}) -} - -// deletePod - identifies the secret relationship with pods and deletes corresponding pods -// if its part of replicaset -func (manager TokenManager) deletePod(secretName string, ns string) error { - pods, err := manager.kclient.CoreV1().Pods(ns).List(metav1.ListOptions{}) - if err != nil { - return err - } - - for _, pod := range pods.Items { - for _, volume := range pod.Spec.Volumes { - if volume.Name == secretName { - if manager.isReplicaSet(pod.OwnerReferences) { - log.Printf("Deleting pod - %s in %s", pod.Name, ns) - if deleteErr := manager.kclient.CoreV1().Pods(ns).Delete(pod.Name, - &metav1.DeleteOptions{}); deleteErr != nil { - log.Printf("Failed to delete pod: %v", err.Error()) - } - } - } - } - } - return nil -} - -// rotateAllTokens rotates all the tokens in the given namespace -func (manager TokenManager) rotateAllTokens(ns string) error { - tokenTypeFieldSelector := fmt.Sprintf("type=%s", corev1.SecretTypeServiceAccountToken) - listOptions := metav1.ListOptions{FieldSelector: tokenTypeFieldSelector} - - secrets, err := manager.kclient.CoreV1().Secrets(ns).List(listOptions) - if err != nil { - return err - } - - if len(secrets.Items) == 0 { - return ErrNoSATokenFound{namespace: ns} - } - - for _, secret := range secrets.Items { - err := manager.rotate(secret.Name, secret.Namespace) - if err != nil { - return err - } - } - return nil -} - -// rotateSingleToken rotates a given token in the given ns -func (manager TokenManager) rotateSingleToken(ns string, secretName string) error { - secret, err := manager.kclient.CoreV1().Secrets(ns).Get(secretName, metav1.GetOptions{}) - if err != nil { - return err - } - - if secret.Type != corev1.SecretTypeServiceAccountToken { - return ErrNotSAToken{secretName: secretName} - } - return manager.rotate(secretName, ns) -} - -// rotate performs delete action for secrets and its pods -func (manager TokenManager) rotate(secretName string, secretNamespace string) error { - log.Printf("Rotating token - %s in %s", secretName, secretNamespace) - err := manager.deleteSecret(secretName, secretNamespace) - if err != nil { - return err - } - - return manager.deletePod(secretName, secretNamespace) -} - -// isReplicaSet checks if the pod is controlled by a ReplicaSet making it safe to delete -func (manager TokenManager) isReplicaSet(ownerReferences []metav1.OwnerReference) bool { - for _, ownerRef := range ownerReferences { - if ownerRef.Kind == replicaSetKind { - return true - } - } - return false -} diff --git a/pkg/cluster/resetsatoken/resetsatoken_test.go b/pkg/cluster/resetsatoken/resetsatoken_test.go deleted file mode 100644 index 8f35e1f51..000000000 --- a/pkg/cluster/resetsatoken/resetsatoken_test.go +++ /dev/null @@ -1,166 +0,0 @@ -/* - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package resetsatoken_test - -import ( - "io/ioutil" - "testing" - - "github.com/stretchr/testify/assert" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/yaml" - kfake "k8s.io/client-go/kubernetes/fake" - "k8s.io/client-go/kubernetes/scheme" - ktesting "k8s.io/client-go/testing" - - "opendev.org/airship/airshipctl/pkg/cluster/resetsatoken" - "opendev.org/airship/airshipctl/pkg/k8s/client/fake" - "opendev.org/airship/airshipctl/testutil" -) - -type testCase struct { - name string - existingSecrets []*v1.Secret - existingPods []*v1.Pod - secretName string - secretNamespace string - numPodDeletes int - numSecretDeletes int - expectErr bool -} - -var testCases = []testCase{ - { - name: "no-pods-secrets", - expectErr: true, - }, - { - name: "valid-secret-no-pod", - secretName: "valid-secret", - secretNamespace: "valid-namespace", - existingSecrets: []*v1.Secret{getSecret()}, - numSecretDeletes: 1, - }, - { - name: "valid-secret-no-pod-empty-filter", - secretNamespace: "valid-namespace", - existingSecrets: []*v1.Secret{getSecret()}, - numSecretDeletes: 1, - }, - { - name: "invalid-secret-no-pod", - secretName: "invalid-secret", - existingSecrets: []*v1.Secret{getSecret()}, - secretNamespace: "valid-namespace", - }, - { - name: "unmatched-secret-pod", - secretName: "invalid-secret", - secretNamespace: "valid-namespace", - existingPods: []*v1.Pod{getPod()}, - existingSecrets: []*v1.Secret{getSecret()}, - }, - { - name: "matched-secret-pod", - secretName: "valid-secret", - secretNamespace: "valid-namespace", - existingPods: []*v1.Pod{getPod()}, - existingSecrets: []*v1.Secret{getSecret()}, - numPodDeletes: 1, - numSecretDeletes: 1, - }, -} - -func TestResetSaToken(t *testing.T) { - for _, testCase := range testCases { - cfg, _ := testutil.InitConfig(t) - - var objects []runtime.Object - for _, pod := range testCase.existingPods { - objects = append(objects, pod) - } - for _, secret := range testCase.existingSecrets { - objects = append(objects, secret) - } - ra := fake.WithTypedObjects(objects...) - kclient := fake.NewClient(ra) - - assert.NotEmpty(t, kclient) - assert.NotEmpty(t, cfg) - - clientset := kclient.ClientSet() - manager, err := resetsatoken.NewTokenManager(clientset) - assert.NoError(t, err) - - err = manager.RotateToken(testCase.secretNamespace, testCase.secretName) - if testCase.expectErr { - assert.Error(t, err) - continue - } - - actions := clientset.(*kfake.Clientset).Actions() - - podDeleteActions := filterActions(actions, "pods", "delete") - assert.Len(t, podDeleteActions, testCase.numPodDeletes) - - secretDeleteActions := filterActions(actions, "secrets", "delete") - assert.Len(t, secretDeleteActions, testCase.numSecretDeletes) - } -} - -func getSecret() *v1.Secret { - object := readObjectFromFile("testdata/secret.yaml") - if secret, ok := object.(*v1.Secret); ok { - return secret - } - return nil -} - -func getPod() *v1.Pod { - object := readObjectFromFile("testdata/pod.yaml") - if pod, ok := object.(*v1.Pod); ok { - return pod - } - return nil -} - -func readObjectFromFile(fileName string) runtime.Object { - contents, err := ioutil.ReadFile(fileName) - if err != nil { - return nil - } - jsonContents, err := yaml.ToJSON(contents) - if err != nil { - return nil - } - - object, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), jsonContents) - if err != nil { - return nil - } - return object -} - -func filterActions(actions []ktesting.Action, resource string, verb string) []ktesting.Action { - var result []ktesting.Action - for _, action := range actions { - if action.GetVerb() == verb && action.GetResource().Resource == resource { - result = append(result, action) - } - } - return result -} diff --git a/pkg/cluster/resetsatoken/testdata/airshipconfig.yaml b/pkg/cluster/resetsatoken/testdata/airshipconfig.yaml deleted file mode 100644 index 7a7d762e9..000000000 --- a/pkg/cluster/resetsatoken/testdata/airshipconfig.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -contexts: - dummy_cluster: - manifest: dummy_manifest -currentContext: dummy_cluster -kind: Config -manifests: - dummy_manifest: - primaryRepositoryName: primary - repositories: - primary: - auth: - sshKey: testdata/test-key.pem - type: ssh-key - checkout: - branch: "" - force: false - remoteRef: "" - tag: v1.0.1 - url: http://dummy.url.com/primary.git - targetPath: testdata diff --git a/pkg/cluster/resetsatoken/testdata/kubeconfig.yaml b/pkg/cluster/resetsatoken/testdata/kubeconfig.yaml deleted file mode 100644 index b0d205918..000000000 --- a/pkg/cluster/resetsatoken/testdata/kubeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -clusters: -- cluster: - certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - server: https://127.0.0.1:6443 - name: dummycluster_ephemeral -contexts: -- context: - cluster: dummycluster_ephemeral - user: kubernetes-admin - name: dummy_cluster -current-context: dummy_cluster -kind: Config -preferences: {} -users: -- name: kubernetes-admin - user: - client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= diff --git a/pkg/cluster/resetsatoken/testdata/pod.yaml b/pkg/cluster/resetsatoken/testdata/pod.yaml deleted file mode 100644 index 8e6b6f1b8..000000000 --- a/pkg/cluster/resetsatoken/testdata/pod.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: valid-pod - namespace: valid-namespace - ownerReferences: - - apiVersion: apps/v1 - blockOwnerDeletion: true - controller: true - kind: ReplicaSet - name: valid-pod-rs -spec: - containers: - - image: pod-image - volumeMounts: - - mountPath: /var/run/secrets/kubernetes.io/serviceaccount - name: valid-secret - readOnly: true - serviceAccount: valid-serviceaccount - serviceAccountName: valid-serviceaccount - volumes: - - name: valid-secret - secret: - defaultMode: 420 - secretName: valid-secret diff --git a/pkg/cluster/resetsatoken/testdata/secret.yaml b/pkg/cluster/resetsatoken/testdata/secret.yaml deleted file mode 100644 index 17ce464d4..000000000 --- a/pkg/cluster/resetsatoken/testdata/secret.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: valid-secret - namespace: valid-namespace -type: kubernetes.io/service-account-token