Skip to content

Commit ec7ff7e

Browse files
authored
oci: refactors pusher auth (#2979)
Signed-off-by: kapil <kapilsareen584@gmail.com>
1 parent 92cb030 commit ec7ff7e

14 files changed

Lines changed: 236 additions & 116 deletions

cmd/build.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,14 @@ func (c buildConfig) clientOptions() ([]fn.Option, error) {
394394
o := []fn.Option{fn.WithRegistry(c.Registry)}
395395
switch c.Builder {
396396
case builders.Host:
397+
t := newTransport(c.RegistryInsecure) // may provide a custom impl which proxies
398+
creds := newCredentialsProvider(config.Dir(), t)
397399
o = append(o,
398400
fn.WithBuilder(oci.NewBuilder(builders.Host, c.Verbose)),
399-
fn.WithPusher(oci.NewPusher(c.RegistryInsecure, false, c.Verbose)))
401+
fn.WithPusher(oci.NewPusher(c.RegistryInsecure, false, c.Verbose,
402+
oci.WithCredentialsProvider(creds),
403+
oci.WithVerbose(c.Verbose))),
404+
)
400405
case builders.Pack:
401406
o = append(o,
402407
fn.WithBuilder(pack.NewBuilder(

cmd/client.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import (
88
"knative.dev/func/cmd/prompt"
99
"knative.dev/func/pkg/builders/buildpacks"
1010
"knative.dev/func/pkg/config"
11+
"knative.dev/func/pkg/creds"
1112
"knative.dev/func/pkg/docker"
12-
"knative.dev/func/pkg/docker/creds"
1313
fn "knative.dev/func/pkg/functions"
1414
fnhttp "knative.dev/func/pkg/http"
1515
"knative.dev/func/pkg/k8s"
1616
"knative.dev/func/pkg/knative"
17+
"knative.dev/func/pkg/oci"
1718
"knative.dev/func/pkg/pipelines/tekton"
1819
)
1920

@@ -100,19 +101,22 @@ func newTransport(insecureSkipVerify bool) fnhttp.RoundTripCloser {
100101
// newCredentialsProvider returns a credentials provider which possibly
101102
// has cluster-flavor specific additional credential loaders to take advantage
102103
// of features or configuration nuances of cluster variants.
103-
func newCredentialsProvider(configPath string, t http.RoundTripper) docker.CredentialsProvider {
104+
func newCredentialsProvider(configPath string, t http.RoundTripper) oci.CredentialsProvider {
105+
additionalLoaders := append(k8s.GetOpenShiftDockerCredentialLoaders(), k8s.GetGoogleCredentialLoader()...)
106+
additionalLoaders = append(additionalLoaders, k8s.GetECRCredentialLoader()...)
107+
additionalLoaders = append(additionalLoaders, k8s.GetACRCredentialLoader()...)
104108
options := []creds.Opt{
105109
creds.WithPromptForCredentials(prompt.NewPromptForCredentials(os.Stdin, os.Stdout, os.Stderr)),
106110
creds.WithPromptForCredentialStore(prompt.NewPromptForCredentialStore()),
107111
creds.WithTransport(t),
108-
creds.WithAdditionalCredentialLoaders(k8s.GetOpenShiftDockerCredentialLoaders()...),
112+
creds.WithAdditionalCredentialLoaders(additionalLoaders...),
109113
}
110114

111115
// Other cluster variants can be supported here
112116
return creds.NewCredentialsProvider(configPath, options...)
113117
}
114118

115-
func newTektonPipelinesProvider(creds docker.CredentialsProvider, verbose bool) *tekton.PipelinesProvider {
119+
func newTektonPipelinesProvider(creds oci.CredentialsProvider, verbose bool) *tekton.PipelinesProvider {
116120
options := []tekton.Opt{
117121
tekton.WithCredentialsProvider(creds),
118122
tekton.WithVerbose(verbose),

cmd/prompt/prompt.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ import (
1111
"github.com/AlecAivazis/survey/v2/terminal"
1212
"golang.org/x/term"
1313

14-
"knative.dev/func/pkg/docker"
15-
"knative.dev/func/pkg/docker/creds"
14+
"knative.dev/func/pkg/creds"
15+
"knative.dev/func/pkg/oci"
1616
)
1717

18-
func NewPromptForCredentials(in io.Reader, out, errOut io.Writer) func(repository string) (docker.Credentials, error) {
18+
func NewPromptForCredentials(in io.Reader, out, errOut io.Writer) func(repository string) (oci.Credentials, error) {
1919
firstTime := true
20-
return func(repository string) (docker.Credentials, error) {
21-
var result docker.Credentials
20+
return func(repository string) (oci.Credentials, error) {
21+
var result oci.Credentials
2222
if firstTime {
2323
firstTime = false
2424
fmt.Fprintf(out, "Please provide credentials for image repository '%s'.\n", repository)
@@ -56,26 +56,26 @@ func NewPromptForCredentials(in io.Reader, out, errOut io.Writer) func(repositor
5656
if isTerm {
5757
err := survey.Ask(qs, &result, survey.WithStdio(fr, out.(terminal.FileWriter), errOut))
5858
if err != nil {
59-
return docker.Credentials{}, err
59+
return oci.Credentials{}, err
6060
}
6161
} else {
6262
reader := bufio.NewReader(in)
6363

6464
fmt.Fprintf(out, "Username: ")
6565
u, err := reader.ReadString('\n')
6666
if err != nil {
67-
return docker.Credentials{}, err
67+
return oci.Credentials{}, err
6868
}
6969
u = strings.Trim(u, "\r\n")
7070

7171
fmt.Fprintf(out, "Password: ")
7272
p, err := reader.ReadString('\n')
7373
if err != nil {
74-
return docker.Credentials{}, err
74+
return oci.Credentials{}, err
7575
}
7676
p = strings.Trim(p, "\r\n")
7777

78-
result = docker.Credentials{Username: u, Password: p}
78+
result = oci.Credentials{Username: u, Password: p}
7979
}
8080

8181
return result, nil

cmd/prompt/prompt_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@ import (
1212
"github.com/Netflix/go-expect"
1313
"github.com/creack/pty"
1414
"github.com/hinshun/vt10x"
15-
16-
"knative.dev/func/pkg/docker"
15+
"knative.dev/func/pkg/oci"
1716
)
1817

1918
const (
2019
enter = "\r"
2120
)
2221

2322
func Test_NewPromptForCredentials(t *testing.T) {
24-
expectedCreds := docker.Credentials{
23+
expectedCreds := oci.Credentials{
2524
Username: "testuser",
2625
Password: "testpwd",
2726
}
Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ import (
2222
"github.com/google/go-containerregistry/pkg/v1/remote"
2323
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
2424

25-
"knative.dev/func/pkg/docker"
25+
"knative.dev/func/pkg/oci"
2626
)
2727

28-
type CredentialsCallback func(registry string) (docker.Credentials, error)
28+
type CredentialsCallback func(registry string) (oci.Credentials, error)
2929

3030
var ErrUnauthorized = errors.New("bad credentials")
3131

3232
var ErrCredentialsNotFound = errors.New("credentials not found")
3333

3434
// VerifyCredentialsCallback checks if credentials are authorized for image push.
3535
// If credentials are incorrect this callback shall return ErrUnauthorized.
36-
type VerifyCredentialsCallback func(ctx context.Context, image string, credentials docker.Credentials) error
36+
type VerifyCredentialsCallback func(ctx context.Context, image string, credentials oci.Credentials) error
3737

3838
type keyChain struct {
3939
user string
@@ -48,7 +48,7 @@ func (k keyChain) Resolve(resource authn.Resource) (authn.Authenticator, error)
4848
}
4949

5050
// CheckAuth verifies that credentials can be used for image push
51-
func CheckAuth(ctx context.Context, image string, credentials docker.Credentials, trans http.RoundTripper) error {
51+
func CheckAuth(ctx context.Context, image string, credentials oci.Credentials, trans http.RoundTripper) error {
5252

5353
ref, err := name.ParseReference(image)
5454
if err != nil {
@@ -142,9 +142,8 @@ func WithAdditionalCredentialLoaders(loaders ...CredentialsCallback) Opt {
142142
// The picked value will be saved in the func config.
143143
//
144144
// To verify that credentials are correct custom callback can be used (see WithVerifyCredentials).
145-
func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsProvider {
145+
func NewCredentialsProvider(configPath string, opts ...Opt) oci.CredentialsProvider {
146146
var c credentialsProvider
147-
148147
for _, o := range opts {
149148
o(&c)
150149
}
@@ -154,7 +153,7 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
154153
}
155154

156155
if c.verifyCredentials == nil {
157-
c.verifyCredentials = func(ctx context.Context, registry string, credentials docker.Credentials) error {
156+
c.verifyCredentials = func(ctx context.Context, registry string, credentials oci.Credentials) error {
158157
return CheckAuth(ctx, registry, credentials, c.transport)
159158
}
160159
}
@@ -175,7 +174,7 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
175174

176175
if _, err := os.Stat(c.authFilePath); err == nil {
177176
defaultCredentialLoaders = append(defaultCredentialLoaders,
178-
func(registry string) (docker.Credentials, error) {
177+
func(registry string) (oci.Credentials, error) {
179178
return getCredentialsByCredentialHelper(c.authFilePath, registry)
180179
})
181180
}
@@ -185,54 +184,54 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
185184
if err == nil {
186185
dockerConfigPath := filepath.Join(home, ".docker", "config.json")
187186
defaultCredentialLoaders = append(defaultCredentialLoaders,
188-
func(registry string) (docker.Credentials, error) {
187+
func(registry string) (oci.Credentials, error) {
189188
return getCredentialsByCredentialHelper(dockerConfigPath, registry)
190189
})
191190
}
192191
defaultCredentialLoaders = append(defaultCredentialLoaders,
193-
func(registry string) (docker.Credentials, error) {
192+
func(registry string) (oci.Credentials, error) {
194193
creds, err := dockerConfig.GetCredentials(sys, registry)
195194
if err != nil {
196-
return docker.Credentials{}, err
195+
return oci.Credentials{}, err
197196
}
198197
if creds.Username == "" || creds.Password == "" {
199-
return docker.Credentials{}, ErrCredentialsNotFound
198+
return oci.Credentials{}, ErrCredentialsNotFound
200199
}
201-
return docker.Credentials{
200+
return oci.Credentials{
202201
Username: creds.Username,
203202
Password: creds.Password,
204203
}, nil
205204
})
206205
defaultCredentialLoaders = append(defaultCredentialLoaders,
207-
func(registry string) (docker.Credentials, error) {
206+
func(registry string) (oci.Credentials, error) {
208207
// Fallback onto default docker config locations
209208
emptySys := &containersTypes.SystemContext{}
210209
creds, err := dockerConfig.GetCredentials(emptySys, registry)
211210
if err != nil {
212-
return docker.Credentials{}, err
211+
return oci.Credentials{}, err
213212
}
214-
return docker.Credentials{
213+
return oci.Credentials{
215214
Username: creds.Username,
216215
Password: creds.Password,
217216
}, nil
218217
})
219218
defaultCredentialLoaders = append(defaultCredentialLoaders,
220-
func(registry string) (docker.Credentials, error) { // empty credentials provider for unsecured registries
221-
return docker.Credentials{}, nil
219+
func(registry string) (oci.Credentials, error) { // empty credentials provider for unsecured registries
220+
return oci.Credentials{}, nil
222221
})
223222

224223
c.credentialLoaders = append(c.credentialLoaders, defaultCredentialLoaders...)
225224

226225
return c.getCredentials
227226
}
228227

229-
func (c *credentialsProvider) getCredentials(ctx context.Context, image string) (docker.Credentials, error) {
228+
func (c *credentialsProvider) getCredentials(ctx context.Context, image string) (oci.Credentials, error) {
230229
var err error
231-
result := docker.Credentials{}
230+
result := oci.Credentials{}
232231

233232
ref, err := name.ParseReference(image)
234233
if err != nil {
235-
return docker.Credentials{}, fmt.Errorf("cannot parse the image reference: %w", err)
234+
return oci.Credentials{}, fmt.Errorf("cannot parse the image reference: %w", err)
236235
}
237236

238237
registry := ref.Context().RegistryStr()
@@ -244,22 +243,22 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
244243
if errors.Is(err, ErrCredentialsNotFound) {
245244
continue
246245
}
247-
return docker.Credentials{}, err
246+
return oci.Credentials{}, err
248247
}
249248

250249
err = c.verifyCredentials(ctx, image, result)
251250
if err == nil {
252251
return result, nil
253252
} else {
254253
if !errors.Is(err, ErrUnauthorized) {
255-
return docker.Credentials{}, err
254+
return oci.Credentials{}, err
256255
}
257256
}
258257

259258
}
260259

261260
if c.promptForCredentials == nil {
262-
return docker.Credentials{}, ErrCredentialsNotFound
261+
return oci.Credentials{}, ErrCredentialsNotFound
263262
}
264263

265264
// this is [registry] / [repository]
@@ -271,7 +270,7 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
271270
// use repo here to print it out in prompt
272271
result, err = c.promptForCredentials(repository)
273272
if err != nil {
274-
return docker.Credentials{}, err
273+
return oci.Credentials{}, err
275274
}
276275

277276
err = c.verifyCredentials(ctx, image, result)
@@ -282,33 +281,33 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
282281
// This shouldn't be fatal error.
283282
if strings.Contains(err.Error(), "not implemented") {
284283
fmt.Fprintf(os.Stderr, "the cred-helper does not support write operation (consider changing the cred-helper it in auth.json)\n")
285-
return docker.Credentials{}, nil
284+
return oci.Credentials{}, nil
286285
}
287286

288287
if !errors.Is(err, errNoCredentialHelperConfigured) {
289-
return docker.Credentials{}, err
288+
return oci.Credentials{}, err
290289
}
291290
helpers := listCredentialHelpers()
292291
helper, err := c.promptForCredentialStore(helpers)
293292
if err != nil {
294-
return docker.Credentials{}, err
293+
return oci.Credentials{}, err
295294
}
296295
helper = strings.TrimPrefix(helper, "docker-credential-")
297296
err = setCredentialHelperToConfig(c.authFilePath, helper)
298297
if err != nil {
299-
return docker.Credentials{}, fmt.Errorf("faild to set the helper to the config: %w", err)
298+
return oci.Credentials{}, fmt.Errorf("faild to set the helper to the config: %w", err)
300299
}
301300
err = setCredentialsByCredentialHelper(c.authFilePath, registry, result.Username, result.Password)
302301
if err != nil {
303302

304303
// This shouldn't be fatal error.
305304
if strings.Contains(err.Error(), "not implemented") {
306305
fmt.Fprintf(os.Stderr, "the cred-helper does not support write operation (consider changing the cred-helper it in auth.json)\n")
307-
return docker.Credentials{}, nil
306+
return oci.Credentials{}, nil
308307
}
309308

310309
if !errors.Is(err, errNoCredentialHelperConfigured) {
311-
return docker.Credentials{}, err
310+
return oci.Credentials{}, err
312311
}
313312
}
314313
}
@@ -317,7 +316,7 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, image string)
317316
if errors.Is(err, ErrUnauthorized) {
318317
continue
319318
}
320-
return docker.Credentials{}, err
319+
return oci.Credentials{}, err
321320
}
322321
}
323322
}
@@ -374,8 +373,8 @@ func setCredentialHelperToConfig(confFilePath, helper string) error {
374373
return nil
375374
}
376375

377-
func getCredentialsByCredentialHelper(confFilePath, registry string) (docker.Credentials, error) {
378-
result := docker.Credentials{}
376+
func getCredentialsByCredentialHelper(confFilePath, registry string) (oci.Credentials, error) {
377+
result := oci.Credentials{}
379378

380379
helper, err := getCredentialHelperFromConfig(confFilePath)
381380
if err != nil && !os.IsNotExist(err) {

0 commit comments

Comments
 (0)