github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/cluster/secret.go (about) 1 /* 2 Copyright 2019 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package cluster 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "io/ioutil" 24 25 v1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 typedV1 "k8s.io/client-go/kubernetes/typed/core/v1" 28 29 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/kaniko" 30 kubernetesclient "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client" 31 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output" 32 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log" 33 ) 34 35 const ( 36 defaultKanikoSecretPath = "kaniko-secret" 37 ) 38 39 func (b *Builder) setupPullSecret(ctx context.Context, out io.Writer) (func(), error) { 40 if b.PullSecretPath == "" && b.PullSecretName == "" { 41 return func() {}, nil 42 } 43 44 output.Default.Fprintf(out, "Checking for kaniko secret [%s/%s]...\n", b.Namespace, b.PullSecretName) 45 client, err := kubernetesclient.DefaultClient() 46 if err != nil { 47 return nil, fmt.Errorf("getting Kubernetes client: %w", err) 48 } 49 50 secrets := client.CoreV1().Secrets(b.Namespace) 51 if _, err := secrets.Get(ctx, b.PullSecretName, metav1.GetOptions{}); err != nil { 52 output.Default.Fprintf(out, "Creating kaniko secret [%s/%s]...\n", b.Namespace, b.PullSecretName) 53 if b.PullSecretPath == "" { 54 return nil, fmt.Errorf("secret %s does not exist. No path specified to create it", b.PullSecretName) 55 } 56 return b.createSecretFromFile(ctx, secrets) 57 } 58 if b.PullSecretPath == "" { 59 // TODO: Remove the warning when pod health check can display pod failure errors. 60 log.Entry(ctx).Warnf("Assuming the secret %s is mounted inside Kaniko pod with the filename %s. If your secret is mounted at different path, please specify using config key `pullSecretPath`.\nSee https://skaffold.dev/docs/references/yaml/#build-cluster-pullSecretPath", b.PullSecretName, defaultKanikoSecretPath) 61 b.PullSecretPath = defaultKanikoSecretPath 62 return func() {}, nil 63 } 64 return func() {}, nil 65 } 66 67 func (b *Builder) createSecretFromFile(ctx context.Context, secrets typedV1.SecretInterface) (func(), error) { 68 secretData, err := ioutil.ReadFile(b.PullSecretPath) 69 if err != nil { 70 return nil, fmt.Errorf("cannot create secret %s from path %s. reading pull secret: %w", b.PullSecretName, b.PullSecretPath, err) 71 } 72 secret := &v1.Secret{ 73 ObjectMeta: metav1.ObjectMeta{ 74 Name: b.PullSecretName, 75 Labels: map[string]string{"skaffold-kaniko": "skaffold-kaniko"}, 76 }, 77 Data: map[string][]byte{ 78 kaniko.DefaultSecretName: secretData, 79 }, 80 } 81 b.PullSecretPath = kaniko.DefaultSecretName 82 if _, err := secrets.Create(ctx, secret, metav1.CreateOptions{}); err != nil { 83 return nil, fmt.Errorf("creating pull secret %q: %w", b.PullSecretName, err) 84 } 85 86 return func() { 87 if err := secrets.Delete(ctx, b.PullSecretName, metav1.DeleteOptions{}); err != nil { 88 log.Entry(ctx).Warn("deleting pull secret") 89 } 90 }, nil 91 } 92 93 func (b *Builder) setupDockerConfigSecret(ctx context.Context, out io.Writer) (func(), error) { 94 if b.DockerConfig == nil { 95 return func() {}, nil 96 } 97 98 output.Default.Fprintf(out, "Creating docker config secret [%s]...\n", b.DockerConfig.SecretName) 99 100 client, err := kubernetesclient.DefaultClient() 101 if err != nil { 102 return nil, fmt.Errorf("getting Kubernetes client: %w", err) 103 } 104 105 secrets := client.CoreV1().Secrets(b.Namespace) 106 107 if b.DockerConfig.Path == "" { 108 log.Entry(ctx).Debug("No docker config specified. Checking for one in the cluster.") 109 110 if _, err := secrets.Get(ctx, b.DockerConfig.SecretName, metav1.GetOptions{}); err != nil { 111 return nil, fmt.Errorf("checking for existing kaniko secret: %w", err) 112 } 113 114 return func() {}, nil 115 } 116 117 secretData, err := ioutil.ReadFile(b.DockerConfig.Path) 118 if err != nil { 119 return nil, fmt.Errorf("reading docker config: %w", err) 120 } 121 122 secret := &v1.Secret{ 123 ObjectMeta: metav1.ObjectMeta{ 124 Name: b.DockerConfig.SecretName, 125 Labels: map[string]string{"skaffold-kaniko": "skaffold-kaniko"}, 126 }, 127 Data: map[string][]byte{ 128 "config.json": secretData, 129 }, 130 } 131 132 if _, err := secrets.Create(ctx, secret, metav1.CreateOptions{}); err != nil { 133 return nil, fmt.Errorf("creating docker config secret %q: %w", b.DockerConfig.SecretName, err) 134 } 135 136 return func() { 137 if err := secrets.Delete(ctx, b.DockerConfig.SecretName, metav1.DeleteOptions{}); err != nil { 138 log.Entry(ctx).Warn("deleting docker config secret") 139 } 140 }, nil 141 }