diff --git a/cmd/flux/completion.go b/cmd/flux/completion.go index 08406ac7..077d768e 100644 --- a/cmd/flux/completion.go +++ b/cmd/flux/completion.go @@ -17,7 +17,18 @@ limitations under the License. package main import ( + "context" + "strings" + + "github.com/fluxcd/flux2/internal/utils" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + memory "k8s.io/client-go/discovery/cached" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/restmapper" ) var completionCmd = &cobra.Command{ @@ -29,3 +40,77 @@ var completionCmd = &cobra.Command{ func init() { rootCmd.AddCommand(completionCmd) } + +func contextsCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + rawConfig, err := utils.ClientConfig(rootArgs.kubeconfig, rootArgs.kubecontext).RawConfig() + if err != nil { + return completionError(err) + } + + var comps []string + + for name := range rawConfig.Contexts { + if strings.HasPrefix(name, toComplete) { + comps = append(comps, name) + } + } + + return comps, cobra.ShellCompDirectiveNoFileComp +} + +func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) + defer cancel() + + cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + if err != nil { + return completionError(err) + } + + dc, err := discovery.NewDiscoveryClientForConfig(cfg) + if err != nil { + return completionError(err) + } + mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc)) + + mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return completionError(err) + } + + client, err := dynamic.NewForConfig(cfg) + if err != nil { + return completionError(err) + } + + var dr dynamic.ResourceInterface + if mapping.Scope.Name() == meta.RESTScopeNameNamespace { + dr = client.Resource(mapping.Resource).Namespace(rootArgs.namespace) + } else { + dr = client.Resource(mapping.Resource) + } + + list, err := dr.List(ctx, metav1.ListOptions{}) + if err != nil { + return completionError(err) + } + + var comps []string + + for _, item := range list.Items { + name := item.GetName() + + if strings.HasPrefix(name, toComplete) { + comps = append(comps, name) + } + } + + return comps, cobra.ShellCompDirectiveNoFileComp + } +} + +func completionError(err error) ([]string, cobra.ShellCompDirective) { + cobra.CompError(err.Error()) + return nil, cobra.ShellCompDirectiveError +} diff --git a/cmd/flux/delete_alert.go b/cmd/flux/delete_alert.go index 3b1ac9ce..c9e6f1ab 100644 --- a/cmd/flux/delete_alert.go +++ b/cmd/flux/delete_alert.go @@ -28,6 +28,7 @@ var deleteAlertCmd = &cobra.Command{ Long: "The delete alert command removes the given Alert from the cluster.", Example: ` # Delete an Alert and the Kubernetes resources created by it flux delete alert main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: deleteCommand{ apiType: alertType, object: universalAdapter{¬ificationv1.Alert{}}, diff --git a/cmd/flux/delete_alertprovider.go b/cmd/flux/delete_alertprovider.go index c1de6fea..08f0526c 100644 --- a/cmd/flux/delete_alertprovider.go +++ b/cmd/flux/delete_alertprovider.go @@ -28,6 +28,7 @@ var deleteAlertProviderCmd = &cobra.Command{ Long: "The delete alert-provider command removes the given Provider from the cluster.", Example: ` # Delete a Provider and the Kubernetes resources created by it flux delete alert-provider slack`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)), RunE: deleteCommand{ apiType: alertProviderType, object: universalAdapter{¬ificationv1.Provider{}}, diff --git a/cmd/flux/delete_helmrelease.go b/cmd/flux/delete_helmrelease.go index 05ad157a..c721d3dc 100644 --- a/cmd/flux/delete_helmrelease.go +++ b/cmd/flux/delete_helmrelease.go @@ -29,6 +29,7 @@ var deleteHelmReleaseCmd = &cobra.Command{ Long: "The delete helmrelease command removes the given HelmRelease from the cluster.", Example: ` # Delete a Helm release and the Kubernetes resources created by it flux delete hr podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: deleteCommand{ apiType: helmReleaseType, object: universalAdapter{&helmv2.HelmRelease{}}, diff --git a/cmd/flux/delete_image_policy.go b/cmd/flux/delete_image_policy.go index a11b7b59..e86924da 100644 --- a/cmd/flux/delete_image_policy.go +++ b/cmd/flux/delete_image_policy.go @@ -28,6 +28,7 @@ var deleteImagePolicyCmd = &cobra.Command{ Long: "The delete image policy command deletes the given ImagePolicy from the cluster.", Example: ` # Delete an image policy flux delete image policy alpine3.x`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)), RunE: deleteCommand{ apiType: imagePolicyType, object: universalAdapter{&imagev1.ImagePolicy{}}, diff --git a/cmd/flux/delete_image_repository.go b/cmd/flux/delete_image_repository.go index 10b85ff9..a8769788 100644 --- a/cmd/flux/delete_image_repository.go +++ b/cmd/flux/delete_image_repository.go @@ -28,6 +28,7 @@ var deleteImageRepositoryCmd = &cobra.Command{ Long: "The delete image repository command deletes the given ImageRepository from the cluster.", Example: ` # Delete an image repository flux delete image repository alpine`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)), RunE: deleteCommand{ apiType: imageRepositoryType, object: universalAdapter{&imagev1.ImageRepository{}}, diff --git a/cmd/flux/delete_image_update.go b/cmd/flux/delete_image_update.go index cede3840..3c38f078 100644 --- a/cmd/flux/delete_image_update.go +++ b/cmd/flux/delete_image_update.go @@ -28,6 +28,7 @@ var deleteImageUpdateCmd = &cobra.Command{ Long: "The delete image update command deletes the given ImageUpdateAutomation from the cluster.", Example: ` # Delete an image update automation flux delete image update latest-images`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: deleteCommand{ apiType: imageUpdateAutomationType, object: universalAdapter{&autov1.ImageUpdateAutomation{}}, diff --git a/cmd/flux/delete_kustomization.go b/cmd/flux/delete_kustomization.go index 5e03ad95..142eed26 100644 --- a/cmd/flux/delete_kustomization.go +++ b/cmd/flux/delete_kustomization.go @@ -29,6 +29,7 @@ var deleteKsCmd = &cobra.Command{ Long: "The delete kustomization command deletes the given Kustomization from the cluster.", Example: ` # Delete a kustomization and the Kubernetes resources created by it flux delete kustomization podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: deleteCommand{ apiType: kustomizationType, object: universalAdapter{&kustomizev1.Kustomization{}}, diff --git a/cmd/flux/delete_receiver.go b/cmd/flux/delete_receiver.go index 5806b6df..bfdc5dbc 100644 --- a/cmd/flux/delete_receiver.go +++ b/cmd/flux/delete_receiver.go @@ -28,6 +28,7 @@ var deleteReceiverCmd = &cobra.Command{ Long: "The delete receiver command removes the given Receiver from the cluster.", Example: ` # Delete an Receiver and the Kubernetes resources created by it flux delete receiver main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), RunE: deleteCommand{ apiType: receiverType, object: universalAdapter{¬ificationv1.Receiver{}}, diff --git a/cmd/flux/delete_source_bucket.go b/cmd/flux/delete_source_bucket.go index 3549efb9..56d9bdf8 100644 --- a/cmd/flux/delete_source_bucket.go +++ b/cmd/flux/delete_source_bucket.go @@ -28,6 +28,7 @@ var deleteSourceBucketCmd = &cobra.Command{ Long: "The delete source bucket command deletes the given Bucket from the cluster.", Example: ` # Delete a Bucket source flux delete source bucket podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: deleteCommand{ apiType: bucketType, object: universalAdapter{&sourcev1.Bucket{}}, diff --git a/cmd/flux/delete_source_git.go b/cmd/flux/delete_source_git.go index 36e4303a..5c521a5b 100644 --- a/cmd/flux/delete_source_git.go +++ b/cmd/flux/delete_source_git.go @@ -28,6 +28,7 @@ var deleteSourceGitCmd = &cobra.Command{ Long: "The delete source git command deletes the given GitRepository from the cluster.", Example: ` # Delete a Git repository flux delete source git podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: deleteCommand{ apiType: gitRepositoryType, object: universalAdapter{&sourcev1.GitRepository{}}, diff --git a/cmd/flux/delete_source_helm.go b/cmd/flux/delete_source_helm.go index 35cc2ad0..87b708ad 100644 --- a/cmd/flux/delete_source_helm.go +++ b/cmd/flux/delete_source_helm.go @@ -28,6 +28,7 @@ var deleteSourceHelmCmd = &cobra.Command{ Long: "The delete source helm command deletes the given HelmRepository from the cluster.", Example: ` # Delete a Helm repository flux delete source helm podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: deleteCommand{ apiType: helmRepositoryType, object: universalAdapter{&sourcev1.HelmRepository{}}, diff --git a/cmd/flux/export_alert.go b/cmd/flux/export_alert.go index 32b660e2..9c358e0c 100644 --- a/cmd/flux/export_alert.go +++ b/cmd/flux/export_alert.go @@ -32,6 +32,7 @@ var exportAlertCmd = &cobra.Command{ # Export a Alert flux export alert main > main.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: exportCommand{ object: alertAdapter{¬ificationv1.Alert{}}, list: alertListAdapter{¬ificationv1.AlertList{}}, diff --git a/cmd/flux/export_alertprovider.go b/cmd/flux/export_alertprovider.go index ddb6fe2f..eb47294f 100644 --- a/cmd/flux/export_alertprovider.go +++ b/cmd/flux/export_alertprovider.go @@ -32,6 +32,7 @@ var exportAlertProviderCmd = &cobra.Command{ # Export a Provider flux export alert-provider slack > slack.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)), RunE: exportCommand{ object: alertProviderAdapter{¬ificationv1.Provider{}}, list: alertProviderListAdapter{¬ificationv1.ProviderList{}}, diff --git a/cmd/flux/export_helmrelease.go b/cmd/flux/export_helmrelease.go index 961caa3c..8fd8c87f 100644 --- a/cmd/flux/export_helmrelease.go +++ b/cmd/flux/export_helmrelease.go @@ -33,6 +33,7 @@ var exportHelmReleaseCmd = &cobra.Command{ # Export a HelmRelease flux export hr my-app > app-release.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: exportCommand{ object: helmReleaseAdapter{&helmv2.HelmRelease{}}, list: helmReleaseListAdapter{&helmv2.HelmReleaseList{}}, diff --git a/cmd/flux/export_image_policy.go b/cmd/flux/export_image_policy.go index 6aa64f7b..5302dd63 100644 --- a/cmd/flux/export_image_policy.go +++ b/cmd/flux/export_image_policy.go @@ -32,6 +32,7 @@ var exportImagePolicyCmd = &cobra.Command{ # Export a specific policy flux export image policy alpine1x > alpine1x.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)), RunE: exportCommand{ object: imagePolicyAdapter{&imagev1.ImagePolicy{}}, list: imagePolicyListAdapter{&imagev1.ImagePolicyList{}}, diff --git a/cmd/flux/export_image_repository.go b/cmd/flux/export_image_repository.go index 7fad1da6..13f72f7d 100644 --- a/cmd/flux/export_image_repository.go +++ b/cmd/flux/export_image_repository.go @@ -32,6 +32,7 @@ var exportImageRepositoryCmd = &cobra.Command{ # Export a specific ImageRepository resource flux export image repository alpine > alpine.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)), RunE: exportCommand{ object: imageRepositoryAdapter{&imagev1.ImageRepository{}}, list: imageRepositoryListAdapter{&imagev1.ImageRepositoryList{}}, diff --git a/cmd/flux/export_image_update.go b/cmd/flux/export_image_update.go index 6d6fcffa..44f4b4a1 100644 --- a/cmd/flux/export_image_update.go +++ b/cmd/flux/export_image_update.go @@ -32,6 +32,7 @@ var exportImageUpdateCmd = &cobra.Command{ # Export a specific automation flux export image update latest-images > latest.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: exportCommand{ object: imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}}, list: imageUpdateAutomationListAdapter{&autov1.ImageUpdateAutomationList{}}, diff --git a/cmd/flux/export_kustomization.go b/cmd/flux/export_kustomization.go index d6f4e1db..fcf48819 100644 --- a/cmd/flux/export_kustomization.go +++ b/cmd/flux/export_kustomization.go @@ -33,6 +33,7 @@ var exportKsCmd = &cobra.Command{ # Export a Kustomization flux export kustomization my-app > kustomization.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: exportCommand{ object: kustomizationAdapter{&kustomizev1.Kustomization{}}, list: kustomizationListAdapter{&kustomizev1.KustomizationList{}}, diff --git a/cmd/flux/export_receiver.go b/cmd/flux/export_receiver.go index 54c8e75d..0a79d853 100644 --- a/cmd/flux/export_receiver.go +++ b/cmd/flux/export_receiver.go @@ -32,6 +32,7 @@ var exportReceiverCmd = &cobra.Command{ # Export a Receiver flux export receiver main > main.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), RunE: exportCommand{ list: receiverListAdapter{¬ificationv1.ReceiverList{}}, object: receiverAdapter{¬ificationv1.Receiver{}}, diff --git a/cmd/flux/export_source_bucket.go b/cmd/flux/export_source_bucket.go index 7a7039c1..33e36ebd 100644 --- a/cmd/flux/export_source_bucket.go +++ b/cmd/flux/export_source_bucket.go @@ -33,6 +33,7 @@ var exportSourceBucketCmd = &cobra.Command{ # Export a Bucket source including the static credentials flux export source bucket my-bucket --with-credentials > source.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: exportWithSecretCommand{ list: bucketListAdapter{&sourcev1.BucketList{}}, object: bucketAdapter{&sourcev1.Bucket{}}, diff --git a/cmd/flux/export_source_git.go b/cmd/flux/export_source_git.go index 7f069193..c93e0fd1 100644 --- a/cmd/flux/export_source_git.go +++ b/cmd/flux/export_source_git.go @@ -33,6 +33,7 @@ var exportSourceGitCmd = &cobra.Command{ # Export a GitRepository source including the SSH key pair or basic auth credentials flux export source git my-private-repo --with-credentials > source.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: exportWithSecretCommand{ object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, list: gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}}, diff --git a/cmd/flux/export_source_helm.go b/cmd/flux/export_source_helm.go index 62499987..d2215335 100644 --- a/cmd/flux/export_source_helm.go +++ b/cmd/flux/export_source_helm.go @@ -33,6 +33,7 @@ var exportSourceHelmCmd = &cobra.Command{ # Export a HelmRepository source including the basic auth credentials flux export source helm my-private-repo --with-credentials > source.yaml`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: exportWithSecretCommand{ list: helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}}, object: helmRepositoryAdapter{&sourcev1.HelmRepository{}}, diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go index 122d1bc6..126dbe56 100644 --- a/cmd/flux/get_alert.go +++ b/cmd/flux/get_alert.go @@ -34,6 +34,7 @@ var getAlertCmd = &cobra.Command{ Long: "The get alert command prints the statuses of the resources.", Example: ` # List all Alerts and their status flux get alerts`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: alertType, diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go index 4c7f6105..cb27973f 100644 --- a/cmd/flux/get_alertprovider.go +++ b/cmd/flux/get_alertprovider.go @@ -32,6 +32,7 @@ var getAlertProviderCmd = &cobra.Command{ Long: "The get alert-provider command prints the statuses of the resources.", Example: ` # List all Providers and their status flux get alert-providers`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: alertProviderType, diff --git a/cmd/flux/get_helmrelease.go b/cmd/flux/get_helmrelease.go index f489aa87..5478e29c 100644 --- a/cmd/flux/get_helmrelease.go +++ b/cmd/flux/get_helmrelease.go @@ -33,6 +33,7 @@ var getHelmReleaseCmd = &cobra.Command{ Long: "The get helmreleases command prints the statuses of the resources.", Example: ` # List all Helm releases and their status flux get helmreleases`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: helmReleaseType, diff --git a/cmd/flux/get_image_policy.go b/cmd/flux/get_image_policy.go index fe73118d..7974c380 100644 --- a/cmd/flux/get_image_policy.go +++ b/cmd/flux/get_image_policy.go @@ -34,6 +34,7 @@ var getImagePolicyCmd = &cobra.Command{ # List image policies from all namespaces flux get image policy --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: imagePolicyType, diff --git a/cmd/flux/get_image_repository.go b/cmd/flux/get_image_repository.go index a5b55fea..0878a29c 100644 --- a/cmd/flux/get_image_repository.go +++ b/cmd/flux/get_image_repository.go @@ -37,6 +37,7 @@ var getImageRepositoryCmd = &cobra.Command{ # List image repositories from all namespaces flux get image repository --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: imageRepositoryType, diff --git a/cmd/flux/get_image_update.go b/cmd/flux/get_image_update.go index 9c34f95d..da16c576 100644 --- a/cmd/flux/get_image_update.go +++ b/cmd/flux/get_image_update.go @@ -37,6 +37,7 @@ var getImageUpdateCmd = &cobra.Command{ # List image update automations from all namespaces flux get image update --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: imageUpdateAutomationType, diff --git a/cmd/flux/get_kustomization.go b/cmd/flux/get_kustomization.go index d507b2a5..3e749b2d 100644 --- a/cmd/flux/get_kustomization.go +++ b/cmd/flux/get_kustomization.go @@ -34,6 +34,7 @@ var getKsCmd = &cobra.Command{ Long: "The get kustomizations command prints the statuses of the resources.", Example: ` # List all kustomizations and their status flux get kustomizations`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: kustomizationType, diff --git a/cmd/flux/get_receiver.go b/cmd/flux/get_receiver.go index f3da4bb4..d2147d1b 100644 --- a/cmd/flux/get_receiver.go +++ b/cmd/flux/get_receiver.go @@ -34,6 +34,7 @@ var getReceiverCmd = &cobra.Command{ Long: "The get receiver command prints the statuses of the resources.", Example: ` # List all Receiver and their status flux get receivers`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: receiverType, diff --git a/cmd/flux/get_source_bucket.go b/cmd/flux/get_source_bucket.go index c34ef8c2..963a8ed4 100644 --- a/cmd/flux/get_source_bucket.go +++ b/cmd/flux/get_source_bucket.go @@ -36,6 +36,7 @@ var getSourceBucketCmd = &cobra.Command{ # List buckets from all namespaces flux get sources helm --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: bucketType, diff --git a/cmd/flux/get_source_chart.go b/cmd/flux/get_source_chart.go index 3e890a5f..f5401791 100644 --- a/cmd/flux/get_source_chart.go +++ b/cmd/flux/get_source_chart.go @@ -36,6 +36,7 @@ var getSourceHelmChartCmd = &cobra.Command{ # List Helm charts from all namespaces flux get sources chart --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: helmChartType, diff --git a/cmd/flux/get_source_git.go b/cmd/flux/get_source_git.go index 75639903..31a8e5bd 100644 --- a/cmd/flux/get_source_git.go +++ b/cmd/flux/get_source_git.go @@ -36,6 +36,7 @@ var getSourceGitCmd = &cobra.Command{ # List Git repositories from all namespaces flux get sources git --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: gitRepositoryType, diff --git a/cmd/flux/get_source_helm.go b/cmd/flux/get_source_helm.go index e0d0bb4d..cf98246b 100644 --- a/cmd/flux/get_source_helm.go +++ b/cmd/flux/get_source_helm.go @@ -36,6 +36,7 @@ var getSourceHelmCmd = &cobra.Command{ # List Helm repositories from all namespaces flux get sources helm --all-namespaces`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ apiType: helmRepositoryType, diff --git a/cmd/flux/main.go b/cmd/flux/main.go index 9295e83e..5bd8fa50 100644 --- a/cmd/flux/main.go +++ b/cmd/flux/main.go @@ -23,6 +23,7 @@ import ( "time" "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" _ "k8s.io/client-go/plugin/pkg/client/auth" "github.com/fluxcd/flux2/pkg/manifestgen/install" @@ -108,11 +109,15 @@ var rootArgs = NewRootFlags() func init() { rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace, "the namespace scope for this operation") + rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace"))) + rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation") rootCmd.PersistentFlags().BoolVar(&rootArgs.verbose, "verbose", false, "print generated objects") rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "", "absolute path to the kubeconfig file") + rootCmd.PersistentFlags().StringVarP(&rootArgs.kubecontext, "context", "", "", "kubernetes context to use") + rootCmd.RegisterFlagCompletionFunc("context", contextsCompletionFunc) rootCmd.DisableAutoGenTag = true } diff --git a/cmd/flux/reconcile_alert.go b/cmd/flux/reconcile_alert.go index 2bc79c9c..6027da3e 100644 --- a/cmd/flux/reconcile_alert.go +++ b/cmd/flux/reconcile_alert.go @@ -28,6 +28,7 @@ var reconcileAlertCmd = &cobra.Command{ Long: `The reconcile alert command triggers a reconciliation of an Alert resource and waits for it to finish.`, Example: ` # Trigger a reconciliation for an existing alert flux reconcile alert main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: reconcileCommand{ apiType: alertType, object: alertAdapter{¬ificationv1.Alert{}}, diff --git a/cmd/flux/reconcile_alertprovider.go b/cmd/flux/reconcile_alertprovider.go index ccf68bdb..092e8ac9 100644 --- a/cmd/flux/reconcile_alertprovider.go +++ b/cmd/flux/reconcile_alertprovider.go @@ -37,7 +37,8 @@ var reconcileAlertProviderCmd = &cobra.Command{ Long: `The reconcile alert-provider command triggers a reconciliation of a Provider resource and waits for it to finish.`, Example: ` # Trigger a reconciliation for an existing provider flux reconcile alert-provider slack`, - RunE: reconcileAlertProviderCmdRun, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)), + RunE: reconcileAlertProviderCmdRun, } func init() { diff --git a/cmd/flux/reconcile_helmrelease.go b/cmd/flux/reconcile_helmrelease.go index 0262dad9..38558a0f 100644 --- a/cmd/flux/reconcile_helmrelease.go +++ b/cmd/flux/reconcile_helmrelease.go @@ -35,6 +35,7 @@ The reconcile kustomization command triggers a reconciliation of a HelmRelease r # Trigger a reconciliation of the HelmRelease's source and apply changes flux reconcile hr podinfo --with-source`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: reconcileWithSourceCommand{ apiType: helmReleaseType, object: helmReleaseAdapter{&helmv2.HelmRelease{}}, diff --git a/cmd/flux/reconcile_image_repository.go b/cmd/flux/reconcile_image_repository.go index d2e4c087..efd89e9c 100644 --- a/cmd/flux/reconcile_image_repository.go +++ b/cmd/flux/reconcile_image_repository.go @@ -30,6 +30,7 @@ var reconcileImageRepositoryCmd = &cobra.Command{ Long: `The reconcile image repository command triggers a reconciliation of an ImageRepository resource and waits for it to finish.`, Example: ` # Trigger an scan for an existing image repository flux reconcile image repository alpine`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)), RunE: reconcileCommand{ apiType: imageRepositoryType, object: imageRepositoryAdapter{&imagev1.ImageRepository{}}, diff --git a/cmd/flux/reconcile_image_updateauto.go b/cmd/flux/reconcile_image_updateauto.go index b1af0d56..8fba13cc 100644 --- a/cmd/flux/reconcile_image_updateauto.go +++ b/cmd/flux/reconcile_image_updateauto.go @@ -32,6 +32,7 @@ var reconcileImageUpdateCmd = &cobra.Command{ Long: `The reconcile image update command triggers a reconciliation of an ImageUpdateAutomation resource and waits for it to finish.`, Example: ` # Trigger an automation run for an existing image update automation flux reconcile image update latest-images`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: reconcileCommand{ apiType: imageUpdateAutomationType, object: imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}}, diff --git a/cmd/flux/reconcile_kustomization.go b/cmd/flux/reconcile_kustomization.go index d108bcfa..48b7ec2e 100644 --- a/cmd/flux/reconcile_kustomization.go +++ b/cmd/flux/reconcile_kustomization.go @@ -35,6 +35,7 @@ The reconcile kustomization command triggers a reconciliation of a Kustomization # Trigger a sync of the Kustomization's source and apply changes flux reconcile kustomization podinfo --with-source`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: reconcileWithSourceCommand{ apiType: kustomizationType, object: kustomizationAdapter{&kustomizev1.Kustomization{}}, diff --git a/cmd/flux/reconcile_receiver.go b/cmd/flux/reconcile_receiver.go index 8ec849de..9b7e7fd0 100644 --- a/cmd/flux/reconcile_receiver.go +++ b/cmd/flux/reconcile_receiver.go @@ -37,7 +37,8 @@ var reconcileReceiverCmd = &cobra.Command{ Long: `The reconcile receiver command triggers a reconciliation of a Receiver resource and waits for it to finish.`, Example: ` # Trigger a reconciliation for an existing receiver flux reconcile receiver main`, - RunE: reconcileReceiverCmdRun, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), + RunE: reconcileReceiverCmdRun, } func init() { diff --git a/cmd/flux/reconcile_source_bucket.go b/cmd/flux/reconcile_source_bucket.go index 6fa346ba..768071da 100644 --- a/cmd/flux/reconcile_source_bucket.go +++ b/cmd/flux/reconcile_source_bucket.go @@ -37,6 +37,7 @@ var reconcileSourceBucketCmd = &cobra.Command{ Long: `The reconcile source command triggers a reconciliation of a Bucket resource and waits for it to finish.`, Example: ` # Trigger a reconciliation for an existing source flux reconcile source bucket podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: reconcileCommand{ apiType: bucketType, object: bucketAdapter{&sourcev1.Bucket{}}, diff --git a/cmd/flux/reconcile_source_git.go b/cmd/flux/reconcile_source_git.go index 9c01a8fc..9b5a75be 100644 --- a/cmd/flux/reconcile_source_git.go +++ b/cmd/flux/reconcile_source_git.go @@ -30,6 +30,7 @@ var reconcileSourceGitCmd = &cobra.Command{ Long: `The reconcile source command triggers a reconciliation of a GitRepository resource and waits for it to finish.`, Example: ` # Trigger a git pull for an existing source flux reconcile source git podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: reconcileCommand{ apiType: gitRepositoryType, object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, diff --git a/cmd/flux/reconcile_source_helm.go b/cmd/flux/reconcile_source_helm.go index 736b9245..e0836259 100644 --- a/cmd/flux/reconcile_source_helm.go +++ b/cmd/flux/reconcile_source_helm.go @@ -30,6 +30,7 @@ var reconcileSourceHelmCmd = &cobra.Command{ Long: `The reconcile source command triggers a reconciliation of a HelmRepository resource and waits for it to finish.`, Example: ` # Trigger a reconciliation for an existing source flux reconcile source helm podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: reconcileCommand{ apiType: helmRepositoryType, object: helmRepositoryAdapter{&sourcev1.HelmRepository{}}, diff --git a/cmd/flux/resume_alert.go b/cmd/flux/resume_alert.go index de5a645a..bede1e3e 100644 --- a/cmd/flux/resume_alert.go +++ b/cmd/flux/resume_alert.go @@ -29,6 +29,7 @@ var resumeAlertCmd = &cobra.Command{ finish the apply.`, Example: ` # Resume reconciliation for an existing Alert flux resume alert main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: resumeCommand{ apiType: alertType, object: alertAdapter{¬ificationv1.Alert{}}, diff --git a/cmd/flux/resume_helmrelease.go b/cmd/flux/resume_helmrelease.go index 24ee8010..0de4fb90 100644 --- a/cmd/flux/resume_helmrelease.go +++ b/cmd/flux/resume_helmrelease.go @@ -32,6 +32,7 @@ var resumeHrCmd = &cobra.Command{ finish the apply.`, Example: ` # Resume reconciliation for an existing Helm release flux resume hr podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: resumeCommand{ apiType: helmReleaseType, object: helmReleaseAdapter{&helmv2.HelmRelease{}}, diff --git a/cmd/flux/resume_image_repository.go b/cmd/flux/resume_image_repository.go index 59349c55..b0c15b18 100644 --- a/cmd/flux/resume_image_repository.go +++ b/cmd/flux/resume_image_repository.go @@ -28,6 +28,7 @@ var resumeImageRepositoryCmd = &cobra.Command{ Long: `The resume command marks a previously suspended ImageRepository resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing ImageRepository flux resume image repository alpine`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)), RunE: resumeCommand{ apiType: imageRepositoryType, object: imageRepositoryAdapter{&imagev1.ImageRepository{}}, diff --git a/cmd/flux/resume_image_updateauto.go b/cmd/flux/resume_image_updateauto.go index c7e45d74..8cc40bfc 100644 --- a/cmd/flux/resume_image_updateauto.go +++ b/cmd/flux/resume_image_updateauto.go @@ -28,6 +28,7 @@ var resumeImageUpdateCmd = &cobra.Command{ Long: `The resume command marks a previously suspended ImageUpdateAutomation resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing ImageUpdateAutomation flux resume image update latest-images`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: resumeCommand{ apiType: imageUpdateAutomationType, object: imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}}, diff --git a/cmd/flux/resume_kustomization.go b/cmd/flux/resume_kustomization.go index 1555cc9a..78bc5e66 100644 --- a/cmd/flux/resume_kustomization.go +++ b/cmd/flux/resume_kustomization.go @@ -32,6 +32,7 @@ var resumeKsCmd = &cobra.Command{ finish the apply.`, Example: ` # Resume reconciliation for an existing Kustomization flux resume ks podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: resumeCommand{ apiType: kustomizationType, object: kustomizationAdapter{&kustomizev1.Kustomization{}}, diff --git a/cmd/flux/resume_receiver.go b/cmd/flux/resume_receiver.go index eecfe63d..d4d3c64b 100644 --- a/cmd/flux/resume_receiver.go +++ b/cmd/flux/resume_receiver.go @@ -29,6 +29,7 @@ var resumeReceiverCmd = &cobra.Command{ finish the apply.`, Example: ` # Resume reconciliation for an existing Receiver flux resume receiver main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), RunE: resumeCommand{ apiType: receiverType, object: receiverAdapter{¬ificationv1.Receiver{}}, diff --git a/cmd/flux/resume_source_bucket.go b/cmd/flux/resume_source_bucket.go index e40cef34..c16d2090 100644 --- a/cmd/flux/resume_source_bucket.go +++ b/cmd/flux/resume_source_bucket.go @@ -28,6 +28,7 @@ var resumeSourceBucketCmd = &cobra.Command{ Long: `The resume command marks a previously suspended Bucket resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing Bucket flux resume source bucket podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: resumeCommand{ apiType: bucketType, object: &bucketAdapter{&sourcev1.Bucket{}}, diff --git a/cmd/flux/resume_source_chart.go b/cmd/flux/resume_source_chart.go index d3525eb3..6da61eed 100644 --- a/cmd/flux/resume_source_chart.go +++ b/cmd/flux/resume_source_chart.go @@ -30,6 +30,7 @@ var resumeSourceHelmChartCmd = &cobra.Command{ Long: `The resume command marks a previously suspended HelmChart resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing HelmChart flux resume source chart podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)), RunE: resumeCommand{ apiType: helmChartType, object: &helmChartAdapter{&sourcev1.HelmChart{}}, diff --git a/cmd/flux/resume_source_git.go b/cmd/flux/resume_source_git.go index f4aa22ed..31784281 100644 --- a/cmd/flux/resume_source_git.go +++ b/cmd/flux/resume_source_git.go @@ -28,6 +28,7 @@ var resumeSourceGitCmd = &cobra.Command{ Long: `The resume command marks a previously suspended GitRepository resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing GitRepository flux resume source git podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: resumeCommand{ apiType: gitRepositoryType, object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, diff --git a/cmd/flux/resume_source_helm.go b/cmd/flux/resume_source_helm.go index a22d7327..674a81b1 100644 --- a/cmd/flux/resume_source_helm.go +++ b/cmd/flux/resume_source_helm.go @@ -28,6 +28,7 @@ var resumeSourceHelmCmd = &cobra.Command{ Long: `The resume command marks a previously suspended HelmRepository resource for reconciliation and waits for it to finish.`, Example: ` # Resume reconciliation for an existing HelmRepository flux resume source helm bitnami`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: resumeCommand{ apiType: helmRepositoryType, object: helmRepositoryAdapter{&sourcev1.HelmRepository{}}, diff --git a/cmd/flux/suspend_alert.go b/cmd/flux/suspend_alert.go index eb3c184f..42ee60df 100644 --- a/cmd/flux/suspend_alert.go +++ b/cmd/flux/suspend_alert.go @@ -28,6 +28,7 @@ var suspendAlertCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a Alert resource.", Example: ` # Suspend reconciliation for an existing Alert flux suspend alert main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)), RunE: suspendCommand{ apiType: alertType, object: &alertAdapter{¬ificationv1.Alert{}}, diff --git a/cmd/flux/suspend_helmrelease.go b/cmd/flux/suspend_helmrelease.go index d222916a..5e552278 100644 --- a/cmd/flux/suspend_helmrelease.go +++ b/cmd/flux/suspend_helmrelease.go @@ -29,6 +29,7 @@ var suspendHrCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a HelmRelease resource.", Example: ` # Suspend reconciliation for an existing Helm release flux suspend hr podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: suspendCommand{ apiType: helmReleaseType, object: &helmReleaseAdapter{&helmv2.HelmRelease{}}, diff --git a/cmd/flux/suspend_image_repository.go b/cmd/flux/suspend_image_repository.go index 5651b799..826c4de4 100644 --- a/cmd/flux/suspend_image_repository.go +++ b/cmd/flux/suspend_image_repository.go @@ -28,6 +28,7 @@ var suspendImageRepositoryCmd = &cobra.Command{ Long: "The suspend image repository command disables the reconciliation of a ImageRepository resource.", Example: ` # Suspend reconciliation for an existing ImageRepository flux suspend image repository alpine`, + ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)), RunE: suspendCommand{ apiType: imageRepositoryType, object: imageRepositoryAdapter{&imagev1.ImageRepository{}}, diff --git a/cmd/flux/suspend_image_updateauto.go b/cmd/flux/suspend_image_updateauto.go index cc6c2ecf..cd6e8f3a 100644 --- a/cmd/flux/suspend_image_updateauto.go +++ b/cmd/flux/suspend_image_updateauto.go @@ -28,6 +28,7 @@ var suspendImageUpdateCmd = &cobra.Command{ Long: "The suspend image update command disables the reconciliation of a ImageUpdateAutomation resource.", Example: ` # Suspend reconciliation for an existing ImageUpdateAutomation flux suspend image update latest-images`, + ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)), RunE: suspendCommand{ apiType: imageUpdateAutomationType, object: imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}}, diff --git a/cmd/flux/suspend_kustomization.go b/cmd/flux/suspend_kustomization.go index 1d1f208b..18d00764 100644 --- a/cmd/flux/suspend_kustomization.go +++ b/cmd/flux/suspend_kustomization.go @@ -29,6 +29,7 @@ var suspendKsCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a Kustomization resource.", Example: ` # Suspend reconciliation for an existing Kustomization flux suspend ks podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: suspendCommand{ apiType: kustomizationType, object: kustomizationAdapter{&kustomizev1.Kustomization{}}, diff --git a/cmd/flux/suspend_receiver.go b/cmd/flux/suspend_receiver.go index 90ca5cf0..2edf1572 100644 --- a/cmd/flux/suspend_receiver.go +++ b/cmd/flux/suspend_receiver.go @@ -28,6 +28,7 @@ var suspendReceiverCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a Receiver resource.", Example: ` # Suspend reconciliation for an existing Receiver flux suspend receiver main`, + ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)), RunE: suspendCommand{ apiType: receiverType, object: &receiverAdapter{¬ificationv1.Receiver{}}, diff --git a/cmd/flux/suspend_source_bucket.go b/cmd/flux/suspend_source_bucket.go index 72f1d0e3..e452b9dc 100644 --- a/cmd/flux/suspend_source_bucket.go +++ b/cmd/flux/suspend_source_bucket.go @@ -28,6 +28,7 @@ var suspendSourceBucketCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a Bucket resource.", Example: ` # Suspend reconciliation for an existing Bucket flux suspend source bucket podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), RunE: suspendCommand{ apiType: bucketType, object: bucketAdapter{&sourcev1.Bucket{}}, diff --git a/cmd/flux/suspend_source_chart.go b/cmd/flux/suspend_source_chart.go index 703e820e..750e65ff 100644 --- a/cmd/flux/suspend_source_chart.go +++ b/cmd/flux/suspend_source_chart.go @@ -28,6 +28,7 @@ var suspendSourceHelmChartCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a HelmChart resource.", Example: ` # Suspend reconciliation for an existing HelmChart flux suspend source chart podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)), RunE: suspendCommand{ apiType: helmChartType, object: helmChartAdapter{&sourcev1.HelmChart{}}, diff --git a/cmd/flux/suspend_source_git.go b/cmd/flux/suspend_source_git.go index bc058303..16ebd0a6 100644 --- a/cmd/flux/suspend_source_git.go +++ b/cmd/flux/suspend_source_git.go @@ -28,6 +28,7 @@ var suspendSourceGitCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a GitRepository resource.", Example: ` # Suspend reconciliation for an existing GitRepository flux suspend source git podinfo`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)), RunE: suspendCommand{ apiType: gitRepositoryType, object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, diff --git a/cmd/flux/suspend_source_helm.go b/cmd/flux/suspend_source_helm.go index a4a5787c..0b29a2dc 100644 --- a/cmd/flux/suspend_source_helm.go +++ b/cmd/flux/suspend_source_helm.go @@ -28,6 +28,7 @@ var suspendSourceHelmCmd = &cobra.Command{ Long: "The suspend command disables the reconciliation of a HelmRepository resource.", Example: ` # Suspend reconciliation for an existing HelmRepository flux suspend source helm bitnami`, + ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)), RunE: suspendCommand{ apiType: helmRepositoryType, object: helmRepositoryAdapter{&sourcev1.HelmRepository{}}, diff --git a/internal/utils/utils.go b/internal/utils/utils.go index d06629e2..1181cc0b 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -107,7 +107,7 @@ func ExecKubectlCommand(ctx context.Context, mode ExecMode, kubeConfigPath strin return "", nil } -func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) { +func ClientConfig(kubeConfigPath string, kubeContext string) clientcmd.ClientConfig { configFiles := SplitKubeConfigPath(kubeConfigPath) configOverrides := clientcmd.ConfigOverrides{} @@ -115,11 +115,14 @@ func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) configOverrides.CurrentContext = kubeContext } - cfg, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( &clientcmd.ClientConfigLoadingRules{Precedence: configFiles}, &configOverrides, - ).ClientConfig() + ) +} +func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) { + cfg, err := ClientConfig(kubeConfigPath, kubeContext).ClientConfig() if err != nil { return nil, fmt.Errorf("kubernetes configuration load failed: %w", err) }