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..ac26bde7e4 100644 --- a/knative/client.go +++ b/knative/client.go @@ -1,43 +1,68 @@ package knative import ( - "bytes" "fmt" - "io" - "os" "time" "k8s.io/client-go/tools/clientcmd" - "knative.dev/client/pkg/kn/commands" + clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1" 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 NewClient(namespace string, verbose bool) (clientservingv1.KnServingClient, io.Writer, error) { +func NewServingClient(namespace string) (clientservingv1.KnServingClient, error) { - p := commands.KnParams{} - p.Initialize() + restConfig, err := getClientConfig().ClientConfig() + if err != nil { + return nil, fmt.Errorf("failed to create new serving client: %v", err) + } - // 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{} + servingClient, err := servingv1.NewForConfig(restConfig) + if err != nil { + return nil, fmt.Errorf("failed to create new serving client: %v", err) } - if namespace == "" { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) - namespace, _, _ = clientConfig.Namespace() + client := clientservingv1.NewKnServingClient(servingClient, namespace) + + return client, nil +} + +func NewEventingClient(namespace string) (clienteventingv1beta1.KnEventingClient, error) { + + restConfig, err := getClientConfig().ClientConfig() + if err != nil { + return nil, fmt.Errorf("failed to create new serving client: %v", err) } - client, err := p.NewServingClient(namespace) + eventingClient, err := eventingv1beta1.NewForConfig(restConfig) if err != nil { - return nil, p.Output, fmt.Errorf("failed to create new serving client: %v", err) + return nil, fmt.Errorf("failed to create new eventing client: %v", err) } - return client, p.Output, nil + client := clienteventingv1beta1.NewKnEventingClient(eventingClient, namespace) + + return client, nil +} + +func GetNamespace(defaultNamespace string) (namespace string, err error) { + namespace = defaultNamespace + + if defaultNamespace == "" { + namespace, _, err = getClientConfig().Namespace() + if err != nil { + return + } + } + return +} + +func getClientConfig() clientcmd.ClientConfig { + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + &clientcmd.ConfigOverrides{}) } diff --git a/knative/deployer.go b/knative/deployer.go index ebe3250bf9..19ca154913 100644 --- a/knative/deployer.go +++ b/knative/deployer.go @@ -1,7 +1,6 @@ package knative import ( - "bytes" "fmt" "strings" "time" @@ -28,12 +27,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,70 +39,50 @@ 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, err := NewServingClient(d.Namespace) 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()) - } 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(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()) - } 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(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()) - } 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(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()) - } 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 78fd45aed3..045c7e8ddf 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) + if err != nil { + return + } + + eventingClient, err := NewEventingClient(d.namespace) + 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..73cc21c571 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) + 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..02ea7d0298 100644 --- a/knative/remover.go +++ b/knative/remover.go @@ -1,18 +1,21 @@ 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,42 +25,19 @@ 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, err := NewServingClient(remover.Namespace) 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) - } 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