diff --git a/cmd/flux/completion.go b/cmd/flux/completion.go index 08406ac7ffa68bf60b22d5854afbcae17783d2a0..077d768eb6878371d67ab36e1e2a15585d4df9f4 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 3b1ac9ce25e8f0b761682597d539366ad538c642..c9e6f1abb35426777f3585b88d2f8fdeb9f8a6a2 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 c1de6fea04446497cb838aafb6f428b54696f5a9..08f0526c3b33528d775ec07d3f7465de3899fc6e 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 05ad157afe05540716d495557de9c455cba5a7a3..c721d3dcba46a858cfc2b1c2798d7806f3d13e95 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 a11b7b5915a1e211b4ee9f024de3feced54b7286..e86924da990c9cdf44ae2da3e4ecba73b275a04d 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 10b85ff902bbd81a207530c2f6e813c83d512544..a8769788a5e2d2edd8f0f7ef3f4211e9e4920726 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 cede3840a657efc71bf7891f1fbab40ba13b6966..3c38f078d29acd62df264be271fadd25123eb1f3 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 5e03ad9526291671b7da28df45ebb409e3b9ff51..142eed262572295e84fc516bd3b0858edd551f79 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 5806b6df8ff30c92beadf90ac03543cba1c6cc3b..bfdc5dbc8910ce1d244203091ff24d664b35f19d 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 3549efb98cbca247d2451dcfe4ced6c56b62173a..56d9bdf8e6f9e51c025fad3cad86664707605390 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 36e4303a011e2ab363113b06a30dd4d0ceeaa299..5c521a5b2e93afd52a43711f92a36ddad05f9266 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 35cc2ad073ff2d679bafa8a823d73514d894ddb0..87b708ad72abb956234e8d2533e87c21f7425123 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 32b660e2c5340a139df04f3653e65b1983938199..9c358e0c643a9124f9dcbd42fc2bfe2e8326fcdc 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 ddb6fe2fdf7ad7f59f5dc102e21e79204f6b6070..eb47294f9a6ee5c55e48993a78fe9f8072cf7688 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 961caa3c4b4689bfbf0c133aad45abc74f9f246b..8fd8c87fb3035818285af711d10892d8dde420f9 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 6aa64f7b055941c021f57ffd175f92712f7c96f6..5302dd635d629d2c95eace5f9f6d8949bab1aac8 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 7fad1da639ddb3a6a53ec884a0a61433d7a6c1c3..13f72f7d43b08c589412ca45cb219c4c5cd6ca4b 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 6d6fcffabc6b57933fa980d78efe6bef04b229de..44f4b4a165a84840d375aa6ffb9ec7d066a1ecfd 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 d6f4e1db8613c01a7c9f3c5ea5fadf354a2a349a..fcf488194cdc63d760e30cdb030459b1ccfeca4e 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 54c8e75debefa99d2a131b7be32b06b001dc5e75..0a79d853c7e3dfe34a617b41041b2c5b94f6dd8e 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 7a7039c180c717889f2167c8950fb249b676c32f..33e36ebd17059d4275825bf96b7474c505c0f103 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 7f0691930aa309603c864a32358a419ba62c1984..c93e0fd1a1f435754136b259377073562f70317b 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 62499987b6b8588ea9398159c3d815132a911e0d..d22153351080fb7454c31848792659aa5ba33aff 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 122d1bc6dee85b336736dec78dff7408bf322da1..126dbe569a59e76d8c005a5079589967745fce0a 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 4c7f6105232faf6238d7560319cf419fffbc6de2..cb27973f731df841f96143078d294c856b689cdb 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 f489aa8761472d4ed75c3f41c2a2b26608a5c982..5478e29c0663ead8053312313bbe10437402bca8 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 fe73118d8af821974a6be781740a52ab76faa95f..7974c380e33d597d5e5c1f6c613f6bbb0e2460bf 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 a5b55feaa1967698b29b459ece7848c98fc70977..0878a29c01a5df86bf40c57a0df8fd12f091d1ea 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 9c34f95d1cfb234cededa545b8f863898a2badde..da16c57611c494a10699403378dcfead3b83684f 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 d507b2a5cb091b80f405052a80797ea4681ae4c8..3e749b2d691ac2d251eef3aa5f8fac2c4e1739d1 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 f3da4bb4747b5f466123734bd0d04baafc58440c..d2147d1b18a557bafb5a17c244cd67cafc02e288 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 c34ef8c271cd567ef49a619b173ffe3b3f89a5a6..963a8ed416a9cefc33891693811325ed8ebca88a 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 3e890a5faca7a58352942a5acde4397319783141..f5401791f3405cd56f2ac76444509557fdae726b 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 75639903ef020775da17753386da9a98c4b34376..31a8e5bd7da22626c3b14a518e61e65b82f7ad89 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 e0d0bb4d437a9dd646ae824b3b81f488bd62a322..cf98246b59c8ac8f1db2e243340632c7f5ecae9a 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 9295e83ea3ea7eb6daf56a62d46e666a44c10497..5bd8fa508a2c0eab70bf2f8561d138f13689d846 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 2bc79c9c82874e0b33acd6534c480df557848e9b..6027da3ef435726625809134f3ace7641966f642 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 ccf68bdbd505284c16f21895fdb04bd51945354f..092e8ac90b0a0e0a6dc6fdcf55063a6c7d67507b 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 0262dad9c5be2bb530b12cf2c798f8bd3b5be526..38558a0fe76a9a3617b3d8562d045c82116555f0 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 d2e4c0875ab347724a37989c800a834502b7bccf..efd89e9c570299b351870abef32cbc9d265bd97d 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 b1af0d56154d7c7fbc374484d6521b08dbdd6924..8fba13ccf4374f9197358320089d9e1a29070843 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 d108bcfa0eec2d729cc8d54089883df30b3ff6ac..48b7ec2ece223e584963e2b14fd4a22cd42cbbfc 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 8ec849def83b7c507d19092fa93fbd885d9034c4..9b7e7fd042f10e606fdb583411a34b98e9d8baf3 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 6fa346baa69a0b7ec46edc3ec246f17fc0eec497..768071da20d010b6dca102ef25e9bdb25589466d 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 9c01a8fce7bfcfd7b1c17dbe61ce81c592c83eb7..9b5a75be13889ed385506e619e5f0eb3fcca2c51 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 736b924548026fe41c4280e1c9992879b4fb58a0..e0836259c4a3374142d44a690413ce14c0ee9ed0 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 de5a645a7b2e07b8ff15ea7a4b5b5a51554a79a2..bede1e3efaaa9f124f406045eb830916e0de3e71 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 24ee8010fce798ef2e8b20dd897103c7d0907ab9..0de4fb9042004ba849841335f750e43cd0495b59 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 59349c55e08cbe6a2e5b4131e5de3560b47c8338..b0c15b189d93672e0b520abdb7873719fe7f1656 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 c7e45d74a80efb79264c10ec274c48029ab69086..8cc40bfc80e53c4ae728218c9e358cc962024df0 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 1555cc9a32b3279adf28d7871c5b3ccd1a065ba0..78bc5e6645fffec34adb04b0a552eace5c532ac9 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 eecfe63d9fc7aee70bd87715e4d0fedc38a2dbe6..d4d3c64be099d3f42d27ef67d2fa601157cabddc 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 e40cef344a7628c6f12fc6f6d92045f6e43f6653..c16d20902a934d5dcdba6698d6d7fc7788a26056 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 d3525eb3c8045629dcd1b72ddc381d092b8fff5a..6da61eed8d72f52344211e3974e19db6a8012ea0 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 f4aa22edad77d0f4829f85461730318814352279..3178428121612dcdb8d567db8991e73bce1b8202 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 a22d73270af21d09eebe40f00a2a306d8f6a85de..674a81b1b27ff9b3254570e4ec5bfccd46c0da47 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 eb3c184f8b4d61d76f7de71228ded7885bd1aa0d..42ee60df8de3377854dda1e2cda1cf04e3a6b5e8 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 d222916a02d8b39b9a3fb4651ea57457b072b5ba..5e552278769fe028580abb68f95124c26c41e214 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 5651b79936fec8ec74df7e014dd13e583b4674dc..826c4de4fd3327be9db4c43a5e9da827881c340b 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 cc6c2ecfcaf89b7c36932e96b942e9f305acbb8f..cd6e8f3a6e7b71882f53c5fc65f40752e851c682 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 1d1f208b1cb4ee9b2fe69d1f531fd4b0f5ec41af..18d007644dc0c44c17adaacfaa822c00649a2e55 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 90ca5cf0961d63fea997a4c28176fcbacf371f05..2edf1572e841db95bf195bb17c528b7f944ed730 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 72f1d0e3f4f63315db0a59fd8b54e4bbbd7aa8b2..e452b9dce32fa46725740eb5159dcd0b48fbac94 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 703e820e367cc9f417538e34968fc9b6eb62ed1d..750e65ff6b32876664288c86f8c9d4e26edb0ff9 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 bc058303ea40ea91d8dbe8615ad3ca02335a7fc9..16ebd0a637b8558c1fbb2507f80a2fbaff906b21 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 a4a5787c9678d40c888ea453357526b77a6cac59..0b29a2dc60925cbeb940b10a65c966c5438f821a 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 d06629e24c857d9a3bb9c3d0b82cdbd35af557da..1181cc0b582cf60aa522848a4864565366029a3b 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) }