mirror of https://github.com/knative/func.git
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:
parent
cb719ff564
commit
15d617f99d
|
@ -20,7 +20,6 @@ import (
|
||||||
"knative.dev/kn-plugin-func/docker"
|
"knative.dev/kn-plugin-func/docker"
|
||||||
"knative.dev/kn-plugin-func/docker/creds"
|
"knative.dev/kn-plugin-func/docker/creds"
|
||||||
"knative.dev/kn-plugin-func/knative"
|
"knative.dev/kn-plugin-func/knative"
|
||||||
"knative.dev/kn-plugin-func/pipelines"
|
|
||||||
"knative.dev/kn-plugin-func/pipelines/tekton"
|
"knative.dev/kn-plugin-func/pipelines/tekton"
|
||||||
"knative.dev/kn-plugin-func/progress"
|
"knative.dev/kn-plugin-func/progress"
|
||||||
)
|
)
|
||||||
|
@ -37,11 +36,13 @@ func newDeployClient(cfg deployConfig) (*fn.Client, error) {
|
||||||
pusher *docker.Pusher
|
pusher *docker.Pusher
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
credentialsProvider := creds.NewCredentialsProvider(
|
||||||
|
creds.WithPromptForCredentials(newPromptForCredentials()),
|
||||||
|
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
|
||||||
|
creds.WithTransport(cfg.Transport))
|
||||||
|
|
||||||
if cfg.Push {
|
if cfg.Push {
|
||||||
credentialsProvider := creds.NewCredentialsProvider(
|
|
||||||
creds.WithPromptForCredentials(newPromptForCredentials()),
|
|
||||||
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
|
|
||||||
creds.WithTransport(cfg.Transport))
|
|
||||||
pusher, err = docker.NewPusher(
|
pusher, err = docker.NewPusher(
|
||||||
docker.WithCredentialsProvider(credentialsProvider),
|
docker.WithCredentialsProvider(credentialsProvider),
|
||||||
docker.WithProgressListener(listener),
|
docker.WithProgressListener(listener),
|
||||||
|
@ -60,7 +61,7 @@ func newDeployClient(cfg deployConfig) (*fn.Client, error) {
|
||||||
pipelinesProvider, err := tekton.NewPipelinesProvider(
|
pipelinesProvider, err := tekton.NewPipelinesProvider(
|
||||||
tekton.WithNamespace(cfg.Namespace),
|
tekton.WithNamespace(cfg.Namespace),
|
||||||
tekton.WithProgressListener(listener),
|
tekton.WithProgressListener(listener),
|
||||||
tekton.WithPromptForContainerRegistryCredentials(newPromptForPipelineRegistryCredentials()))
|
tekton.WithCredentialsProvider(credentialsProvider))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
func newPromptForCredentialStore() creds.ChooseCredentialHelperCallback {
|
||||||
return func(availableHelpers []string) (string, error) {
|
return func(availableHelpers []string) (string, error) {
|
||||||
if len(availableHelpers) < 1 {
|
if len(availableHelpers) < 1 {
|
||||||
|
|
|
@ -12,13 +12,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/docker/docker/client"
|
|
||||||
|
|
||||||
fn "knative.dev/kn-plugin-func"
|
fn "knative.dev/kn-plugin-func"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
@ -111,18 +109,12 @@ func NewPusher(opts ...Opt) (*Pusher, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRegistry(image_url string) (string, error) {
|
func GetRegistry(img string) (string, error) {
|
||||||
var registry string
|
ref, err := name.ParseReference(img, name.WeakValidation)
|
||||||
parts := strings.Split(image_url, "/")
|
if err != nil {
|
||||||
switch {
|
return "", err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
registry := ref.Context().RegistryStr()
|
||||||
return registry, nil
|
return registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,18 +45,13 @@ func TestGetRegistry(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "default registry",
|
name: "default registry",
|
||||||
arg: "docker.io/mysamplefunc:latest",
|
arg: "docker.io/mysamplefunc:latest",
|
||||||
want: "docker.io",
|
want: "index.docker.io",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "long-form nested url",
|
name: "long-form nested url",
|
||||||
arg: "myregistry.io/myorg/myuser/myfunctions/mysamplefunc:latest",
|
arg: "myregistry.io/myorg/myuser/myfunctions/mysamplefunc:latest",
|
||||||
want: "myregistry.io",
|
want: "myregistry.io",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "invalid url",
|
|
||||||
arg: "myregistry.io-mysamplefunc:latest",
|
|
||||||
want: "",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
package pipelines
|
|
@ -1,9 +0,0 @@
|
||||||
package pipelines
|
|
||||||
|
|
||||||
type ContainerRegistryCredentialsCallback func() (ContainerRegistryCredentials, error)
|
|
||||||
|
|
||||||
type ContainerRegistryCredentials struct {
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
Server string
|
|
||||||
}
|
|
|
@ -5,6 +5,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"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/pipelinerun"
|
||||||
"github.com/tektoncd/cli/pkg/taskrun"
|
"github.com/tektoncd/cli/pkg/taskrun"
|
||||||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
|
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
|
||||||
|
@ -14,9 +17,9 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
||||||
fn "knative.dev/kn-plugin-func"
|
fn "knative.dev/kn-plugin-func"
|
||||||
|
"knative.dev/kn-plugin-func/docker"
|
||||||
"knative.dev/kn-plugin-func/k8s"
|
"knative.dev/kn-plugin-func/k8s"
|
||||||
"knative.dev/kn-plugin-func/knative"
|
"knative.dev/kn-plugin-func/knative"
|
||||||
"knative.dev/kn-plugin-func/pipelines"
|
|
||||||
"knative.dev/pkg/apis"
|
"knative.dev/pkg/apis"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,10 +28,10 @@ type Opt func(*PipelinesProvider) error
|
||||||
type PipelinesProvider struct {
|
type PipelinesProvider struct {
|
||||||
// namespace with which to override that set on the default configuration (such as the ~/.kube/config).
|
// 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.
|
// If left blank, pipeline creation/run will commence to the configured namespace.
|
||||||
namespace string
|
namespace string
|
||||||
Verbose bool
|
Verbose bool
|
||||||
progressListener fn.ProgressListener
|
progressListener fn.ProgressListener
|
||||||
containerRegistryCredentialsCallback pipelines.ContainerRegistryCredentialsCallback
|
credentialsProvider docker.CredentialsProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithNamespace(namespace string) Opt {
|
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 {
|
return func(pp *PipelinesProvider) error {
|
||||||
pp.containerRegistryCredentialsCallback = cbk
|
pp.credentialsProvider = credentialsProvider
|
||||||
return nil
|
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)
|
_, err = k8s.GetSecret(ctx, getPipelineSecretName(f), pp.namespace)
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
pp.progressListener.Stopping()
|
pp.progressListener.Stopping()
|
||||||
creds, err := pp.containerRegistryCredentialsCallback()
|
creds, err := pp.credentialsProvider(ctx, registry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pp.progressListener.Increment("Creating Pipeline resources")
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue