From 62c488923ae8ce21b3d6b49d49e80cc27282763d Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Thu, 8 Oct 2020 13:51:47 +0200 Subject: [PATCH 1/2] use Knative Client libs Signed-off-by: Zbynek Roubalik --- cmd/delete.go | 11 +++++---- cmd/deploy.go | 1 - knative/client.go | 53 +++++++++++++++++++++++++++++++++----------- knative/deployer.go | 17 +++++++------- knative/describer.go | 50 ++++++++++++++++------------------------- knative/lister.go | 39 +++++++++++++------------------- knative/remover.go | 45 +++++++++++++------------------------ 7 files changed, 104 insertions(+), 112 deletions(-) diff --git a/cmd/delete.go b/cmd/delete.go index d566512b28..2ae025d90a 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -42,10 +42,6 @@ overwrite the value in faas.yaml. func runDelete(cmd *cobra.Command, args []string) (err error) { config := newDeleteConfig(args).Prompt() - remover := knative.NewRemover(config.Namespace) - remover.Verbose = config.Verbose - remover.Namespace = config.Namespace - function, err := faas.NewFunction(config.Path) if err != nil { return @@ -56,6 +52,13 @@ func runDelete(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("the given path '%v' does not contain an initialized Function.", config.Path) } + remover, err := knative.NewRemover(config.Namespace) + if err != nil { + return + } + + remover.Verbose = config.Verbose + client := faas.New( faas.WithVerbose(config.Verbose), faas.WithRemover(remover)) diff --git a/cmd/deploy.go b/cmd/deploy.go index 68389c7f2e..520958f8d0 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -103,7 +103,6 @@ func runDeploy(cmd *cobra.Command, _ []string) (err error) { listener := progress.New() deployer.Verbose = config.Verbose - deployer.Namespace = function.Namespace client := faas.New( faas.WithVerbose(config.Verbose), diff --git a/knative/client.go b/knative/client.go index dca09c4eac..15d8b9fb97 100644 --- a/knative/client.go +++ b/knative/client.go @@ -8,6 +8,7 @@ import ( "time" "k8s.io/client-go/tools/clientcmd" + clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" "knative.dev/client/pkg/kn/commands" clientservingv1 "knative.dev/client/pkg/serving/v1" ) @@ -16,8 +17,45 @@ const ( DefaultWaitingTimeout = 60 * time.Second ) -func NewClient(namespace string, verbose bool) (clientservingv1.KnServingClient, io.Writer, error) { +func NewServingClient(namespace string, verbose bool) (clientservingv1.KnServingClient, io.Writer, error) { + knParams := initKnParams(verbose) + + client, err := knParams.NewServingClient(namespace) + if err != nil { + return nil, knParams.Output, fmt.Errorf("failed to create new serving client: %v", err) + } + + return client, knParams.Output, nil +} + +func NewEventingClient(namespace string, verbose bool) (clienteventingv1beta1.KnEventingClient, io.Writer, error) { + + knParams := initKnParams(verbose) + + client, err := knParams.NewEventingClient(namespace) + if err != nil { + return nil, knParams.Output, fmt.Errorf("failed to create new eventing client: %v", err) + } + + return client, knParams.Output, nil +} + +func GetNamespace(defaultNamespace string) (namespace string, err error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) + namespace = defaultNamespace + + if defaultNamespace == "" { + namespace, _, err = clientConfig.Namespace() + if err != nil { + return + } + } + return +} + +func initKnParams(verbose bool) commands.KnParams { p := commands.KnParams{} p.Initialize() @@ -28,16 +66,5 @@ func NewClient(namespace string, verbose bool) (clientservingv1.KnServingClient, p.Output = &bytes.Buffer{} } - if namespace == "" { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) - namespace, _, _ = clientConfig.Namespace() - } - - client, err := p.NewServingClient(namespace) - if err != nil { - return nil, p.Output, fmt.Errorf("failed to create new serving client: %v", err) - } - - return client, p.Output, nil + return p } diff --git a/knative/deployer.go b/knative/deployer.go index ebe3250bf9..5b7882e2dd 100644 --- a/knative/deployer.go +++ b/knative/deployer.go @@ -28,12 +28,11 @@ type Deployer struct { func NewDeployer(namespaceOverride string) (deployer *Deployer, err error) { deployer = &Deployer{} - _, namespace, err := newClientConfig(namespaceOverride) + namespace, err := GetNamespace(namespaceOverride) if err != nil { return } deployer.Namespace = namespace - // deployer.client, err = servingv1client.NewForConfig(config) return } @@ -41,22 +40,22 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { // k8s does not support service names with dots. so encode it such that // www.my-domain,com -> www-my--domain-com - encodedName, err := k8s.ToK8sAllowedName(f.Name) + serviceName, err := k8s.ToK8sAllowedName(f.Name) if err != nil { return } - client, output, err := NewClient(d.Namespace, d.Verbose) + client, output, err := NewServingClient(d.Namespace, d.Verbose) if err != nil { return } - _, err = client.GetService(encodedName) + _, err = client.GetService(serviceName) if err != nil { if errors.IsNotFound(err) { // Let's create a new Service - err := client.CreateService(generateNewService(encodedName, f.Image)) + err := client.CreateService(generateNewService(serviceName, f.Image)) if err != nil { if !d.Verbose { err = fmt.Errorf("failed to deploy the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) @@ -66,7 +65,7 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { return err } - err, _ = client.WaitForService(encodedName, DefaultWaitingTimeout, wait.NoopMessageCallback()) + err, _ = client.WaitForService(serviceName, DefaultWaitingTimeout, wait.NoopMessageCallback()) if err != nil { if !d.Verbose { err = fmt.Errorf("deployer failed to wait for the service to become ready: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) @@ -76,7 +75,7 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { return err } - route, err := client.GetRoute(encodedName) + route, err := client.GetRoute(serviceName) if err != nil { if !d.Verbose { err = fmt.Errorf("deployer failed to get the route: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) @@ -98,7 +97,7 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { } } else { // Update the existing Service - err = client.UpdateServiceWithRetry(encodedName, updateEnvVars(f.EnvVars), 3) + err = client.UpdateServiceWithRetry(serviceName, updateEnvVars(f.EnvVars), 3) if err != nil { if !d.Verbose { err = fmt.Errorf("deployer failed to update the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) diff --git a/knative/describer.go b/knative/describer.go index 78fd45aed3..a798f569a2 100644 --- a/knative/describer.go +++ b/knative/describer.go @@ -1,44 +1,27 @@ package knative import ( - "fmt" "k8s.io/apimachinery/pkg/api/errors" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/rest" + v1 "knative.dev/client/pkg/serving/v1" "knative.dev/eventing/pkg/apis/eventing/v1beta1" - eventingv1client "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" - servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1" "github.com/boson-project/faas" "github.com/boson-project/faas/k8s" ) type Describer struct { - Verbose bool - namespace string - servingClient *servingv1client.ServingV1alpha1Client - eventingClient *eventingv1client.EventingV1beta1Client - config *rest.Config + Verbose bool + namespace string } func NewDescriber(namespaceOverride string) (describer *Describer, err error) { describer = &Describer{} - config, namespace, err := newClientConfig(namespaceOverride) + namespace, err := GetNamespace(namespaceOverride) if err != nil { return } - describer.namespace = namespace - describer.servingClient, err = servingv1client.NewForConfig(config) - if err != nil { - return - } - describer.eventingClient, err = eventingv1client.NewForConfig(config) - if err != nil { - return - } - describer.config = config + describer.namespace = namespace return } @@ -46,24 +29,29 @@ func NewDescriber(namespaceOverride string) (describer *Describer, err error) { // restricts to label-syntax, which is thus escaped. Therefore as a knative (kube) implementation // detal proper full names have to be escaped on the way in and unescaped on the way out. ex: // www.example-site.com -> www-example--site-com -func (describer *Describer) Describe(name string) (description faas.Description, err error) { - - namespace := describer.namespace - servingClient := describer.servingClient - eventingClient := describer.eventingClient +func (d *Describer) Describe(name string) (description faas.Description, err error) { serviceName, err := k8s.ToK8sAllowedName(name) if err != nil { return } - service, err := servingClient.Services(namespace).Get(serviceName, metav1.GetOptions{}) + servingClient, _, err := NewServingClient(d.namespace, d.Verbose) + if err != nil { + return + } + + eventingClient, _, err := NewEventingClient(d.namespace, d.Verbose) + if err != nil { + return + } + + service, err := servingClient.GetService(serviceName) if err != nil { return } - serviceLabel := fmt.Sprintf("serving.knative.dev/service=%s", serviceName) - routes, err := servingClient.Routes(namespace).List(metav1.ListOptions{LabelSelector: serviceLabel}) + routes, err := servingClient.ListRoutes(v1.WithService(serviceName)) if err != nil { return } @@ -73,7 +61,7 @@ func (describer *Describer) Describe(name string) (description faas.Description, routeURLs = append(routeURLs, route.Status.URL.String()) } - triggers, err := eventingClient.Triggers(namespace).List(metav1.ListOptions{}) + triggers, err := eventingClient.ListTriggers() // IsNotFound -- Eventing is probably not installed on the cluster if err != nil && !errors.IsNotFound(err) { return diff --git a/knative/lister.go b/knative/lister.go index 28df3db54d..8e3e1e3869 100644 --- a/knative/lister.go +++ b/knative/lister.go @@ -1,40 +1,45 @@ package knative import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - restclient "k8s.io/client-go/rest" - clientcmd "k8s.io/client-go/tools/clientcmd" - servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" + clientservingv1 "knative.dev/client/pkg/serving/v1" "github.com/boson-project/faas/k8s" ) -const labelSelector = "bosonFunction" +const ( + labelKey = "bosonFunction" + labelValue = "true" +) type Lister struct { Verbose bool namespace string - client *servingv1client.ServingV1Client } func NewLister(namespaceOverride string) (l *Lister, err error) { l = &Lister{} - config, namespace, err := newClientConfig(namespaceOverride) + namespace, err := GetNamespace(namespaceOverride) if err != nil { return } l.namespace = namespace - l.client, err = servingv1client.NewForConfig(config) + return } func (l *Lister) List() (names []string, err error) { - opts := metav1.ListOptions{LabelSelector: labelSelector} - lst, err := l.client.Services(l.namespace).List(opts) + + client, _, err := NewServingClient(l.namespace, l.Verbose) + if err != nil { + return + } + + lst, err := client.ListServices(clientservingv1.WithLabel(labelKey, labelValue)) if err != nil { return } + for _, service := range lst.Items { // Convert the "subdomain-encoded" (i.e. kube-service-friendly) name // back out to a fully qualified service name. @@ -46,17 +51,3 @@ func (l *Lister) List() (names []string, err error) { } return } - -func newClientConfig(defaultNamespace string) (c *restclient.Config, namespace string, err error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) - namespace = defaultNamespace - if defaultNamespace == "" { - namespace, _, err = clientConfig.Namespace() - if err != nil { - return - } - } - c, err = clientConfig.ClientConfig() - return -} diff --git a/knative/remover.go b/knative/remover.go index 5e4094c321..026a832ffc 100644 --- a/knative/remover.go +++ b/knative/remover.go @@ -3,16 +3,20 @@ package knative import ( "bytes" "fmt" - "github.com/boson-project/faas/k8s" - "io" - "k8s.io/client-go/tools/clientcmd" - commands "knative.dev/client/pkg/kn/commands" - "os" "time" + + "github.com/boson-project/faas/k8s" ) -func NewRemover(namespaceOverride string) *Remover { - return &Remover{Namespace: namespaceOverride} +func NewRemover(namespaceOverride string) (remover *Remover, err error) { + remover = &Remover{} + namespace, err := GetNamespace(namespaceOverride) + if err != nil { + return + } + remover.Namespace = namespace + + return } type Remover struct { @@ -22,36 +26,17 @@ type Remover struct { func (remover *Remover) Remove(name string) (err error) { - project, err := k8s.ToK8sAllowedName(name) + serviceName, err := k8s.ToK8sAllowedName(name) if err != nil { return } - var output io.Writer - if remover.Verbose { - output = os.Stdout - } else { - output = &bytes.Buffer{} - } - - p := commands.KnParams{} - p.Initialize() - p.Output = output - + client, output, err := NewServingClient(remover.Namespace, remover.Verbose) if err != nil { - return err - } - if remover.Namespace == "" { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) - remover.Namespace, _, _ = clientConfig.Namespace() - } - client, err := p.NewServingClient(remover.Namespace) - if err != nil { - return fmt.Errorf("remover failed to create new serving client: %v", err) + return } - err = client.DeleteService(project, time.Second*30) + err = client.DeleteService(serviceName, time.Second*60) if err != nil { if remover.Verbose { err = fmt.Errorf("remover failed to delete the service: %v", err) From 886cb5a74e69f0a17790b59727f304492e975967 Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Tue, 13 Oct 2020 20:41:42 +0200 Subject: [PATCH 2/2] get rid of knative.dev/client/pkg/kn/commands Signed-off-by: Zbynek Roubalik --- knative/client.go | 56 +++++++++++++++++++++----------------------- knative/deployer.go | 33 +++++--------------------- knative/describer.go | 4 ++-- knative/lister.go | 2 +- knative/remover.go | 9 ++----- 5 files changed, 38 insertions(+), 66 deletions(-) diff --git a/knative/client.go b/knative/client.go index 15d8b9fb97..ac26bde7e4 100644 --- a/knative/client.go +++ b/knative/client.go @@ -1,53 +1,59 @@ package knative import ( - "bytes" "fmt" - "io" - "os" "time" "k8s.io/client-go/tools/clientcmd" clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" - "knative.dev/client/pkg/kn/commands" clientservingv1 "knative.dev/client/pkg/serving/v1" + eventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1" + servingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" ) const ( DefaultWaitingTimeout = 60 * time.Second ) -func NewServingClient(namespace string, verbose bool) (clientservingv1.KnServingClient, io.Writer, error) { +func NewServingClient(namespace string) (clientservingv1.KnServingClient, error) { - knParams := initKnParams(verbose) + restConfig, err := getClientConfig().ClientConfig() + if err != nil { + return nil, fmt.Errorf("failed to create new serving client: %v", err) + } - client, err := knParams.NewServingClient(namespace) + servingClient, err := servingv1.NewForConfig(restConfig) if err != nil { - return nil, knParams.Output, fmt.Errorf("failed to create new serving client: %v", err) + return nil, fmt.Errorf("failed to create new serving client: %v", err) } - return client, knParams.Output, nil + client := clientservingv1.NewKnServingClient(servingClient, namespace) + + return client, nil } -func NewEventingClient(namespace string, verbose bool) (clienteventingv1beta1.KnEventingClient, io.Writer, error) { +func NewEventingClient(namespace string) (clienteventingv1beta1.KnEventingClient, error) { - knParams := initKnParams(verbose) + restConfig, err := getClientConfig().ClientConfig() + if err != nil { + return nil, fmt.Errorf("failed to create new serving client: %v", err) + } - client, err := knParams.NewEventingClient(namespace) + eventingClient, err := eventingv1beta1.NewForConfig(restConfig) if err != nil { - return nil, knParams.Output, fmt.Errorf("failed to create new eventing client: %v", err) + return nil, fmt.Errorf("failed to create new eventing client: %v", err) } - return client, knParams.Output, nil + client := clienteventingv1beta1.NewKnEventingClient(eventingClient, namespace) + + return client, nil } func GetNamespace(defaultNamespace string) (namespace string, err error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) namespace = defaultNamespace if defaultNamespace == "" { - namespace, _, err = clientConfig.Namespace() + namespace, _, err = getClientConfig().Namespace() if err != nil { return } @@ -55,16 +61,8 @@ func GetNamespace(defaultNamespace string) (namespace string, err error) { return } -func initKnParams(verbose bool) commands.KnParams { - p := commands.KnParams{} - p.Initialize() - - // Capture output in a buffer if verbose is not enabled for output on error. - if verbose { - p.Output = os.Stdout - } else { - p.Output = &bytes.Buffer{} - } - - return p +func getClientConfig() clientcmd.ClientConfig { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + &clientcmd.ConfigOverrides{}) } diff --git a/knative/deployer.go b/knative/deployer.go index 5b7882e2dd..19ca154913 100644 --- a/knative/deployer.go +++ b/knative/deployer.go @@ -1,7 +1,6 @@ package knative import ( - "bytes" "fmt" "strings" "time" @@ -45,7 +44,7 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { return } - client, output, err := NewServingClient(d.Namespace, d.Verbose) + client, err := NewServingClient(d.Namespace) if err != nil { return } @@ -57,53 +56,33 @@ func (d *Deployer) Deploy(f faas.Function) (err error) { // Let's create a new Service err := client.CreateService(generateNewService(serviceName, f.Image)) if err != nil { - if !d.Verbose { - err = fmt.Errorf("failed to deploy the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } else { - err = fmt.Errorf("failed to deploy the service: %v", err) - } + err = fmt.Errorf("knative deployer failed to deploy the service: %v", err) return err } err, _ = client.WaitForService(serviceName, DefaultWaitingTimeout, wait.NoopMessageCallback()) if err != nil { - if !d.Verbose { - err = fmt.Errorf("deployer failed to wait for the service to become ready: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } else { - err = fmt.Errorf("deployer failed to wait for the service to become ready: %v", err) - } + err = fmt.Errorf("knative deployer failed to wait for the service to become ready: %v", err) return err } route, err := client.GetRoute(serviceName) if err != nil { - if !d.Verbose { - err = fmt.Errorf("deployer failed to get the route: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } else { - err = fmt.Errorf("deployer failed to get the route: %v", err) - } + err = fmt.Errorf("knative deployer failed to get the route: %v", err) return err } fmt.Println("Function deployed on: " + route.Status.URL.String()) } else { - if !d.Verbose { - err = fmt.Errorf("deployer failed to get the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } else { - err = fmt.Errorf("deployer failed to get the service: %v", err) - } + err = fmt.Errorf("knative deployer failed to get the service: %v", err) return err } } else { // Update the existing Service err = client.UpdateServiceWithRetry(serviceName, updateEnvVars(f.EnvVars), 3) if err != nil { - if !d.Verbose { - err = fmt.Errorf("deployer failed to update the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } else { - err = fmt.Errorf("deployer failed to update the service: %v", err) - } + err = fmt.Errorf("knative deployer failed to update the service: %v", err) return err } } diff --git a/knative/describer.go b/knative/describer.go index a798f569a2..045c7e8ddf 100644 --- a/knative/describer.go +++ b/knative/describer.go @@ -36,12 +36,12 @@ func (d *Describer) Describe(name string) (description faas.Description, err err return } - servingClient, _, err := NewServingClient(d.namespace, d.Verbose) + servingClient, err := NewServingClient(d.namespace) if err != nil { return } - eventingClient, _, err := NewEventingClient(d.namespace, d.Verbose) + eventingClient, err := NewEventingClient(d.namespace) if err != nil { return } diff --git a/knative/lister.go b/knative/lister.go index 8e3e1e3869..73cc21c571 100644 --- a/knative/lister.go +++ b/knative/lister.go @@ -30,7 +30,7 @@ func NewLister(namespaceOverride string) (l *Lister, err error) { func (l *Lister) List() (names []string, err error) { - client, _, err := NewServingClient(l.namespace, l.Verbose) + client, err := NewServingClient(l.namespace) if err != nil { return } diff --git a/knative/remover.go b/knative/remover.go index 026a832ffc..02ea7d0298 100644 --- a/knative/remover.go +++ b/knative/remover.go @@ -1,7 +1,6 @@ package knative import ( - "bytes" "fmt" "time" @@ -31,18 +30,14 @@ func (remover *Remover) Remove(name string) (err error) { return } - client, output, err := NewServingClient(remover.Namespace, remover.Verbose) + client, err := NewServingClient(remover.Namespace) if err != nil { return } err = client.DeleteService(serviceName, time.Second*60) if err != nil { - if remover.Verbose { - err = fmt.Errorf("remover failed to delete the service: %v", err) - } else { - err = fmt.Errorf("remover failed to delete the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String()) - } + err = fmt.Errorf("knative remover failed to delete the service: %v", err) } return