Skip to content

Commit d7f492c

Browse files
imjasonhtekton-robot
authored andcommitted
Move creds-init to pkg/pod
This simplifies pod.go and makes this logic more easily testable/understandable in isolation, as part of an overall plan to simplify pod.go. This change also avoids running creds-init when there are no credentials to initialize. Previously, we would unconditionally run the creds-init image, and just pass it zero args if there were no creds, in which case it would exit immediately.
1 parent ac3ca43 commit d7f492c

File tree

8 files changed

+305
-170
lines changed

8 files changed

+305
-170
lines changed

pkg/pod/creds_init.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
Copyright 2019 The Tekton 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 pod
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/tektoncd/pipeline/pkg/credentials"
23+
"github.com/tektoncd/pipeline/pkg/credentials/dockercreds"
24+
"github.com/tektoncd/pipeline/pkg/credentials/gitcreds"
25+
"github.com/tektoncd/pipeline/pkg/names"
26+
corev1 "k8s.io/api/core/v1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/client-go/kubernetes"
29+
)
30+
31+
const (
32+
// Name of the credential initialization container.
33+
credsInit = "credential-initializer"
34+
)
35+
36+
func CredsInit(credsImage string, serviceAccountName, namespace string, kubeclient kubernetes.Interface, volumeMounts []corev1.VolumeMount, implicitEnvVars []corev1.EnvVar) (*corev1.Container, []corev1.Volume, error) {
37+
if serviceAccountName == "" {
38+
serviceAccountName = "default"
39+
}
40+
41+
sa, err := kubeclient.CoreV1().ServiceAccounts(namespace).Get(serviceAccountName, metav1.GetOptions{})
42+
if err != nil {
43+
return nil, nil, err
44+
}
45+
46+
builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()}
47+
48+
var volumes []corev1.Volume
49+
args := []string{}
50+
for _, secretEntry := range sa.Secrets {
51+
secret, err := kubeclient.CoreV1().Secrets(namespace).Get(secretEntry.Name, metav1.GetOptions{})
52+
if err != nil {
53+
return nil, nil, err
54+
}
55+
56+
matched := false
57+
for _, b := range builders {
58+
if sa := b.MatchingAnnotations(secret); len(sa) > 0 {
59+
matched = true
60+
args = append(args, sa...)
61+
}
62+
}
63+
64+
if matched {
65+
name := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("secret-volume-%s", secret.Name))
66+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
67+
Name: name,
68+
MountPath: credentials.VolumeName(secret.Name),
69+
})
70+
volumes = append(volumes, corev1.Volume{
71+
Name: name,
72+
VolumeSource: corev1.VolumeSource{
73+
Secret: &corev1.SecretVolumeSource{
74+
SecretName: secret.Name,
75+
},
76+
},
77+
})
78+
}
79+
}
80+
81+
if len(args) == 0 {
82+
// There are no creds to initialize.
83+
return nil, nil, nil
84+
}
85+
86+
return &corev1.Container{
87+
Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(credsInit),
88+
Image: credsImage,
89+
Command: []string{"/ko-app/creds-init"},
90+
Args: args,
91+
Env: implicitEnvVars,
92+
VolumeMounts: volumeMounts,
93+
}, volumes, nil
94+
}

pkg/pod/creds_init_test.go

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
Copyright 2019 The Tekton 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 pod
18+
19+
import (
20+
"testing"
21+
22+
"github.com/google/go-cmp/cmp"
23+
"github.com/tektoncd/pipeline/test/names"
24+
corev1 "k8s.io/api/core/v1"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/runtime"
27+
fakek8s "k8s.io/client-go/kubernetes/fake"
28+
)
29+
30+
const (
31+
credsImage = "creds-image"
32+
serviceAccountName = "my-service-account"
33+
namespace = "namespacey-mcnamespace"
34+
)
35+
36+
func TestCredsInit(t *testing.T) {
37+
volumeMounts := []corev1.VolumeMount{{
38+
Name: "implicit-volume-mount",
39+
}}
40+
envVars := []corev1.EnvVar{{
41+
Name: "FOO",
42+
Value: "bar",
43+
}}
44+
45+
for _, c := range []struct {
46+
desc string
47+
want *corev1.Container
48+
objs []runtime.Object
49+
}{{
50+
desc: "service account exists with no secrets; nothing to initialize",
51+
objs: []runtime.Object{
52+
&corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: serviceAccountName, Namespace: namespace}},
53+
},
54+
want: nil,
55+
}, {
56+
desc: "service account has no annotated secrets; nothing to initialize",
57+
objs: []runtime.Object{
58+
&corev1.ServiceAccount{
59+
ObjectMeta: metav1.ObjectMeta{Name: serviceAccountName, Namespace: namespace},
60+
Secrets: []corev1.ObjectReference{{
61+
Name: "my-creds",
62+
}},
63+
},
64+
&corev1.Secret{
65+
ObjectMeta: metav1.ObjectMeta{
66+
Name: "my-creds",
67+
Namespace: namespace,
68+
Annotations: map[string]string{
69+
// No matching annotations.
70+
},
71+
},
72+
},
73+
},
74+
want: nil,
75+
}, {
76+
desc: "service account has annotated secret; initialize creds",
77+
objs: []runtime.Object{
78+
&corev1.ServiceAccount{
79+
ObjectMeta: metav1.ObjectMeta{Name: serviceAccountName, Namespace: namespace},
80+
Secrets: []corev1.ObjectReference{{
81+
Name: "my-creds",
82+
}},
83+
},
84+
&corev1.Secret{
85+
ObjectMeta: metav1.ObjectMeta{
86+
Name: "my-creds",
87+
Namespace: namespace,
88+
Annotations: map[string]string{
89+
"tekton.dev/docker-0": "https://us.gcr.io",
90+
"tekton.dev/docker-1": "https://docker.io",
91+
"tekton.dev/git-0": "github.com",
92+
"tekton.dev/git-1": "gitlab.com",
93+
},
94+
},
95+
Type: "kubernetes.io/basic-auth",
96+
Data: map[string][]byte{
97+
"username": []byte("foo"),
98+
"password": []byte("BestEver"),
99+
},
100+
},
101+
},
102+
want: &corev1.Container{
103+
Name: "credential-initializer-mz4c7",
104+
Image: credsImage,
105+
Command: []string{"/ko-app/creds-init"},
106+
Args: []string{
107+
"-basic-docker=my-creds=https://docker.io",
108+
"-basic-docker=my-creds=https://us.gcr.io",
109+
"-basic-git=my-creds=github.com",
110+
"-basic-git=my-creds=gitlab.com",
111+
},
112+
Env: envVars,
113+
VolumeMounts: append(volumeMounts, corev1.VolumeMount{
114+
Name: "secret-volume-my-creds-9l9zj",
115+
MountPath: "/var/build-secrets/my-creds",
116+
}),
117+
},
118+
}} {
119+
t.Run(c.desc, func(t *testing.T) {
120+
names.TestingSeed()
121+
kubeclient := fakek8s.NewSimpleClientset(c.objs...)
122+
got, volumes, err := CredsInit(credsImage, serviceAccountName, namespace, kubeclient, volumeMounts, envVars)
123+
if err != nil {
124+
t.Fatalf("CredsInit: %v", err)
125+
}
126+
if got == nil && len(volumes) > 0 {
127+
t.Errorf("Got nil creds-init container, with non-empty volumes: %v", volumes)
128+
}
129+
if d := cmp.Diff(c.want, got); d != "" {
130+
t.Fatalf("Diff(-want, +got): %s", d)
131+
}
132+
})
133+
}
134+
}

pkg/pod/doc.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
Copyright 2019 The Tekton 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 pod provides methods for converting between a TaskRun and a Pod.
18+
package pod

pkg/pod/workingdir_init.go

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2019 The Tekton 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+
117
package pod
218

319
import (
@@ -54,6 +70,7 @@ func WorkingDirInit(shellImage string, steps []v1alpha1.Step) *corev1.Container
5470
}
5571

5672
if len(relativeDirs) == 0 {
73+
// There are no workingDirs to initialize.
5774
return nil
5875
}
5976

pkg/pod/workingdir_init_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2019 The Tekton 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+
117
package pod
218

319
import (

0 commit comments

Comments
 (0)