Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2715 from roffe/context-option
Browse files Browse the repository at this point in the history
Add context option to fluxctl
  • Loading branch information
2opremio authored Jan 9, 2020
2 parents d443cfe + f90cd3f commit 997d1da
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 37 deletions.
21 changes: 19 additions & 2 deletions cmd/fluxctl/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,18 @@ func getUserGitConfigValue(arg string) string {
return strings.Trim(res, "\x00")
}

var getKubeConfigContextNamespace = func(defaultNamespace string) string {
// Wrapper for getKubeConfigContextNamespace where the return order is
// 1. Given namespace
// 2. Namespace from current kubeconfig context if 1. is empty
// 3. Default namespace specified if 1 is empty and 2 fails
func getKubeConfigContextNamespaceOrDefault(namespace string, defaultNamespace string, kubeConfigContext string) string {
if namespace == "" {
return getKubeConfigContextNamespace(defaultNamespace, kubeConfigContext)
}
return namespace
}

var getKubeConfigContextNamespace = func(defaultNamespace string, kubeConfigContext string) string {
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{},
Expand All @@ -61,7 +72,13 @@ var getKubeConfigContextNamespace = func(defaultNamespace string) string {
return defaultNamespace
}

cc := config.CurrentContext
var cc string
if kubeConfigContext == "" {
cc = config.CurrentContext
} else {
cc = kubeConfigContext
}

if c, ok := config.Contexts[cc]; ok && c.Namespace != "" {
return c.Namespace
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/fluxctl/automate_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (opts *workloadAutomateOpts) Command() *cobra.Command {
}
AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Workload namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Workload namespace")
cmd.Flags().StringVarP(&opts.workload, "workload", "w", "", "Workload to automate")

// Deprecated
Expand All @@ -50,10 +50,11 @@ func (opts *workloadAutomateOpts) RunE(cmd *cobra.Command, args []string) error
case opts.controller != "":
opts.workload = opts.controller
}
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
policyOpts := &workloadPolicyOpts{
rootOpts: opts.rootOpts,
outputOpts: opts.outputOpts,
namespace: opts.namespace,
namespace: ns,
workload: opts.workload,
cause: opts.cause,
automate: true,
Expand Down
5 changes: 3 additions & 2 deletions cmd/fluxctl/deautomate_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (opts *workloadDeautomateOpts) Command() *cobra.Command {
}
AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Workload namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Workload namespace")
cmd.Flags().StringVarP(&opts.workload, "workload", "w", "", "Workload to deautomate")

// Deprecated
Expand All @@ -50,10 +50,11 @@ func (opts *workloadDeautomateOpts) RunE(cmd *cobra.Command, args []string) erro
case opts.controller != "":
opts.workload = opts.controller
}
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
policyOpts := &workloadPolicyOpts{
rootOpts: opts.rootOpts,
outputOpts: opts.outputOpts,
namespace: opts.namespace,
namespace: ns,
workload: opts.workload,
cause: opts.cause,
deautomate: true,
Expand Down
3 changes: 2 additions & 1 deletion cmd/fluxctl/install_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fluxctl install --git-url '[email protected]:<your username>/flux-get-started' | ku
"Tell flux it has readonly access to the repo")
cmd.Flags().BoolVar(&opts.ManifestGeneration, "manifest-generation", false,
"Whether to enable manifest generation")
cmd.Flags().StringVar(&opts.Namespace, "namespace", getKubeConfigContextNamespace("default"),
cmd.Flags().StringVar(&opts.Namespace, "namespace", "",
"Cluster namespace where to install flux")
cmd.Flags().StringVarP(&opts.outputDir, "output-dir", "o", "", "a directory in which to write individual manifests, rather than printing to stdout")

Expand All @@ -64,6 +64,7 @@ func (opts *installOpts) RunE(cmd *cobra.Command, args []string) error {
if opts.GitEmail == "" {
return fmt.Errorf("please supply a valid --git-email argument")
}
opts.TemplateParameters.Namespace = getKubeConfigContextNamespaceOrDefault(opts.Namespace, "default", "")
manifests, err := install.FillInTemplates(opts.TemplateParameters)
if err != nil {
return err
Expand Down
12 changes: 6 additions & 6 deletions cmd/fluxctl/list_images_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/spf13/cobra"

"github.com/fluxcd/flux/pkg/api/v10"
"github.com/fluxcd/flux/pkg/api/v6"
v10 "github.com/fluxcd/flux/pkg/api/v10"
v6 "github.com/fluxcd/flux/pkg/api/v6"
"github.com/fluxcd/flux/pkg/registry"
"github.com/fluxcd/flux/pkg/resource"
"github.com/fluxcd/flux/pkg/update"
Expand All @@ -36,7 +36,7 @@ func (opts *imageListOpts) Command() *cobra.Command {
Example: makeExample("fluxctl list-images --namespace default --workload=deployment/foo"),
RunE: opts.RunE,
}
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace(""), "Namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Namespace")
cmd.Flags().StringVarP(&opts.workload, "workload", "w", "", "Show images for this workload")
cmd.Flags().IntVarP(&opts.limit, "limit", "l", 10, "Number of images to show (0 for all)")

Expand All @@ -51,10 +51,10 @@ func (opts *imageListOpts) RunE(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return errorWantedNoArgs
}

ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
imageOpts := v10.ListImagesOptions{
Spec: update.ResourceSpecAll,
Namespace: opts.namespace,
Namespace: ns,
}
// Backwards compatibility with --controller until we remove it
switch {
Expand All @@ -64,7 +64,7 @@ func (opts *imageListOpts) RunE(cmd *cobra.Command, args []string) error {
opts.workload = opts.controller
}
if len(opts.workload) > 0 {
id, err := resource.ParseIDOptionalNamespace(opts.namespace, opts.workload)
id, err := resource.ParseIDOptionalNamespace(ns, opts.workload)
if err != nil {
return err
}
Expand Down
11 changes: 7 additions & 4 deletions cmd/fluxctl/list_workloads_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/spf13/cobra"

"github.com/fluxcd/flux/pkg/api/v6"
v6 "github.com/fluxcd/flux/pkg/api/v6"
"github.com/fluxcd/flux/pkg/policy"
)

Expand All @@ -30,7 +30,7 @@ func (opts *workloadListOpts) Command() *cobra.Command {
Example: makeExample("fluxctl list-workloads"),
RunE: opts.RunE,
}
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Confine query to namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Confine query to namespace")
cmd.Flags().BoolVarP(&opts.allNamespaces, "all-namespaces", "a", false, "Query across all namespaces")
return cmd
}
Expand All @@ -40,13 +40,16 @@ func (opts *workloadListOpts) RunE(cmd *cobra.Command, args []string) error {
return errorWantedNoArgs
}

var ns string
if opts.allNamespaces {
opts.namespace = ""
ns = ""
} else {
ns = getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
}

ctx := context.Background()

workloads, err := opts.API.ListServices(ctx, opts.namespace)
workloads, err := opts.API.ListServices(ctx, ns)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/fluxctl/lock_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (opts *workloadLockOpts) Command() *cobra.Command {
}
AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Controller namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Controller namespace")
cmd.Flags().StringVarP(&opts.workload, "workload", "w", "", "Workload to lock")

// Deprecated
Expand All @@ -50,10 +50,11 @@ func (opts *workloadLockOpts) RunE(cmd *cobra.Command, args []string) error {
case opts.controller != "":
opts.workload = opts.controller
}
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
policyOpts := &workloadPolicyOpts{
rootOpts: opts.rootOpts,
outputOpts: opts.outputOpts,
namespace: opts.namespace,
namespace: ns,
workload: opts.workload,
cause: opts.cause,
lock: true,
Expand Down
2 changes: 1 addition & 1 deletion cmd/fluxctl/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (t *genericMockRoundTripper) calledURL(method string) (u *url.URL) {
func testArgs(t *testing.T, args []string, shouldErr bool, errMsg string) *genericMockRoundTripper {
svc := newMockService()
releaseClient := newWorkloadRelease(mockServiceOpts(svc))
getKubeConfigContextNamespace = func(s string) string { return s }
getKubeConfigContextNamespace = func(s string, c string) string { return s }

// Run fluxctl release
cmd := releaseClient.Command()
Expand Down
5 changes: 3 additions & 2 deletions cmd/fluxctl/policy_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ containers which aren't explicitly named.
AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
flags := cmd.Flags()
flags.StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Workload namespace")
flags.StringVarP(&opts.namespace, "namespace", "n", "", "Workload namespace")
flags.StringVarP(&opts.workload, "workload", "w", "", "Workload to modify")
flags.StringVar(&opts.tagAll, "tag-all", "", "Tag filter pattern to apply to all containers")
flags.StringSliceVar(&opts.tags, "tag", nil, "Tag filter container/pattern pairs")
Expand Down Expand Up @@ -98,7 +98,8 @@ func (opts *workloadPolicyOpts) RunE(cmd *cobra.Command, args []string) error {
return newUsageError("lock and unlock both specified")
}

resourceID, err := resource.ParseIDOptionalNamespace(opts.namespace, opts.workload)
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
resourceID, err := resource.ParseIDOptionalNamespace(ns, opts.workload)
if err != nil {
return err
}
Expand Down
36 changes: 29 additions & 7 deletions cmd/fluxctl/portforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import (
"fmt"
"strings"

"github.com/justinbarrick/go-k8s-portforward"
portforward "github.com/justinbarrick/go-k8s-portforward"
"github.com/pkg/errors"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)

// Attempt to create PortForwards to fluxes that match the label selectors until a Flux
// is found or an error is returned.
func tryPortforwards(ns string, selectors ...metav1.LabelSelector) (p *portforward.PortForward, err error) {
func tryPortforwards(context string, ns string, selectors ...metav1.LabelSelector) (p *portforward.PortForward, err error) {
message := fmt.Sprintf("No pod found in namespace %q using the following selectors:", ns)

for _, selector := range selectors {
p, err = tryPortforward(ns, selector)
p, err = tryPortforward(context, ns, selector)
if err == nil {
return
}
Expand All @@ -37,10 +38,31 @@ func tryPortforwards(ns string, selectors ...metav1.LabelSelector) (p *portforwa
}

// Attempt to create a portforward in the namespace for the provided LabelSelector
func tryPortforward(ns string, selector metav1.LabelSelector) (*portforward.PortForward, error) {
portforwarder, err := portforward.NewPortForwarder(ns, selector, 3030)
func tryPortforward(kubeConfigContext string, ns string, selector metav1.LabelSelector) (*portforward.PortForward, error) {
portforwarder := &portforward.PortForward{
Namespace: ns,
Labels: selector,
DestinationPort: 3030,
}

var configOverrides clientcmd.ConfigOverrides
if kubeConfigContext != "" {
configOverrides.CurrentContext = kubeConfigContext
}

var err error
portforwarder.Config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&configOverrides,
).ClientConfig()

if err != nil {
return portforwarder, err
return portforwarder, errors.Wrap(err, "Could not load kubernetes configuration file")
}

portforwarder.Clientset, err = kubernetes.NewForConfig(portforwarder.Config)
if err != nil {
return portforwarder, errors.Wrap(err, "Could not create kubernetes client")
}

err = portforwarder.Start()
Expand Down
11 changes: 6 additions & 5 deletions cmd/fluxctl/release_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/spf13/cobra"

"github.com/fluxcd/flux/pkg/api/v11"
"github.com/fluxcd/flux/pkg/api/v6"
v11 "github.com/fluxcd/flux/pkg/api/v11"
v6 "github.com/fluxcd/flux/pkg/api/v6"
"github.com/fluxcd/flux/pkg/cluster"
"github.com/fluxcd/flux/pkg/job"
"github.com/fluxcd/flux/pkg/resource"
Expand Down Expand Up @@ -53,7 +53,7 @@ func (opts *workloadReleaseOpts) Command() *cobra.Command {

AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Workload namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Workload namespace")
// Note: we cannot define a shorthand for --workload since it clashes with the shorthand of --watch
cmd.Flags().StringSliceVarP(&opts.workloads, "workload", "", []string{}, "List of workloads to release <namespace>:<kind>/<name>")
cmd.Flags().BoolVar(&opts.allWorkloads, "all", false, "Release all workloads")
Expand Down Expand Up @@ -98,12 +98,13 @@ func (opts *workloadReleaseOpts) RunE(cmd *cobra.Command, args []string) error {
}

var workloads []update.ResourceSpec
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)

if opts.allWorkloads {
workloads = []update.ResourceSpec{update.ResourceSpecAll}
} else {
for _, workload := range opts.workloads {
id, err := resource.ParseIDOptionalNamespace(opts.namespace, workload)
id, err := resource.ParseIDOptionalNamespace(ns, workload)
if err != nil {
return err
}
Expand Down Expand Up @@ -132,7 +133,7 @@ func (opts *workloadReleaseOpts) RunE(cmd *cobra.Command, args []string) error {

var excludes []resource.ID
for _, exclude := range opts.exclude {
s, err := resource.ParseIDOptionalNamespace(opts.namespace, exclude)
s, err := resource.ParseIDOptionalNamespace(ns, exclude)
if err != nil {
return err
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/fluxctl/root_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
)

type rootOpts struct {
Context string
URL string
Token string
Namespace string
Expand Down Expand Up @@ -70,6 +71,8 @@ func (opts *rootOpts) Command() *cobra.Command {
PersistentPreRunE: opts.PersistentPreRunE,
}

cmd.PersistentFlags().StringVar(&opts.Context, "context", "",
fmt.Sprint("The kubeconfig context to use, will use your current selected if not specified"))
cmd.PersistentFlags().StringVar(&opts.Namespace, "k8s-fwd-ns", "default",
fmt.Sprintf("Namespace in which fluxd is running, for creating a port forward to access the API. No port forward will be created if a URL or token is given. You can also set the environment variable %s", envVariableNamespace))
cmd.PersistentFlags().StringToStringVar(&opts.Labels, "k8s-fwd-labels", map[string]string{"app": "flux"},
Expand Down Expand Up @@ -119,7 +122,7 @@ func (opts *rootOpts) PersistentPreRunE(cmd *cobra.Command, _ []string) error {
}

if opts.URL == "" {
portforwarder, err := tryPortforwards(opts.Namespace, metav1.LabelSelector{
portforwarder, err := tryPortforwards(opts.Context, opts.Namespace, metav1.LabelSelector{
MatchLabels: opts.Labels,
}, metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
Expand Down
5 changes: 3 additions & 2 deletions cmd/fluxctl/unlock_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (opts *workloadUnlockOpts) Command() *cobra.Command {
}
AddOutputFlags(cmd, &opts.outputOpts)
AddCauseFlags(cmd, &opts.cause)
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", getKubeConfigContextNamespace("default"), "Controller namespace")
cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "", "Controller namespace")
cmd.Flags().StringVarP(&opts.workload, "workload", "w", "", "Controller to unlock")

// Deprecated
Expand All @@ -50,10 +50,11 @@ func (opts *workloadUnlockOpts) RunE(cmd *cobra.Command, args []string) error {
case opts.controller != "":
opts.workload = opts.controller
}
ns := getKubeConfigContextNamespaceOrDefault(opts.namespace, "default", opts.Context)
policyOpts := &workloadPolicyOpts{
rootOpts: opts.rootOpts,
outputOpts: opts.outputOpts,
namespace: opts.namespace,
namespace: ns,
workload: opts.workload,
cause: opts.cause,
unlock: true,
Expand Down
1 change: 1 addition & 0 deletions docs/references/fluxctl.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ Available Commands:
version Output the version of fluxctl
Flags:
--context string The kubeconfig context to use
-h, --help help for fluxctl
--k8s-fwd-labels stringToString Labels used to select the fluxd pod a port forward should be created for. You can also set the environment variable FLUX_FORWARD_LABELS (default [app=flux])
--k8s-fwd-ns string Namespace in which fluxd is running, for creating a port forward to access the API. No port forward will be created if a URL or token is given. You can also set the environment variable FLUX_FORWARD_NAMESPACE (default "default")
Expand Down

0 comments on commit 997d1da

Please sign in to comment.