From b129af238ba28242778b07b8447cccaa3f34ce7f Mon Sep 17 00:00:00 2001 From: "roytman@il.ibm.com" Date: Fri, 19 Jul 2019 00:12:29 +0300 Subject: [PATCH] Resolve target namespace from the client kubeconfig context --- CHANGELOG.md | 3 +++ docs/userguide.md | 4 +++- pkg/kubefedctl/federate/federate.go | 11 ++++++++++- pkg/kubefedctl/orphaning/disable.go | 2 +- pkg/kubefedctl/orphaning/enable.go | 2 +- pkg/kubefedctl/orphaning/orphaning.go | 9 +++++++-- pkg/kubefedctl/orphaning/status.go | 2 +- pkg/kubefedctl/util/util.go | 20 +++++++++++++++++++- 8 files changed, 45 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c68f70c9..1aed8bd339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ leaving managed resources, when their relevant federated resource is deleted. In addition, the command allows to check current `status` of the orphaning deletion mode. +- [#1044](https://github.com/kubernetes-sigs/kubefed/issues/1044) If a target namespace + of `federate` and all `orphaning-deletion` commands is not specified, use the namespace from + the client kubeconfig context. # v0.1.0-rc3 - [#520](https://github.com/kubernetes-sigs/kubefed/issues/520) Adds support diff --git a/docs/userguide.md b/docs/userguide.md index c7df0fb737..43744c177f 100644 --- a/docs/userguide.md +++ b/docs/userguide.md @@ -290,7 +290,7 @@ kubefedctl federate [flags] ``` If the flag `--namespace` is additionally not specified, the `` will be -searched for in the namespace `default`. Please take note that `--namespace` flag is of no +searched for in the namespace according to the client kubeconfig context. Please take note that `--namespace` flag is of no meaning when federating a `namespace` itself and is discarded even if specified. Please check the next section for more details about [federating a namespace](#federate-a-namespace). @@ -504,6 +504,8 @@ the `orphaning-deletion` by: kubefedctl orphaning-deletion disable ``` +If the flag `--namespace` is additionally not specified, the federated resource will +be searched for in the namespace according to the client kubeconfig context. If the sync controller for a given federated type is not able to reconcile a federated resource slated for deletion, a federated resource that still has the KubeFed finalizer will linger rather than being garbage collected. If diff --git a/pkg/kubefedctl/federate/federate.go b/pkg/kubefedctl/federate/federate.go index 9e0880cf55..119227490f 100644 --- a/pkg/kubefedctl/federate/federate.go +++ b/pkg/kubefedctl/federate/federate.go @@ -88,7 +88,7 @@ type federateResource struct { } func (j *federateResource) Bind(flags *pflag.FlagSet) { - flags.StringVarP(&j.resourceNamespace, "namespace", "n", "default", "The namespace of the resource to federate.") + flags.StringVarP(&j.resourceNamespace, "namespace", "n", "", "The namespace of the resource to federate.") flags.StringVarP(&j.output, "output", "o", "", "If provided, the resource that would be created in the API by the command is instead output to stdout in the provided format. Valid format is ['yaml'].") flags.BoolVarP(&j.enableType, "enable-type", "e", false, "If true, attempt to enable federation of the API type of the resource before creating the federated resource.") flags.BoolVarP(&j.federateContents, "contents", "c", false, "Applicable only to namespaces. If provided, the command will federate all resources within the namespace after federating the namespace.") @@ -161,6 +161,15 @@ func NewCmdFederateResource(cmdOut io.Writer, config util.FedConfig) *cobra.Comm // Run is the implementation of the `federate resource` command. func (j *federateResource) Run(cmdOut io.Writer, config util.FedConfig) error { + + if len(j.resourceNamespace) == 0 { + var err error + j.resourceNamespace, err = util.GetNamespace(j.HostClusterContext, j.Kubeconfig, config) + if err != nil { + return err + } + } + hostConfig, err := config.HostConfig(j.HostClusterContext, j.Kubeconfig) if err != nil { return errors.Wrap(err, "Failed to get host cluster config") diff --git a/pkg/kubefedctl/orphaning/disable.go b/pkg/kubefedctl/orphaning/disable.go index 284835c84f..7b14388690 100644 --- a/pkg/kubefedctl/orphaning/disable.go +++ b/pkg/kubefedctl/orphaning/disable.go @@ -53,7 +53,7 @@ func newCmdDisableOrphaning(cmdOut io.Writer, config util.FedConfig) *cobra.Comm Long: orphaning_disable_long, Example: orphaning_disable_example, Run: func(cmd *cobra.Command, args []string) { - err := opts.Complete(args) + err := opts.Complete(args, config) if err != nil { klog.Fatalf("Error: %v", err) } diff --git a/pkg/kubefedctl/orphaning/enable.go b/pkg/kubefedctl/orphaning/enable.go index 37d503b7fc..1f8a905fbc 100644 --- a/pkg/kubefedctl/orphaning/enable.go +++ b/pkg/kubefedctl/orphaning/enable.go @@ -53,7 +53,7 @@ func newCmdEnableOrphaning(cmdOut io.Writer, config util.FedConfig) *cobra.Comma Long: orphaning_enable_long, Example: orphan_enable_example, Run: func(cmd *cobra.Command, args []string) { - err := opts.Complete(args) + err := opts.Complete(args, config) if err != nil { klog.Fatalf("Error: %v", err) } diff --git a/pkg/kubefedctl/orphaning/orphaning.go b/pkg/kubefedctl/orphaning/orphaning.go index 10d64e3b61..b29a51658a 100644 --- a/pkg/kubefedctl/orphaning/orphaning.go +++ b/pkg/kubefedctl/orphaning/orphaning.go @@ -45,7 +45,7 @@ type orphanResource struct { // Bind adds the join specific arguments to the flagset passed in as an argument. func (o *orphanResource) Bind(flags *pflag.FlagSet) error { - flags.StringVarP(&o.resourceNamespace, "namespace", "n", "default", "If present, the namespace scope for this CLI request") + flags.StringVarP(&o.resourceNamespace, "namespace", "n", "", "If present, the namespace scope for this CLI request") err := flags.MarkHidden("kubefed-namespace") if err != nil { return err @@ -78,7 +78,7 @@ func NewCmdOrphaning(cmdOut io.Writer, config util.FedConfig) *cobra.Command { } // Complete ensures that options are valid and marshals them if necessary. -func (o *orphanResource) Complete(args []string) error { +func (o *orphanResource) Complete(args []string, config util.FedConfig) error { if len(args) == 0 { return errors.New("resource type is required") } @@ -90,6 +90,11 @@ func (o *orphanResource) Complete(args []string) error { } o.resourceName = args[1] + if len(o.resourceNamespace) == 0 { + var err error + o.resourceNamespace, err = util.GetNamespace(o.HostClusterContext, o.Kubeconfig, config) + return err + } return nil } diff --git a/pkg/kubefedctl/orphaning/status.go b/pkg/kubefedctl/orphaning/status.go index e624046d3b..740aefdf16 100644 --- a/pkg/kubefedctl/orphaning/status.go +++ b/pkg/kubefedctl/orphaning/status.go @@ -54,7 +54,7 @@ func newCmdStatusOrphaning(cmdOut io.Writer, config util.FedConfig) *cobra.Comma Long: orphaning_status_long, Example: orphaning_status_example, Run: func(cmd *cobra.Command, args []string) { - err := opts.Complete(args) + err := opts.Complete(args, config) if err != nil { klog.Fatalf("Error: %v", err) } diff --git a/pkg/kubefedctl/util/util.go b/pkg/kubefedctl/util/util.go index 20b329c34c..aa3ca0b433 100644 --- a/pkg/kubefedctl/util/util.go +++ b/pkg/kubefedctl/util/util.go @@ -18,12 +18,15 @@ package util import ( "fmt" + "strings" + + "github.com/pkg/errors" kubeclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/kubefed/pkg/kubefedctl/options" - "strings" ) const FederatedKindPrefix = "Federated" @@ -118,6 +121,21 @@ func HealthCheckRoleName(serviceAccountName, namespace string) string { return fmt.Sprintf("kubefed-controller-manager:%s:healthcheck-%s", namespace, serviceAccountName) } +// IsFederatedAPIResource checks if a resource with the given Kind and group is a Federated one func IsFederatedAPIResource(kind, group string) bool { return strings.HasPrefix(kind, FederatedKindPrefix) && group == options.DefaultFederatedGroup } + +// GetNamespace returns namespace of the current context +func GetNamespace(hostClusterContext string, kubeconfig string, config FedConfig) (string, error) { + ns, _, err := config.GetClientConfig(hostClusterContext, kubeconfig).Namespace() + if err != nil { + return "", errors.Wrapf(err, "Failed to get ClientConfig for host cluster context %q and kubeconfig %q", + hostClusterContext, kubeconfig) + } + + if len(ns) == 0 { + ns = "default" + } + return ns, nil +}