Skip to content

Commit

Permalink
Merge pull request #3617 from gab-satchi/3558-clusterctl-delete
Browse files Browse the repository at this point in the history
🌱 Allows delelting multiple providers at once
  • Loading branch information
k8s-ci-robot committed Sep 14, 2020
2 parents dd5a68d + b315908 commit cd8ac05
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 32 deletions.
24 changes: 9 additions & 15 deletions cmd/clusterctl/client/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ func (c *clusterctlClient) Delete(options DeleteOptions) error {

if options.DeleteAll {
providersToDelete = installedProviders.Items
if options.Namespace != "" {
// Delete only the providers in the specified namespace
providersToDelete = []clusterctlv1.Provider{}
for _, provider := range installedProviders.Items {
if provider.Namespace == options.Namespace {
providersToDelete = append(providersToDelete, provider)
}
}
}
} else {
// Otherwise we are deleting only a subset of providers.
var providers []clusterctlv1.Provider
Expand Down Expand Up @@ -111,21 +120,6 @@ func (c *clusterctlClient) Delete(options DeleteOptions) error {
}
}

// Check the provider/type/namespace tuple actually matches one of the installed provider instances.
found := false
for _, ip := range installedProviders.Items {
if ip.InstanceName() == provider.InstanceName() {
found = true
providersToDelete = append(providersToDelete, ip)
break
}
}
if found {
break
}

// In case the provider does not match any installed providers, we still force deletion
// so the user can do 'delete' without removing CRD and after some time 'delete --delete-crd' (same for the namespace).
providersToDelete = append(providersToDelete, provider)
}
}
Expand Down
88 changes: 71 additions & 17 deletions cmd/clusterctl/client/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"sigs.k8s.io/cluster-api/cmd/clusterctl/client/cluster"
)

var namespace = "foobar"

func Test_clusterctlClient_Delete(t *testing.T) {
type fields struct {
client *fakeClient
Expand Down Expand Up @@ -80,8 +82,11 @@ func Test_clusterctlClient_Delete(t *testing.T) {
DeleteAll: false,
},
},
wantProviders: sets.NewString(capiProviderConfig.Name()),
wantErr: false,
wantProviders: sets.NewString(
capiProviderConfig.Name(),
clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()),
clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())),
wantErr: false,
},
{
name: "Delete single provider auto-detect namespace",
Expand All @@ -101,8 +106,57 @@ func Test_clusterctlClient_Delete(t *testing.T) {
DeleteAll: false,
},
},
wantProviders: sets.NewString(capiProviderConfig.Name()),
wantErr: false,
wantProviders: sets.NewString(
capiProviderConfig.Name(),
clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()),
clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())),
wantErr: false,
},
{
name: "Delete multiple providers of different type",
fields: fields{
client: fakeClusterForDelete(),
},
args: args{
options: DeleteOptions{
Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"},
IncludeNamespace: false,
IncludeCRDs: false,
Namespace: "", // empty namespace triggers namespace auto detection
CoreProvider: capiProviderConfig.Name(),
BootstrapProviders: []string{bootstrapProviderConfig.Name()},
InfrastructureProviders: nil,
ControlPlaneProviders: nil,
DeleteAll: false,
},
},
wantProviders: sets.NewString(
clusterctlv1.ManifestLabel(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type()),
clusterctlv1.ManifestLabel(infraProviderConfig.Name(), infraProviderConfig.Type())),
wantErr: false,
},
{
name: "Delete all providers in a namespace",
fields: fields{
client: fakeClusterForDelete(),
},
args: args{
options: DeleteOptions{
Kubeconfig: Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"},
IncludeNamespace: false,
IncludeCRDs: false,
Namespace: namespace,
CoreProvider: "",
BootstrapProviders: nil,
InfrastructureProviders: nil,
ControlPlaneProviders: nil,
DeleteAll: true,
},
},
wantProviders: sets.NewString(
capiProviderConfig.Name(),
clusterctlv1.ManifestLabel(bootstrapProviderConfig.Name(), bootstrapProviderConfig.Type())),
wantErr: false,
},
}
for _, tt := range tests {
Expand Down Expand Up @@ -139,27 +193,27 @@ func fakeClusterForDelete() *fakeClient {
config1 := newFakeConfig().
WithVar("var", "value").
WithProvider(capiProviderConfig).
WithProvider(bootstrapProviderConfig)

repository1 := newFakeRepository(capiProviderConfig, config1).
WithPaths("root", "components.yaml").
WithDefaultVersion("v1.0.0").
WithFile("v1.0.0", "components.yaml", componentsYAML("ns1")).
WithFile("v1.1.0", "components.yaml", componentsYAML("ns1"))
repository2 := newFakeRepository(bootstrapProviderConfig, config1).
WithPaths("root", "components.yaml").
WithDefaultVersion("v2.0.0").
WithFile("v2.0.0", "components.yaml", componentsYAML("ns2")).
WithFile("v2.1.0", "components.yaml", componentsYAML("ns2"))
WithProvider(bootstrapProviderConfig).
WithProvider(controlPlaneProviderConfig).
WithProvider(infraProviderConfig)

repository1 := newFakeRepository(capiProviderConfig, config1)
repository2 := newFakeRepository(bootstrapProviderConfig, config1)
repository3 := newFakeRepository(controlPlaneProviderConfig, config1)
repository4 := newFakeRepository(infraProviderConfig, config1)

cluster1 := newFakeCluster(cluster.Kubeconfig{Path: "kubeconfig", Context: "mgmt-context"}, config1)
cluster1.fakeProxy.WithProviderInventory(capiProviderConfig.Name(), capiProviderConfig.Type(), "v1.0.0", "capi-system", "")
cluster1.fakeProxy.WithProviderInventory(bootstrapProviderConfig.Name(), bootstrapProviderConfig.Type(), "v1.0.0", "capbpk-system", "")
cluster1.fakeProxy.WithProviderInventory(controlPlaneProviderConfig.Name(), controlPlaneProviderConfig.Type(), "v1.0.0", namespace, "")
cluster1.fakeProxy.WithProviderInventory(infraProviderConfig.Name(), infraProviderConfig.Type(), "v1.0.0", namespace, "")

client := newFakeClient(config1).
// fake repository for capi, bootstrap and infra provider (matching provider's config)
// fake repository for capi, bootstrap, controlplane and infra provider (matching provider's config)
WithRepository(repository1).
WithRepository(repository2).
WithRepository(repository3).
WithRepository(repository4).
// fake empty cluster
WithCluster(cluster1)

Expand Down
12 changes: 12 additions & 0 deletions cmd/clusterctl/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ var deleteCmd = &cobra.Command{
# Cluster API Providers are orphaned and there might be ongoing costs incurred as a result of this.
clusterctl delete --all
# Deletes all the providers in a namespace
# Important! As a consequence of this operation, all the corresponding resources managed by
# Cluster API Providers are orphaned and there might be ongoing costs incurred as a result of this.
clusterctl delete --all --namespace=foo
# Delete the AWS infrastructure provider and Core provider. This will leave behind Bootstrap and ControlPlane
# providers
# Important! As a consequence of this operation, all the corresponding resources managed by
# the AWS infrastructure provider and Cluster API Providers are orphaned and there might be
# ongoing costs incurred as a result of this.
clusterctl delete --core cluster-api --infrastructure aws
# Delete the AWS infrastructure provider and related CRDs. Please note that this forces deletion of
# all the related objects (e.g. AWSClusters, AWSMachines etc.).
# Important! As a consequence of this operation, all the corresponding resources managed by
Expand Down

0 comments on commit cd8ac05

Please sign in to comment.