sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/delete_test.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 "testing" 22 23 . "github.com/onsi/gomega" 24 "k8s.io/apimachinery/pkg/util/sets" 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 const ( 31 namespace = "foobar" 32 providerVersion = "v1.0.0" 33 ) 34 35 func Test_clusterctlClient_Delete(t *testing.T) { 36 type fields struct { 37 client *fakeClient 38 } 39 type args struct { 40 options DeleteOptions 41 } 42 tests := []struct { 43 name string 44 fields fields 45 args args 46 wantProviders sets.Set[string] 47 wantErr bool 48 }{ 49 { 50 name: "Delete all the providers", 51 fields: fields{ 52 client: fakeClusterForDelete(), 53 }, 54 args: args{ 55 options: DeleteOptions{ 56 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 57 IncludeNamespace: false, 58 IncludeCRDs: false, 59 SkipInventory: false, 60 CoreProvider: "", 61 BootstrapProviders: nil, 62 InfrastructureProviders: nil, 63 ControlPlaneProviders: nil, 64 DeleteAll: true, // delete all the providers 65 }, 66 }, 67 wantProviders: sets.Set[string]{}, 68 wantErr: false, 69 }, 70 { 71 name: "Delete all the providers including CRDs", 72 fields: fields{ 73 client: fakeClusterForDelete(), 74 }, 75 args: args{ 76 options: DeleteOptions{ 77 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 78 IncludeNamespace: false, 79 IncludeCRDs: true, 80 SkipInventory: false, 81 CoreProvider: "", 82 BootstrapProviders: nil, 83 InfrastructureProviders: nil, 84 ControlPlaneProviders: nil, 85 DeleteAll: true, // delete all the providers 86 }, 87 }, 88 wantProviders: sets.Set[string]{}, 89 wantErr: false, 90 }, 91 { 92 name: "Delete single provider auto-detect namespace", 93 fields: fields{ 94 client: fakeClusterForDelete(), 95 }, 96 args: args{ 97 options: DeleteOptions{ 98 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 99 IncludeNamespace: false, 100 IncludeCRDs: false, 101 SkipInventory: false, 102 CoreProvider: "", 103 BootstrapProviders: []string{bootstrapProviderConfig.Name()}, 104 InfrastructureProviders: nil, 105 ControlPlaneProviders: nil, 106 DeleteAll: false, 107 }, 108 }, 109 wantProviders: sets.Set[string]{}.Insert( 110 capiProviderConfig.Name(), 111 clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()), 112 clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())), 113 wantErr: false, 114 }, 115 { 116 name: "Delete a provider with version mentioned", 117 fields: fields{ 118 client: fakeClusterForDelete(), 119 }, 120 args: args{ 121 options: DeleteOptions{ 122 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 123 IncludeNamespace: false, 124 IncludeCRDs: false, 125 SkipInventory: false, 126 CoreProvider: "", 127 BootstrapProviders: nil, 128 InfrastructureProviders: []string{infraProviderConfig.Name() + ":" + providerVersion}, 129 ControlPlaneProviders: nil, 130 DeleteAll: false, 131 }, 132 }, 133 wantProviders: sets.Set[string]{}.Insert( 134 capiProviderConfig.Name(), 135 clusterctlv1.ManifestLabel(bootstrapProviderConfig.Name(), bootstrapProviderConfig.Type()), 136 clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type())), 137 wantErr: false, 138 }, 139 { 140 name: "Delete a provider with wrong version", 141 fields: fields{ 142 client: fakeClusterForDelete(), 143 }, 144 args: args{ 145 options: DeleteOptions{ 146 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 147 IncludeNamespace: false, 148 IncludeCRDs: false, 149 SkipInventory: false, 150 CoreProvider: "", 151 BootstrapProviders: nil, 152 InfrastructureProviders: []string{infraProviderConfig.Name() + ":v99.99.99"}, 153 ControlPlaneProviders: nil, 154 DeleteAll: false, 155 }, 156 }, 157 wantProviders: sets.Set[string]{}.Insert( 158 capiProviderConfig.Name(), 159 clusterctlv1.ManifestLabel(bootstrapProviderConfig.Name(), bootstrapProviderConfig.Type()), 160 clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()), 161 clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())), 162 wantErr: true, 163 }, 164 { 165 name: "Delete multiple providers of different type", 166 fields: fields{ 167 client: fakeClusterForDelete(), 168 }, 169 args: args{ 170 options: DeleteOptions{ 171 Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, 172 IncludeNamespace: false, 173 IncludeCRDs: false, 174 SkipInventory: false, 175 CoreProvider: capiProviderConfig.Name(), 176 BootstrapProviders: []string{bootstrapProviderConfig.Name()}, 177 InfrastructureProviders: nil, 178 ControlPlaneProviders: nil, 179 DeleteAll: false, 180 }, 181 }, 182 wantProviders: sets.Set[string]{}.Insert( 183 clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()), 184 clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())), 185 wantErr: false, 186 }, 187 } 188 for _, tt := range tests { 189 t.Run(tt.name, func(t *testing.T) { 190 g := NewWithT(t) 191 192 ctx := context.Background() 193 194 err := tt.fields.client.Delete(ctx, tt.args.options) 195 if tt.wantErr { 196 g.Expect(err).To(HaveOccurred()) 197 return 198 } 199 g.Expect(err).ToNot(HaveOccurred()) 200 201 input := cluster.Kubeconfig(tt.args.options.Kubeconfig) 202 proxy := tt.fields.client.clusters[input].Proxy() 203 gotProviders := &clusterctlv1.ProviderList{} 204 205 c, err := proxy.NewClient(ctx) 206 g.Expect(err).ToNot(HaveOccurred()) 207 g.Expect(c.List(ctx, gotProviders)).To(Succeed()) 208 209 gotProvidersSet := sets.Set[string]{} 210 for _, gotProvider := range gotProviders.Items { 211 gotProvidersSet.Insert(gotProvider.Name) 212 } 213 214 g.Expect(gotProvidersSet).To(BeComparableTo(tt.wantProviders)) 215 }) 216 } 217 } 218 219 // clusterctl client for a management cluster with capi and bootstrap provider. 220 func fakeClusterForDelete() *fakeClient { 221 ctx := context.Background() 222 223 config1 := newFakeConfig(ctx). 224 WithVar("var", "value"). 225 WithProvider(capiProviderConfig). 226 WithProvider(bootstrapProviderConfig). 227 WithProvider(controlPlaneProviderConfig). 228 WithProvider(infraProviderConfig) 229 230 repository1 := newFakeRepository(ctx, capiProviderConfig, config1) 231 repository2 := newFakeRepository(ctx, bootstrapProviderConfig, config1) 232 repository3 := newFakeRepository(ctx, controlPlaneProviderConfig, config1) 233 repository4 := newFakeRepository(ctx, infraProviderConfig, config1) 234 235 cluster1 := newFakeCluster(cluster.Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, config1) 236 cluster1.fakeProxy.WithProviderInventory(capiProviderConfig.Name(), capiProviderConfig.Type(), providerVersion, "capi-system") 237 cluster1.fakeProxy.WithProviderInventory(bootstrapProviderConfig.Name(), bootstrapProviderConfig.Type(), providerVersion, "capi-kubeadm-bootstrap-system") 238 cluster1.fakeProxy.WithProviderInventory(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type(), providerVersion, "capi-kubeadm-control-plane-system") 239 cluster1.fakeProxy.WithProviderInventory(infraProviderConfig.Name(), infraProviderConfig.Type(), providerVersion, namespace) 240 cluster1.fakeProxy.WithFakeCAPISetup() 241 242 client := newFakeClient(ctx, config1). 243 // fake repository for capi, bootstrap, controlplane and infra provider (matching provider's config) 244 WithRepository(repository1). 245 WithRepository(repository2). 246 WithRepository(repository3). 247 WithRepository(repository4). 248 // fake empty cluster 249 WithCluster(cluster1) 250 251 return client 252 }