Skip to content

Commit f02776a

Browse files
committed
test: add "upgrade plan" tests
1 parent 8b61e23 commit f02776a

File tree

2 files changed

+195
-22
lines changed

2 files changed

+195
-22
lines changed

cmd/plugin/cmd/upgrade_plan.go

+16-22
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
3232
"sigs.k8s.io/cluster-api/cmd/clusterctl/client/cluster"
3333
configclient "sigs.k8s.io/cluster-api/cmd/clusterctl/client/config"
34+
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
3435

3536
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
3637
"sigs.k8s.io/cluster-api-operator/util"
@@ -123,6 +124,11 @@ func runUpgradePlan() error {
123124
upgradePlanOpts.kubeconfig = GetKubeconfigLocation()
124125
}
125126

127+
client, err := CreateKubeClient(upgradePlanOpts.kubeconfig, upgradePlanOpts.kubeconfigContext)
128+
if err != nil {
129+
return fmt.Errorf("cannot create a client: %w", err)
130+
}
131+
126132
certManUpgradePlan, err := planCertManagerUpgrade(ctx, upgradePlanOpts)
127133
if err != nil {
128134
return err
@@ -138,7 +144,7 @@ func runUpgradePlan() error {
138144
log.Info("There are no managed Cert-Manager installations found")
139145
}
140146

141-
capiOperatorUpgradePlan, err := planCAPIOperatorUpgrade(ctx, upgradePlanOpts)
147+
capiOperatorUpgradePlan, err := planCAPIOperatorUpgrade(ctx, client)
142148
if err != nil {
143149
return err
144150
}
@@ -153,7 +159,7 @@ func runUpgradePlan() error {
153159
log.Info("CAPI operator is not managed by the plugin and won't be modified during upgrade")
154160
}
155161

156-
upgradePlan, err := planUpgrade(ctx)
162+
upgradePlan, err := planUpgrade(ctx, client)
157163
if err != nil {
158164
return err
159165
}
@@ -233,16 +239,11 @@ func planCertManagerUpgrade(ctx context.Context, opts *upgradePlanOptions) (cert
233239
}, nil
234240
}
235241

236-
func planCAPIOperatorUpgrade(ctx context.Context, opts *upgradePlanOptions) (capiOperatorUpgradePlan, error) {
242+
func planCAPIOperatorUpgrade(ctx context.Context, client ctrlclient.Client) (capiOperatorUpgradePlan, error) {
237243
upgradePlan := capiOperatorUpgradePlan{}
238244

239245
log.Info("Checking CAPI Operator version...")
240246

241-
client, err := CreateKubeClient(opts.kubeconfig, opts.kubeconfigContext)
242-
if err != nil {
243-
return upgradePlan, fmt.Errorf("cannot create a client: %w", err)
244-
}
245-
246247
capiOperatorDeployment, err := GetDeploymentByLabels(ctx, client, capiOperatorLabels)
247248
if err != nil {
248249
return upgradePlan, fmt.Errorf("cannot get CAPI operator deployment: %w", err)
@@ -294,12 +295,8 @@ func isCAPIOperatorExternallyManaged(deployment *appsv1.Deployment) bool {
294295
return deployment.Labels[clusterv1.ProviderNameLabel] != capiOperatorProviderName
295296
}
296297

297-
func planUpgrade(ctx context.Context) (upgradePlan, error) {
298-
if initOpts.kubeconfig == "" {
299-
initOpts.kubeconfig = GetKubeconfigLocation()
300-
}
301-
302-
genericProviders, contract, err := getInstalledProviders(ctx)
298+
func planUpgrade(ctx context.Context, client ctrlclient.Client) (upgradePlan, error) {
299+
genericProviders, contract, err := getInstalledProviders(ctx, client)
303300
if err != nil {
304301
return upgradePlan{}, fmt.Errorf("cannot get installed providers: %w", err)
305302
}
@@ -343,16 +340,11 @@ func planUpgrade(ctx context.Context) (upgradePlan, error) {
343340
return upgradePlan{Contract: contract, Providers: upgradeItems}, nil
344341
}
345342

346-
func getInstalledProviders(ctx context.Context) ([]operatorv1.GenericProvider, string, error) {
347-
client, err := CreateKubeClient(initOpts.kubeconfig, initOpts.kubeconfigContext)
348-
if err != nil {
349-
return nil, "", fmt.Errorf("cannot create a client: %w", err)
350-
}
351-
343+
func getInstalledProviders(ctx context.Context, client ctrlclient.Client) ([]operatorv1.GenericProvider, string, error) {
352344
// Iterate through installed providers and create a list of upgrade plans.
353345
genericProviders := []operatorv1.GenericProvider{}
354346

355-
var contract string
347+
contract := "v1beta1"
356348

357349
// Get Core Providers.
358350
var coreProviderList operatorv1.CoreProviderList
@@ -361,9 +353,11 @@ func getInstalledProviders(ctx context.Context) ([]operatorv1.GenericProvider, s
361353
return nil, "", fmt.Errorf("cannot get a list of core providers from the server: %w", err)
362354
}
363355

364-
for i := range coreProviderList.Items {
356+
if len(coreProviderList.Items) == 1 && coreProviderList.Items[0].Status.Contract != nil {
365357
contract = *coreProviderList.Items[0].Status.Contract
358+
}
366359

360+
for i := range coreProviderList.Items {
367361
genericProviders = append(genericProviders, &coreProviderList.Items[i])
368362
}
369363

cmd/plugin/cmd/upgrade_plan_test.go

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
Copyright 2024 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 cmd
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/gomega"
23+
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
24+
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
25+
26+
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
27+
"sigs.k8s.io/cluster-api-operator/internal/controller/genericprovider"
28+
"sigs.k8s.io/cluster-api-operator/util"
29+
)
30+
31+
func TestUpgradePlan(t *testing.T) {
32+
tests := []struct {
33+
name string
34+
opts *initOptions
35+
customURL string
36+
wantedUpgradePlan upgradePlan
37+
wantedProviders []genericprovider.GenericProvider
38+
wantErr bool
39+
}{
40+
{
41+
name: "no providers",
42+
wantedUpgradePlan: upgradePlan{
43+
Contract: "v1beta1",
44+
Providers: []upgradeItem{},
45+
},
46+
wantErr: false,
47+
opts: &initOptions{},
48+
},
49+
{
50+
name: "builtin core provider",
51+
wantedUpgradePlan: upgradePlan{
52+
Contract: "v1beta1",
53+
Providers: []upgradeItem{
54+
{
55+
Name: "cluster-api",
56+
Namespace: "capi-system",
57+
Type: "core",
58+
CurrentVersion: "v1.6.0",
59+
Source: "https://github.com/kubernetes-sigs/cluster-api/releases/latest/core-components.yaml",
60+
SourceType: providerSourceTypeBuiltin,
61+
},
62+
},
63+
},
64+
wantedProviders: []genericprovider.GenericProvider{
65+
generateGenericProvider(clusterctlv1.CoreProviderType, "cluster-api", "capi-system", "v1.6.0", "", ""),
66+
},
67+
wantErr: false,
68+
opts: &initOptions{
69+
coreProvider: "cluster-api:capi-system:v1.6.0",
70+
targetNamespace: "capi-operator-system",
71+
},
72+
},
73+
{
74+
name: "custom infra provider",
75+
customURL: "https://github.com/kubernetes-sigs/cluster-api/releases/latest/core-components.yaml",
76+
wantedUpgradePlan: upgradePlan{
77+
Contract: "v1beta1",
78+
Providers: []upgradeItem{
79+
{
80+
Name: "docker",
81+
Namespace: "capi-system",
82+
Type: "infrastructure",
83+
CurrentVersion: "v1.6.0",
84+
Source: "https://github.com/kubernetes-sigs/cluster-api/releases/latest/core-components.yaml",
85+
SourceType: providerSourceTypeCustomURL,
86+
},
87+
},
88+
},
89+
wantedProviders: []genericprovider.GenericProvider{
90+
generateGenericProvider(clusterctlv1.InfrastructureProviderType, "docker", "capi-system", "v1.6.0", "", ""),
91+
},
92+
wantErr: false,
93+
opts: &initOptions{
94+
infrastructureProviders: []string{"docker:capi-system:v1.6.0"},
95+
targetNamespace: "capi-operator-system",
96+
},
97+
},
98+
}
99+
for _, tt := range tests {
100+
t.Run(tt.name, func(t *testing.T) {
101+
g := NewWithT(t)
102+
103+
resources := []ctrlclient.Object{}
104+
105+
for _, provider := range tt.wantedProviders {
106+
resources = append(resources, provider)
107+
}
108+
109+
err := initProviders(ctx, env, tt.opts)
110+
if tt.wantErr {
111+
g.Expect(err).To(HaveOccurred())
112+
113+
return
114+
} else {
115+
g.Expect(err).NotTo(HaveOccurred())
116+
}
117+
118+
for _, genericProvider := range tt.wantedProviders {
119+
g.Eventually(func() (bool, error) {
120+
provider, err := getGenericProvider(ctx, env, string(util.ClusterctlProviderType(genericProvider)), genericProvider.GetName(), genericProvider.GetNamespace())
121+
if err != nil {
122+
return false, err
123+
}
124+
125+
if provider.GetSpec().Version != genericProvider.GetSpec().Version {
126+
return false, nil
127+
}
128+
129+
return true, nil
130+
}, waitShort).Should(BeTrue())
131+
}
132+
133+
// Init doesn't support custom URLs yet, so we have to update providers here
134+
if tt.customURL != "" {
135+
for _, genericProvider := range tt.wantedProviders {
136+
provider, err := getGenericProvider(ctx, env, string(util.ClusterctlProviderType(genericProvider)), genericProvider.GetName(), genericProvider.GetNamespace())
137+
g.Expect(err).NotTo(HaveOccurred())
138+
139+
spec := provider.GetSpec()
140+
spec.FetchConfig = &operatorv1.FetchConfiguration{
141+
URL: tt.customURL,
142+
}
143+
144+
provider.SetSpec(spec)
145+
146+
g.Expect(env.Update(ctx, provider)).NotTo(HaveOccurred())
147+
148+
g.Eventually(func() (bool, error) {
149+
provider, err := getGenericProvider(ctx, env, string(util.ClusterctlProviderType(genericProvider)), genericProvider.GetName(), genericProvider.GetNamespace())
150+
if err != nil {
151+
return false, err
152+
}
153+
154+
if provider.GetSpec().FetchConfig == nil || provider.GetSpec().FetchConfig.URL != tt.customURL {
155+
return false, nil
156+
}
157+
158+
return true, nil
159+
}, waitShort).Should(BeTrue())
160+
}
161+
}
162+
163+
// Run upgrade plan
164+
upgradePlan, err := planUpgrade(ctx, env)
165+
g.Expect(err).NotTo(HaveOccurred())
166+
167+
for i, provider := range upgradePlan.Providers {
168+
g.Expect(provider.Name).To(Equal(tt.wantedUpgradePlan.Providers[i].Name))
169+
g.Expect(provider.Namespace).To(Equal(tt.wantedUpgradePlan.Providers[i].Namespace))
170+
g.Expect(provider.Type).To(Equal(tt.wantedUpgradePlan.Providers[i].Type))
171+
g.Expect(provider.CurrentVersion).To(Equal(tt.wantedUpgradePlan.Providers[i].CurrentVersion))
172+
g.Expect(provider.Source).To(Equal(tt.wantedUpgradePlan.Providers[i].Source))
173+
g.Expect(provider.SourceType).To(Equal(tt.wantedUpgradePlan.Providers[i].SourceType))
174+
}
175+
176+
g.Expect(env.CleanupAndWait(ctx, resources...)).To(Succeed())
177+
})
178+
}
179+
}

0 commit comments

Comments
 (0)