sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/delete.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package client 18 19 import ( 20 "context" 21 22 "github.com/pkg/errors" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 kerrors "k8s.io/apimachinery/pkg/util/errors" 25 26 clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3" 27 "sigs.k8s.io/cluster-api/cmd/clusterctl/client/cluster" 28 ) 29 30 // DeleteOptions carries the options supported by Delete. 31 type DeleteOptions struct { 32 // Kubeconfig defines the kubeconfig to use for accessing the management cluster. If empty, 33 // default rules for kubeconfig discovery will be used. 34 Kubeconfig Kubeconfig 35 36 // CoreProvider version (e.g. cluster-api:v1.1.5) to delete from the management cluster. 37 CoreProvider string 38 39 // BootstrapProviders and versions (e.g. kubeadm:v1.1.5) to delete from the management cluster. 40 BootstrapProviders []string 41 42 // InfrastructureProviders and versions (e.g. aws:v0.5.0) to delete from the management cluster. 43 InfrastructureProviders []string 44 45 // ControlPlaneProviders and versions (e.g. kubeadm:v1.1.5) to delete from the management cluster. 46 ControlPlaneProviders []string 47 48 // IPAMProviders and versions (e.g. infoblox:v0.0.1) to delete from the management cluster. 49 IPAMProviders []string 50 51 // RuntimeExtensionProviders and versions (e.g. test:v0.0.1) to delete from the management cluster. 52 RuntimeExtensionProviders []string 53 54 // AddonProviders and versions (e.g. helm:v0.1.0) to delete from the management cluster. 55 AddonProviders []string 56 57 // DeleteAll set for deletion of all the providers. 58 DeleteAll bool 59 60 // IncludeNamespace forces the deletion of the namespace where the providers are hosted 61 // (and of all the contained objects). 62 IncludeNamespace bool 63 64 // IncludeCRDs forces the deletion of the provider's CRDs (and of all the related objects). 65 IncludeCRDs bool 66 67 // SkipInventory forces the deletion of the inventory items used by clusterctl to track providers. 68 SkipInventory bool 69 } 70 71 func (c *clusterctlClient) Delete(ctx context.Context, options DeleteOptions) error { 72 clusterClient, err := c.clusterClientFactory(ClusterClientFactoryInput{Kubeconfig: options.Kubeconfig}) 73 if err != nil { 74 return err 75 } 76 77 // Ensure this command only runs against management clusters with the current Cluster API contract. 78 if err := clusterClient.ProviderInventory().CheckCAPIContract(ctx); err != nil { 79 return err 80 } 81 82 // Ensure the custom resource definitions required by clusterctl are in place. 83 if err := clusterClient.ProviderInventory().EnsureCustomResourceDefinitions(ctx); err != nil { 84 return err 85 } 86 87 // Get the list of installed providers. 88 installedProviders, err := clusterClient.ProviderInventory().List(ctx) 89 if err != nil { 90 return err 91 } 92 93 // Prepare the list of providers to delete. 94 var providersToDelete []clusterctlv1.Provider 95 96 if options.DeleteAll { 97 providersToDelete = installedProviders.Items 98 } else { 99 // Otherwise we are deleting only a subset of providers. 100 var providers []clusterctlv1.Provider 101 providers, err = appendProviders(providers, clusterctlv1.CoreProviderType, options.CoreProvider) 102 if err != nil { 103 return err 104 } 105 106 providers, err = appendProviders(providers, clusterctlv1.BootstrapProviderType, options.BootstrapProviders...) 107 if err != nil { 108 return err 109 } 110 111 providers, err = appendProviders(providers, clusterctlv1.ControlPlaneProviderType, options.ControlPlaneProviders...) 112 if err != nil { 113 return err 114 } 115 116 providers, err = appendProviders(providers, clusterctlv1.InfrastructureProviderType, options.InfrastructureProviders...) 117 if err != nil { 118 return err 119 } 120 121 providers, err = appendProviders(providers, clusterctlv1.IPAMProviderType, options.IPAMProviders...) 122 if err != nil { 123 return err 124 } 125 126 providers, err = appendProviders(providers, clusterctlv1.RuntimeExtensionProviderType, options.RuntimeExtensionProviders...) 127 if err != nil { 128 return err 129 } 130 131 providers, err = appendProviders(providers, clusterctlv1.AddonProviderType, options.AddonProviders...) 132 if err != nil { 133 return err 134 } 135 136 for _, provider := range providers { 137 // Try to detect the namespace where the provider lives 138 provider.Namespace, err = clusterClient.ProviderInventory().GetProviderNamespace(ctx, provider.ProviderName, provider.GetProviderType()) 139 if err != nil { 140 return err 141 } 142 if provider.Namespace == "" { 143 return errors.Errorf("failed to identify the namespace for the %q provider", provider.ProviderName) 144 } 145 146 if provider.Version != "" { 147 version, err := clusterClient.ProviderInventory().GetProviderVersion(ctx, provider.ProviderName, provider.GetProviderType()) 148 if err != nil { 149 return err 150 } 151 if provider.Version != version { 152 return errors.Errorf("failed to identify the provider %q with version %q", provider.ProviderName, provider.Version) 153 } 154 } 155 156 providersToDelete = append(providersToDelete, provider) 157 } 158 } 159 160 if options.IncludeCRDs { 161 errList := []error{} 162 for _, provider := range providersToDelete { 163 err = clusterClient.ProviderComponents().ValidateNoObjectsExist(ctx, provider) 164 if err != nil { 165 errList = append(errList, err) 166 } 167 } 168 if len(errList) > 0 { 169 return kerrors.NewAggregate(errList) 170 } 171 } 172 173 // Delete the selected providers. 174 for _, provider := range providersToDelete { 175 if err := clusterClient.ProviderComponents().Delete(ctx, cluster.DeleteOptions{Provider: provider, IncludeNamespace: options.IncludeNamespace, IncludeCRDs: options.IncludeCRDs, SkipInventory: options.SkipInventory}); err != nil { 176 return err 177 } 178 } 179 180 return nil 181 } 182 183 func appendProviders(list []clusterctlv1.Provider, providerType clusterctlv1.ProviderType, names ...string) ([]clusterctlv1.Provider, error) { 184 for _, name := range names { 185 if name == "" { 186 continue 187 } 188 189 // Parse the abbreviated syntax for name[:version] 190 name, version, err := parseProviderName(name) 191 if err != nil { 192 return nil, err 193 } 194 195 list = append(list, clusterctlv1.Provider{ 196 ObjectMeta: metav1.ObjectMeta{ 197 Name: clusterctlv1.ManifestLabel(name, providerType), 198 }, 199 ProviderName: name, 200 Type: string(providerType), 201 Version: version, 202 }) 203 } 204 return list, nil 205 }