From c12e12bd89570979efd7798a3a809228d36e7ec3 Mon Sep 17 00:00:00 2001 From: carlory Date: Wed, 26 Jul 2023 18:08:01 +0800 Subject: [PATCH] fix unusable secret manifest for type docker-registry --- .../pkg/cmd/create/create_secret_docker.go | 14 +++- .../cmd/create/create_secret_docker_test.go | 82 +++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker.go index d8acc90d4a9..980bf2813b9 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker.go @@ -21,6 +21,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "strings" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" @@ -58,7 +59,7 @@ var ( kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL # Create a new secret named my-secret from ~/.docker/config.json - kubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=path/to/.docker/config.json`)) + kubectl create secret docker-registry my-secret --from-file=path/to/.docker/config.json`)) ) // DockerConfigJSON represents a local docker auth config file @@ -152,7 +153,11 @@ func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, ioStreams genericioopti cmd.Flags().StringVar(&o.Email, "docker-email", o.Email, i18n.T("Email for Docker registry")) cmd.Flags().StringVar(&o.Server, "docker-server", o.Server, i18n.T("Server location for Docker registry")) cmd.Flags().BoolVar(&o.AppendHash, "append-hash", o.AppendHash, "Append a hash of the secret to its name.") - cmd.Flags().StringSliceVar(&o.FileSources, "from-file", o.FileSources, "Key files can be specified using their file path, in which case a default name will be given to them, or optionally with a name and file path, in which case the given name will be used. Specifying a directory will iterate each named file in the directory that is a valid secret key.") + cmd.Flags().StringSliceVar(&o.FileSources, "from-file", o.FileSources, "Key files can be specified using their file path, "+ + "in which case a default name of "+corev1.DockerConfigJsonKey+" will be given to them, "+ + "or optionally with a name and file path, in which case the given name will be used. "+ + "Specifying a directory will iterate each named file in the directory that is a valid secret key. "+ + "For this command, the key should always be "+corev1.DockerConfigJsonKey+".") cmdutil.AddFieldManagerFlagVar(cmd, &o.FieldManager, "kubectl-create") @@ -204,6 +209,11 @@ func (o *CreateSecretDockerRegistryOptions) Complete(f cmdutil.Factory, cmd *cob return err } + for i := range o.FileSources { + if !strings.Contains(o.FileSources[i], "=") { + o.FileSources[i] = corev1.DockerConfigJsonKey + "=" + o.FileSources[i] + } + } return nil } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker_test.go index 5bb1cff19b2..649f35596a7 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_secret_docker_test.go @@ -17,11 +17,16 @@ limitations under the License. package create import ( + "encoding/json" + "fmt" + "os" "testing" corev1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/cli-runtime/pkg/genericiooptions" + cmdtesting "k8s.io/kubectl/pkg/cmd/testing" ) func TestCreateSecretDockerRegistry(t *testing.T) { @@ -183,3 +188,80 @@ func TestCreateSecretDockerRegistry(t *testing.T) { }) } } + +func TestCreateSecretDockerRegistryFromFile(t *testing.T) { + username, password, email, server := "test-user", "test-password", "test-user@example.org", "https://index.docker.io/v1/" + secretData, err := handleDockerCfgJSONContent(username, password, email, server) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: corev1.SchemeGroupVersion.String(), + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Type: corev1.SecretTypeDockerConfigJson, + Data: map[string][]byte{ + corev1.DockerConfigJsonKey: secretData, + }, + } + + tests := map[string]struct { + withKey bool + expected *corev1.Secret + }{ + "create_secret_docker_registry_from_file_with_keyname": { + withKey: true, + expected: secret, + }, + "create_secret_docker_registry_from_file_without_keyname": { + withKey: false, + expected: secret, + }, + } + + // Run all the tests + for name, test := range tests { + t.Run(name, func(t *testing.T) { + tmp, _ := os.MkdirTemp("", "input") + defer func() { + err := os.RemoveAll(tmp) + if err != nil { + t.Fatalf("Failed to teardown: %s", err) + } + }() + dockerCfgFile := tmp + "/dockerconfig.json" + err := os.WriteFile(dockerCfgFile, secretData, 0644) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + tf := cmdtesting.NewTestFactory() + defer tf.Cleanup() + ioStreams, _, out, _ := genericiooptions.NewTestIOStreams() + cmd := NewCmdCreateSecretDockerRegistry(tf, ioStreams) + args := []string{"foo", "--dry-run=client", "-ojson"} + if test.withKey { + args = append(args, fmt.Sprintf("--from-file=%s=%s", corev1.DockerConfigJsonKey, dockerCfgFile)) + } else { + args = append(args, fmt.Sprintf("--from-file=%s", dockerCfgFile)) + } + cmd.SetArgs(args) + err = cmd.Execute() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + got := &corev1.Secret{} + err = json.Unmarshal(out.Bytes(), got) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !apiequality.Semantic.DeepEqual(got, test.expected) { + t.Errorf("test %s\n expected:\n%#v\ngot:\n%#v", name, test.expected, got) + } + }) + } +}