src: use common functionality for docker cred retrieval (#756)

* Use common functionality for docker cred retrieval

Signed-off-by: Matej Vasek <mvasek@redhat.com>

* fixup: docker auth secret for tekton pipeline

Signed-off-by: Matej Vasek <mvasek@redhat.com>

* fixup: style

Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
Matej Vasek 2022-01-13 12:52:12 +01:00 committed by GitHub
parent cb719ff564
commit 15d617f99d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 82 deletions

View File

@ -20,7 +20,6 @@ import (
"knative.dev/kn-plugin-func/docker"
"knative.dev/kn-plugin-func/docker/creds"
"knative.dev/kn-plugin-func/knative"
"knative.dev/kn-plugin-func/pipelines"
"knative.dev/kn-plugin-func/pipelines/tekton"
"knative.dev/kn-plugin-func/progress"
)
@ -37,11 +36,13 @@ func newDeployClient(cfg deployConfig) (*fn.Client, error) {
pusher *docker.Pusher
err error
)
credentialsProvider := creds.NewCredentialsProvider(
creds.WithPromptForCredentials(newPromptForCredentials()),
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
creds.WithTransport(cfg.Transport))
if cfg.Push {
credentialsProvider := creds.NewCredentialsProvider(
creds.WithPromptForCredentials(newPromptForCredentials()),
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
creds.WithTransport(cfg.Transport))
pusher, err = docker.NewPusher(
docker.WithCredentialsProvider(credentialsProvider),
docker.WithProgressListener(listener),
@ -60,7 +61,7 @@ func newDeployClient(cfg deployConfig) (*fn.Client, error) {
pipelinesProvider, err := tekton.NewPipelinesProvider(
tekton.WithNamespace(cfg.Namespace),
tekton.WithProgressListener(listener),
tekton.WithPromptForContainerRegistryCredentials(newPromptForPipelineRegistryCredentials()))
tekton.WithCredentialsProvider(credentialsProvider))
if err != nil {
return nil, err
}
@ -287,44 +288,6 @@ func newPromptForCredentials() func(registry string) (docker.Credentials, error)
}
}
func newPromptForPipelineRegistryCredentials() pipelines.ContainerRegistryCredentialsCallback {
return func() (pipelines.ContainerRegistryCredentials, error) {
var result pipelines.ContainerRegistryCredentials
var qs = []*survey.Question{
{
Name: "server",
Prompt: &survey.Input{
Message: "Server:",
Default: "https://index.docker.io/v1/",
},
Validate: survey.Required,
},
{
Name: "username",
Prompt: &survey.Input{
Message: "Username:",
},
Validate: survey.Required,
},
{
Name: "password",
Prompt: &survey.Password{
Message: "Password:",
},
Validate: survey.Required,
},
}
fmt.Printf("Please provide credentials for the image registry used by Pipeline.\n")
err := survey.Ask(qs, &result)
if err != nil {
return pipelines.ContainerRegistryCredentials{}, err
}
return result, nil
}
}
func newPromptForCredentialStore() creds.ChooseCredentialHelperCallback {
return func(availableHelpers []string) (string, error) {
if len(availableHelpers) < 1 {

View File

@ -12,13 +12,11 @@ import (
"net/http"
"os"
"regexp"
"strings"
"github.com/docker/docker/client"
fn "knative.dev/kn-plugin-func"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
@ -111,18 +109,12 @@ func NewPusher(opts ...Opt) (*Pusher, error) {
return result, nil
}
func GetRegistry(image_url string) (string, error) {
var registry string
parts := strings.Split(image_url, "/")
switch {
case len(parts) == 2:
registry = fn.DefaultRegistry
case len(parts) >= 3:
registry = parts[0]
default:
return "", fmt.Errorf("failed to parse image name: %q", image_url)
func GetRegistry(img string) (string, error) {
ref, err := name.ParseReference(img, name.WeakValidation)
if err != nil {
return "", err
}
registry := ref.Context().RegistryStr()
return registry, nil
}

View File

@ -45,18 +45,13 @@ func TestGetRegistry(t *testing.T) {
{
name: "default registry",
arg: "docker.io/mysamplefunc:latest",
want: "docker.io",
want: "index.docker.io",
},
{
name: "long-form nested url",
arg: "myregistry.io/myorg/myuser/myfunctions/mysamplefunc:latest",
want: "myregistry.io",
},
{
name: "invalid url",
arg: "myregistry.io-mysamplefunc:latest",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

1
pipelines/init.go Normal file
View File

@ -0,0 +1 @@
package pipelines

View File

@ -1,9 +0,0 @@
package pipelines
type ContainerRegistryCredentialsCallback func() (ContainerRegistryCredentials, error)
type ContainerRegistryCredentials struct {
Username string
Password string
Server string
}

View File

@ -5,6 +5,9 @@ import (
"fmt"
"sync"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/tektoncd/cli/pkg/pipelinerun"
"github.com/tektoncd/cli/pkg/taskrun"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
@ -14,9 +17,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/docker"
"knative.dev/kn-plugin-func/k8s"
"knative.dev/kn-plugin-func/knative"
"knative.dev/kn-plugin-func/pipelines"
"knative.dev/pkg/apis"
)
@ -25,10 +28,10 @@ type Opt func(*PipelinesProvider) error
type PipelinesProvider struct {
// namespace with which to override that set on the default configuration (such as the ~/.kube/config).
// If left blank, pipeline creation/run will commence to the configured namespace.
namespace string
Verbose bool
progressListener fn.ProgressListener
containerRegistryCredentialsCallback pipelines.ContainerRegistryCredentialsCallback
namespace string
Verbose bool
progressListener fn.ProgressListener
credentialsProvider docker.CredentialsProvider
}
func WithNamespace(namespace string) Opt {
@ -49,9 +52,9 @@ func WithProgressListener(pl fn.ProgressListener) Opt {
}
}
func WithPromptForContainerRegistryCredentials(cbk pipelines.ContainerRegistryCredentialsCallback) Opt {
func WithCredentialsProvider(credentialsProvider docker.CredentialsProvider) Opt {
return func(pp *PipelinesProvider) error {
pp.containerRegistryCredentialsCallback = cbk
pp.credentialsProvider = credentialsProvider
return nil
}
}
@ -97,16 +100,25 @@ func (pp *PipelinesProvider) Run(ctx context.Context, f fn.Function) error {
}
}
registry, err := docker.GetRegistry(f.Image)
if err != nil {
return err
}
_, err = k8s.GetSecret(ctx, getPipelineSecretName(f), pp.namespace)
if errors.IsNotFound(err) {
pp.progressListener.Stopping()
creds, err := pp.containerRegistryCredentialsCallback()
creds, err := pp.credentialsProvider(ctx, registry)
if err != nil {
return err
}
pp.progressListener.Increment("Creating Pipeline resources")
err = k8s.CreateDockerRegistrySecret(ctx, getPipelineSecretName(f), pp.namespace, creds.Username, creds.Password, creds.Server)
if registry == name.DefaultRegistry {
registry = authn.DefaultAuthKey
}
err = k8s.CreateDockerRegistrySecret(ctx, getPipelineSecretName(f), pp.namespace, creds.Username, creds.Password, registry)
if err != nil {
return err
}