Skip to content

Commit ccf64eb

Browse files
committed
cleanup: breakup the pkg/credentials into writer and matcher
The credentials package contains the a matcher and a writer which out of which only the writer is used in cmd/entrypoint. In an effort to isolate usage and not indirectly import the corev1 api which the matcher uses for MatchingAnnotations, we are breaking up the credentials builder interface into two builders for writer and matcher. This ensures that the entrypoint only uses the writer and not the matcher, and we are only using either the writer or the matcher functionality as necessary and not importing unnecessary deps. cleanup: use better names for the credentials interfaces cleanup: use CredsDir from entrypoint pkg instead of pipeline cleanup: remove corev1 usage from credentials package cleanup: add goling gosec exception for Secret type constants
1 parent 990917d commit ccf64eb

File tree

13 files changed

+255
-167
lines changed

13 files changed

+255
-167
lines changed

cmd/entrypoint/main.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ import (
3030

3131
"github.com/tektoncd/pipeline/cmd/entrypoint/subcommands"
3232
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/types"
33-
"github.com/tektoncd/pipeline/pkg/credentials"
3433
"github.com/tektoncd/pipeline/pkg/credentials/dockercreds"
3534
"github.com/tektoncd/pipeline/pkg/credentials/gitcreds"
35+
credwriter "github.com/tektoncd/pipeline/pkg/credentials/writer"
3636
"github.com/tektoncd/pipeline/pkg/entrypoint"
37-
"github.com/tektoncd/pipeline/pkg/entrypoint/pipeline"
3837
"github.com/tektoncd/pipeline/pkg/platforms"
3938
"github.com/tektoncd/pipeline/pkg/termination"
4039
)
@@ -92,9 +91,9 @@ func main() {
9291
// from secret volume mounts to /tekton/creds. This is done to support the expansion
9392
// of a variable, $(credentials.path), that resolves to a single place with all the
9493
// stored credentials.
95-
builders := []credentials.Builder{dockercreds.NewBuilder(), gitcreds.NewBuilder()}
94+
builders := []credwriter.Writer{dockercreds.NewBuilder(), gitcreds.NewBuilder()}
9695
for _, c := range builders {
97-
if err := c.Write(pipeline.CredsDir); err != nil {
96+
if err := c.Write(entrypoint.CredsDir); err != nil {
9897
log.Printf("Error initializing credentials: %s", err)
9998
}
10099
}
@@ -154,7 +153,7 @@ func main() {
154153

155154
// Copy any creds injected by the controller into the $HOME directory of the current
156155
// user so that they're discoverable by git / ssh.
157-
if err := credentials.CopyCredsToHome(credentials.CredsInitCredentials); err != nil {
156+
if err := credwriter.CopyCredsToHome(credwriter.CredsInitCredentials); err != nil {
158157
log.Printf("non-fatal error copying credentials: %q", err)
159158
}
160159

pkg/credentials/common/constants.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package common
2+
3+
// Secret key constants used in credential files,
4+
// so as to avoid reliance on corev1.Secret.
5+
//
6+
//nolint:gosec // for known Kubernetes secret-type constants, not real credentials
7+
const (
8+
BasicAuthUsernameKey = "username"
9+
BasicAuthPasswordKey = "password"
10+
SSHAuthPrivateKey = "ssh-privatekey"
11+
DockerConfigKey = ".dockercfg"
12+
DockerConfigJsonKey = ".dockerconfigjson"
13+
SecretTypeBasicAuth = "kubernetes.io/basic-auth"
14+
SecretTypeSSHAuth = "kubernetes.io/ssh-auth"
15+
SecretTypeDockerConfigJson = "kubernetes.io/dockerconfigjson"
16+
SecretTypeDockercfg = "kubernetes.io/dockercfg"
17+
SecretTypeServiceAccountToken = "kubernetes.io/service-account-token"
18+
SecretTypeOpaque = "kubernetes.io/opaque"
19+
SecretTypeTLS = "kubernetes.io/tls"
20+
SecretTypeBootstrapToken = "kubernetes.io/bootstrap-token"
21+
)

pkg/credentials/dockercreds/creds.go

+27-21
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ import (
2525
"path/filepath"
2626
"strings"
2727

28-
"github.com/tektoncd/pipeline/pkg/credentials"
29-
corev1 "k8s.io/api/core/v1"
28+
"github.com/tektoncd/pipeline/pkg/credentials/common"
29+
credmatcher "github.com/tektoncd/pipeline/pkg/credentials/matcher"
30+
credwriter "github.com/tektoncd/pipeline/pkg/credentials/writer"
3031
)
3132

3233
const annotationPrefix = "tekton.dev/docker-"
@@ -117,15 +118,15 @@ type entry struct {
117118
}
118119

119120
func newEntry(secret string) (*entry, error) {
120-
secretPath := credentials.VolumeName(secret)
121+
secretPath := credmatcher.VolumeName(secret)
121122

122-
ub, err := os.ReadFile(filepath.Join(secretPath, corev1.BasicAuthUsernameKey))
123+
ub, err := os.ReadFile(filepath.Join(secretPath, common.BasicAuthUsernameKey))
123124
if err != nil {
124125
return nil, err
125126
}
126127
username := string(ub)
127128

128-
pb, err := os.ReadFile(filepath.Join(secretPath, corev1.BasicAuthPasswordKey))
129+
pb, err := os.ReadFile(filepath.Join(secretPath, common.BasicAuthPasswordKey))
129130
if err != nil {
130131
return nil, err
131132
}
@@ -143,25 +144,30 @@ func newEntry(secret string) (*entry, error) {
143144
type basicDockerBuilder struct{}
144145

145146
// NewBuilder returns a new builder for Docker credentials.
146-
func NewBuilder() credentials.Builder { return &basicDockerBuilder{} }
147+
func NewBuilder() interface {
148+
credmatcher.Matcher
149+
credwriter.Writer
150+
} {
151+
return &basicDockerBuilder{}
152+
}
147153

148154
// MatchingAnnotations extracts flags for the credential helper
149155
// from the supplied secret and returns a slice (of length 0 or
150156
// greater) of applicable domains.
151-
func (*basicDockerBuilder) MatchingAnnotations(secret *corev1.Secret) []string {
157+
func (*basicDockerBuilder) MatchingAnnotations(secret credmatcher.Secret) []string {
152158
var flags []string
153-
switch secret.Type {
154-
case corev1.SecretTypeBasicAuth:
155-
for _, v := range credentials.SortAnnotations(secret.Annotations, annotationPrefix) {
156-
flags = append(flags, fmt.Sprintf("-basic-docker=%s=%s", secret.Name, v))
159+
switch credmatcher.GetSecretType(secret) {
160+
case common.SecretTypeBasicAuth:
161+
for _, v := range credwriter.SortAnnotations(secret.GetAnnotations(), annotationPrefix) {
162+
flags = append(flags, fmt.Sprintf("-basic-docker=%s=%s", secret.GetName(), v))
157163
}
158-
case corev1.SecretTypeDockerConfigJson:
159-
flags = append(flags, "-docker-config="+secret.Name)
160-
case corev1.SecretTypeDockercfg:
161-
flags = append(flags, "-docker-cfg="+secret.Name)
164+
case common.SecretTypeDockerConfigJson:
165+
flags = append(flags, "-docker-config="+secret.GetName())
166+
case common.SecretTypeDockercfg:
167+
flags = append(flags, "-docker-cfg="+secret.GetName())
162168

163-
case corev1.SecretTypeOpaque, corev1.SecretTypeServiceAccountToken, corev1.SecretTypeSSHAuth, corev1.SecretTypeTLS, corev1.SecretTypeBootstrapToken:
164-
return flags
169+
case common.SecretTypeOpaque, common.SecretTypeServiceAccountToken, common.SecretTypeSSHAuth, common.SecretTypeTLS, common.SecretTypeBootstrapToken:
170+
fallthrough
165171

166172
default:
167173
return flags
@@ -218,9 +224,9 @@ func (*basicDockerBuilder) Write(directory string) error {
218224
}
219225

220226
func authsFromDockerCfg(secret string) (map[string]entry, error) {
221-
secretPath := credentials.VolumeName(secret)
227+
secretPath := credmatcher.VolumeName(secret)
222228
m := make(map[string]entry)
223-
data, err := os.ReadFile(filepath.Join(secretPath, corev1.DockerConfigKey))
229+
data, err := os.ReadFile(filepath.Join(secretPath, common.DockerConfigKey))
224230
if err != nil {
225231
return m, err
226232
}
@@ -229,10 +235,10 @@ func authsFromDockerCfg(secret string) (map[string]entry, error) {
229235
}
230236

231237
func authsFromDockerConfig(secret string) (map[string]entry, error) {
232-
secretPath := credentials.VolumeName(secret)
238+
secretPath := credmatcher.VolumeName(secret)
233239
m := make(map[string]entry)
234240
c := configFile{}
235-
data, err := os.ReadFile(filepath.Join(secretPath, corev1.DockerConfigJsonKey))
241+
data, err := os.ReadFile(filepath.Join(secretPath, common.DockerConfigJsonKey))
236242
if err != nil {
237243
return m, err
238244
}

pkg/credentials/dockercreds/creds_test.go

+30-30
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ import (
2323
"testing"
2424

2525
"github.com/google/go-cmp/cmp"
26-
"github.com/tektoncd/pipeline/pkg/credentials"
26+
credmatcher "github.com/tektoncd/pipeline/pkg/credentials/matcher"
2727
corev1 "k8s.io/api/core/v1"
2828
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2929
)
3030

3131
func TestFlagHandling(t *testing.T) {
32-
credentials.VolumePath = t.TempDir()
33-
dir := credentials.VolumeName("foo")
32+
credmatcher.VolumePath = t.TempDir()
33+
dir := credmatcher.VolumeName("foo")
3434
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
3535
t.Fatalf("os.MkdirAll(%s) = %v", dir, err)
3636
}
@@ -50,12 +50,12 @@ func TestFlagHandling(t *testing.T) {
5050
t.Fatalf("flag.CommandLine.Parse() = %v", err)
5151
}
5252

53-
t.Setenv("HOME", credentials.VolumePath)
54-
if err := NewBuilder().Write(credentials.VolumePath); err != nil {
53+
t.Setenv("HOME", credmatcher.VolumePath)
54+
if err := NewBuilder().Write(credmatcher.VolumePath); err != nil {
5555
t.Fatalf("Write() = %v", err)
5656
}
5757

58-
b, err := os.ReadFile(filepath.Join(credentials.VolumePath, ".docker", "config.json"))
58+
b, err := os.ReadFile(filepath.Join(credmatcher.VolumePath, ".docker", "config.json"))
5959
if err != nil {
6060
t.Fatalf("os.ReadFile(.docker/config.json) = %v", err)
6161
}
@@ -68,8 +68,8 @@ func TestFlagHandling(t *testing.T) {
6868
}
6969

7070
func TestFlagHandlingTwice(t *testing.T) {
71-
credentials.VolumePath = t.TempDir()
72-
fooDir := credentials.VolumeName("foo")
71+
credmatcher.VolumePath = t.TempDir()
72+
fooDir := credmatcher.VolumeName("foo")
7373
if err := os.MkdirAll(fooDir, os.ModePerm); err != nil {
7474
t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err)
7575
}
@@ -79,7 +79,7 @@ func TestFlagHandlingTwice(t *testing.T) {
7979
if err := os.WriteFile(filepath.Join(fooDir, corev1.BasicAuthPasswordKey), []byte("blah"), 0o777); err != nil {
8080
t.Fatalf("os.WriteFile(password) = %v", err)
8181
}
82-
barDir := credentials.VolumeName("bar")
82+
barDir := credmatcher.VolumeName("bar")
8383
if err := os.MkdirAll(barDir, os.ModePerm); err != nil {
8484
t.Fatalf("os.MkdirAll(%s) = %v", barDir, err)
8585
}
@@ -100,12 +100,12 @@ func TestFlagHandlingTwice(t *testing.T) {
100100
t.Fatalf("flag.CommandLine.Parse() = %v", err)
101101
}
102102

103-
t.Setenv("HOME", credentials.VolumePath)
104-
if err := NewBuilder().Write(credentials.VolumePath); err != nil {
103+
t.Setenv("HOME", credmatcher.VolumePath)
104+
if err := NewBuilder().Write(credmatcher.VolumePath); err != nil {
105105
t.Fatalf("Write() = %v", err)
106106
}
107107

108-
b, err := os.ReadFile(filepath.Join(credentials.VolumePath, ".docker", "config.json"))
108+
b, err := os.ReadFile(filepath.Join(credmatcher.VolumePath, ".docker", "config.json"))
109109
if err != nil {
110110
t.Fatalf("os.ReadFile(.docker/config.json) = %v", err)
111111
}
@@ -118,8 +118,8 @@ func TestFlagHandlingTwice(t *testing.T) {
118118
}
119119

120120
func TestFlagHandlingMissingFiles(t *testing.T) {
121-
credentials.VolumePath = t.TempDir()
122-
dir := credentials.VolumeName("not-found")
121+
credmatcher.VolumePath = t.TempDir()
122+
dir := credmatcher.VolumeName("not-found")
123123
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
124124
t.Fatalf("os.MkdirAll(%s) = %v", dir, err)
125125
}
@@ -132,8 +132,8 @@ func TestFlagHandlingMissingFiles(t *testing.T) {
132132
}
133133

134134
func TestFlagHandlingURLCollision(t *testing.T) {
135-
credentials.VolumePath = t.TempDir()
136-
dir := credentials.VolumeName("foo")
135+
credmatcher.VolumePath = t.TempDir()
136+
dir := credmatcher.VolumeName("foo")
137137
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
138138
t.Fatalf("os.MkdirAll(%s) = %v", dir, err)
139139
}
@@ -244,8 +244,8 @@ func TestMatchingAnnotations(t *testing.T) {
244244
}
245245

246246
func TestMultipleFlagHandling(t *testing.T) {
247-
credentials.VolumePath = t.TempDir()
248-
fooDir := credentials.VolumeName("foo")
247+
credmatcher.VolumePath = t.TempDir()
248+
fooDir := credmatcher.VolumeName("foo")
249249
if err := os.MkdirAll(fooDir, os.ModePerm); err != nil {
250250
t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err)
251251
}
@@ -256,31 +256,31 @@ func TestMultipleFlagHandling(t *testing.T) {
256256
t.Fatalf("os.WriteFile(password) = %v", err)
257257
}
258258

259-
barDir := credentials.VolumeName("bar")
259+
barDir := credmatcher.VolumeName("bar")
260260
if err := os.MkdirAll(barDir, os.ModePerm); err != nil {
261261
t.Fatalf("os.MkdirAll(%s) = %v", barDir, err)
262262
}
263263
if err := os.WriteFile(filepath.Join(barDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"https://index.docker.io/v1":{"auth":"fooisbar"}}}`), 0o777); err != nil {
264264
t.Fatalf("os.WriteFile(username) = %v", err)
265265
}
266266

267-
blubbDir := credentials.VolumeName("blubb")
267+
blubbDir := credmatcher.VolumeName("blubb")
268268
if err := os.MkdirAll(blubbDir, os.ModePerm); err != nil {
269269
t.Fatalf("os.MkdirAll(%s) = %v", blubbDir, err)
270270
}
271271
if err := os.WriteFile(filepath.Join(blubbDir, corev1.DockerConfigJsonKey), []byte(`{"auths":{"us.icr.io":{"auth":"fooisblubb"}}}`), 0o777); err != nil {
272272
t.Fatalf("os.WriteFile(username) = %v", err)
273273
}
274274

275-
bazDir := credentials.VolumeName("baz")
275+
bazDir := credmatcher.VolumeName("baz")
276276
if err := os.MkdirAll(bazDir, os.ModePerm); err != nil {
277277
t.Fatalf("os.MkdirAll(%s) = %v", bazDir, err)
278278
}
279279
if err := os.WriteFile(filepath.Join(bazDir, corev1.DockerConfigKey), []byte(`{"https://my.registry/v1":{"auth":"fooisbaz"}}`), 0o777); err != nil {
280280
t.Fatalf("os.WriteFile(username) = %v", err)
281281
}
282282

283-
blaDir := credentials.VolumeName("bla")
283+
blaDir := credmatcher.VolumeName("bla")
284284
if err := os.MkdirAll(blaDir, os.ModePerm); err != nil {
285285
t.Fatalf("os.MkdirAll(%s) = %v", blaDir, err)
286286
}
@@ -301,12 +301,12 @@ func TestMultipleFlagHandling(t *testing.T) {
301301
t.Fatalf("flag.CommandLine.Parse() = %v", err)
302302
}
303303

304-
t.Setenv("HOME", credentials.VolumePath)
305-
if err := NewBuilder().Write(credentials.VolumePath); err != nil {
304+
t.Setenv("HOME", credmatcher.VolumePath)
305+
if err := NewBuilder().Write(credmatcher.VolumePath); err != nil {
306306
t.Fatalf("Write() = %v", err)
307307
}
308308

309-
b, err := os.ReadFile(filepath.Join(credentials.VolumePath, ".docker", "config.json"))
309+
b, err := os.ReadFile(filepath.Join(credmatcher.VolumePath, ".docker", "config.json"))
310310
if err != nil {
311311
t.Fatalf("os.ReadFile(.docker/config.json) = %v", err)
312312
}
@@ -321,8 +321,8 @@ func TestMultipleFlagHandling(t *testing.T) {
321321
// TestNoAuthProvided confirms that providing zero secrets results in no docker
322322
// credential file being written to disk.
323323
func TestNoAuthProvided(t *testing.T) {
324-
credentials.VolumePath = t.TempDir()
325-
fooDir := credentials.VolumeName("foo")
324+
credmatcher.VolumePath = t.TempDir()
325+
fooDir := credmatcher.VolumeName("foo")
326326
if err := os.MkdirAll(fooDir, os.ModePerm); err != nil {
327327
t.Fatalf("os.MkdirAll(%s) = %v", fooDir, err)
328328
}
@@ -333,11 +333,11 @@ func TestNoAuthProvided(t *testing.T) {
333333
if err != nil {
334334
t.Fatalf("flag.CommandLine.Parse() = %v", err)
335335
}
336-
t.Setenv("HOME", credentials.VolumePath)
337-
if err := NewBuilder().Write(credentials.VolumePath); err != nil {
336+
t.Setenv("HOME", credmatcher.VolumePath)
337+
if err := NewBuilder().Write(credmatcher.VolumePath); err != nil {
338338
t.Fatalf("Write() = %v", err)
339339
}
340-
_, err = os.ReadFile(filepath.Join(credentials.VolumePath, ".docker", "config.json"))
340+
_, err = os.ReadFile(filepath.Join(credmatcher.VolumePath, ".docker", "config.json"))
341341
if err == nil || !os.IsNotExist(err) {
342342
t.Errorf("expected does not exist error but received: %v", err)
343343
}

pkg/credentials/gitcreds/basic.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import (
2323
"path/filepath"
2424
"strings"
2525

26-
"github.com/tektoncd/pipeline/pkg/credentials"
27-
corev1 "k8s.io/api/core/v1"
26+
"github.com/tektoncd/pipeline/pkg/credentials/common"
27+
credmatcher "github.com/tektoncd/pipeline/pkg/credentials/matcher"
2828
)
2929

3030
// As the flag is read, this status is populated.
@@ -121,15 +121,15 @@ func (be *basicEntry) escapedUsername() string {
121121
}
122122

123123
func newBasicEntry(u, secret string) (*basicEntry, error) {
124-
secretPath := credentials.VolumeName(secret)
124+
secretPath := credmatcher.VolumeName(secret)
125125

126-
ub, err := os.ReadFile(filepath.Join(secretPath, corev1.BasicAuthUsernameKey))
126+
ub, err := os.ReadFile(filepath.Join(secretPath, common.BasicAuthUsernameKey))
127127
if err != nil {
128128
return nil, err
129129
}
130130
username := string(ub)
131131

132-
pb, err := os.ReadFile(filepath.Join(secretPath, corev1.BasicAuthPasswordKey))
132+
pb, err := os.ReadFile(filepath.Join(secretPath, common.BasicAuthPasswordKey))
133133
if err != nil {
134134
return nil, err
135135
}

0 commit comments

Comments
 (0)