diff --git a/cmd/flux/delete.go b/cmd/flux/delete.go index a276c0d8..4a9737b0 100644 --- a/cmd/flux/delete.go +++ b/cmd/flux/delete.go @@ -17,7 +17,14 @@ limitations under the License. package main import ( + "context" + "fmt" + + "github.com/manifoldco/promptui" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/types" + + "github.com/fluxcd/flux2/internal/utils" ) var deleteCmd = &cobra.Command{ @@ -36,3 +43,52 @@ func init() { rootCmd.AddCommand(deleteCmd) } + +type deleteCommand struct { + humanKind string // the kind being deleted, lowercase and spaced e.g., "image policy" + container objectContainer // for getting the value, and later deleting it +} + +func (del deleteCommand) run(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("%s name is required", del.humanKind) + } + name := args[0] + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + if err != nil { + return err + } + + namespacedName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + + err = kubeClient.Get(ctx, namespacedName, del.container.AsClientObject()) + if err != nil { + return err + } + + if !deleteSilent { + prompt := promptui.Prompt{ + Label: "Are you sure you want to delete this " + del.humanKind, + IsConfirm: true, + } + if _, err := prompt.Run(); err != nil { + return fmt.Errorf("aborting") + } + } + + logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, namespace) + err = kubeClient.Delete(ctx, del.container.AsClientObject()) + if err != nil { + return err + } + logger.Successf("%s deleted", del.humanKind) + + return nil +} diff --git a/cmd/flux/delete_auto_imagepolicy.go b/cmd/flux/delete_auto_imagepolicy.go new file mode 100644 index 00000000..8d6e0095 --- /dev/null +++ b/cmd/flux/delete_auto_imagepolicy.go @@ -0,0 +1,40 @@ +/* +Copyright 2020 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "github.com/spf13/cobra" + + imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1" +) + +var deleteImagePolicyCmd = &cobra.Command{ + Use: "image-policy [name]", + Short: "Delete an ImagePolicy object", + Long: "The delete auto image-policy command deletes the given ImagePolicy from the cluster.", + Example: ` # Delete an image policy + flux delete auto image-policy alpine3.x +`, + RunE: deleteCommand{ + humanKind: "image policy", + container: genericContainer{&imagev1.ImagePolicy{}}, + }.run, +} + +func init() { + deleteAutoCmd.AddCommand(deleteImagePolicyCmd) +} diff --git a/cmd/flux/delete_auto_imagerepository.go b/cmd/flux/delete_auto_imagerepository.go index e436eb80..81f0d68a 100644 --- a/cmd/flux/delete_auto_imagerepository.go +++ b/cmd/flux/delete_auto_imagerepository.go @@ -17,14 +17,8 @@ limitations under the License. package main import ( - "context" - "fmt" - - "github.com/manifoldco/promptui" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "github.com/fluxcd/flux2/internal/utils" imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1" ) @@ -35,54 +29,12 @@ var deleteImageRepositoryCmd = &cobra.Command{ Example: ` # Delete an image repository flux delete auto image-repository alpine `, - RunE: deleteImageRepositoryRun, + RunE: deleteCommand{ + humanKind: "image repository", + container: genericContainer{&imagev1.ImageRepository{}}, + }.run, } func init() { deleteAutoCmd.AddCommand(deleteImageRepositoryCmd) } - -func deleteImageRepositoryRun(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf("image repository name is required") - } - name := args[0] - - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) - if err != nil { - return err - } - - namespacedName := types.NamespacedName{ - Namespace: namespace, - Name: name, - } - - var repo imagev1.ImageRepository - err = kubeClient.Get(ctx, namespacedName, &repo) - if err != nil { - return err - } - - if !deleteSilent { - prompt := promptui.Prompt{ - Label: "Are you sure you want to delete this image repository", - IsConfirm: true, - } - if _, err := prompt.Run(); err != nil { - return fmt.Errorf("aborting") - } - } - - logger.Actionf("deleting image repository %s in %s namespace", name, namespace) - err = kubeClient.Delete(ctx, &repo) - if err != nil { - return err - } - logger.Successf("image repository deleted") - - return nil -} diff --git a/cmd/flux/get.go b/cmd/flux/get.go index a65cd957..26c1ac8a 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/fluxcd/pkg/apis/meta" @@ -46,7 +45,7 @@ func init() { } type summarisable interface { - AsObject() runtime.Object + objectContainer Len() int SummariseAt(i int, includeNamespace bool) []string Headers(includeNamespace bool) []string @@ -93,7 +92,7 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { if !allNamespaces { listOpts = append(listOpts, client.InNamespace(namespace)) } - err = kubeClient.List(ctx, get.list.AsObject(), listOpts...) + err = kubeClient.List(ctx, get.list.AsClientObject(), listOpts...) if err != nil { return err } diff --git a/cmd/flux/get_auto_imagepolicy.go b/cmd/flux/get_auto_imagepolicy.go index 48b9abdd..c2954a2d 100644 --- a/cmd/flux/get_auto_imagepolicy.go +++ b/cmd/flux/get_auto_imagepolicy.go @@ -64,6 +64,6 @@ func (s imagePolicySummary) Headers(includeNamespace bool) []string { return headers } -func (s imagePolicySummary) AsObject() runtime.Object { +func (s imagePolicySummary) AsClientObject() runtime.Object { return s.ImagePolicyList } diff --git a/cmd/flux/get_auto_imagerepository.go b/cmd/flux/get_auto_imagerepository.go index d093dd8b..542d7b32 100644 --- a/cmd/flux/get_auto_imagerepository.go +++ b/cmd/flux/get_auto_imagerepository.go @@ -73,6 +73,6 @@ func (s imageRepositorySummary) Headers(includeNamespace bool) []string { return headers } -func (s imageRepositorySummary) AsObject() runtime.Object { +func (s imageRepositorySummary) AsClientObject() runtime.Object { return s.ImageRepositoryList } diff --git a/cmd/flux/object.go b/cmd/flux/object.go new file mode 100644 index 00000000..922268bb --- /dev/null +++ b/cmd/flux/object.go @@ -0,0 +1,40 @@ +/* +Copyright 2020 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// objectContainer is an interface for a wrapper or alias from which we +// can get a controller-runtime deserialisable value. This is used so +// that you can wrap an API type to give it other useful methods, but +// still use values of the wrapper with `client.Client`, which only +// deals with types that have been added to the schema. +type objectContainer interface { + AsClientObject() runtime.Object +} + +// genericContainer is an objectContainer for any runtime.Object. Use +// this if there are no other methods needed. +type genericContainer struct { + obj runtime.Object +} + +func (c genericContainer) AsClientObject() runtime.Object { + return c.obj +} diff --git a/docs/cmd/flux_delete_auto.md b/docs/cmd/flux_delete_auto.md index feca2043..b511a1df 100644 --- a/docs/cmd/flux_delete_auto.md +++ b/docs/cmd/flux_delete_auto.md @@ -26,5 +26,6 @@ The delete auto sub-commands delete automation objects. ### SEE ALSO * [flux delete](flux_delete.md) - Delete sources and resources +* [flux delete auto image-policy](flux_delete_auto_image-policy.md) - Delete an ImagePolicy object * [flux delete auto image-repository](flux_delete_auto_image-repository.md) - Delete an ImageRepository object diff --git a/docs/cmd/flux_delete_auto_image-policy.md b/docs/cmd/flux_delete_auto_image-policy.md new file mode 100644 index 00000000..64152e00 --- /dev/null +++ b/docs/cmd/flux_delete_auto_image-policy.md @@ -0,0 +1,41 @@ +## flux delete auto image-policy + +Delete an ImagePolicy object + +### Synopsis + +The delete auto image-policy command deletes the given ImagePolicy from the cluster. + +``` +flux delete auto image-policy [name] [flags] +``` + +### Examples + +``` + # Delete an image policy + flux delete auto image-policy alpine3.x + +``` + +### Options + +``` + -h, --help help for image-policy +``` + +### Options inherited from parent commands + +``` + --context string kubernetes context to use + --kubeconfig string path to the kubeconfig file (default "~/.kube/config") + -n, --namespace string the namespace scope for this operation (default "flux-system") + -s, --silent delete resource without asking for confirmation + --timeout duration timeout for this operation (default 5m0s) + --verbose print generated objects +``` + +### SEE ALSO + +* [flux delete auto](flux_delete_auto.md) - Delete automation objects +