Skip to content

Commit 10a3ead

Browse files
committed
feat: Suspend flux calico helmrelease before cluster delete
1 parent 0e7319e commit 10a3ead

File tree

2 files changed

+124
-59
lines changed

2 files changed

+124
-59
lines changed

pkg/addons/fluxhelmrelease/cni.go

Lines changed: 78 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ import (
2121
"sigs.k8s.io/yaml"
2222
)
2323

24-
// CNIForCluster returns a complete set of Cluster API objects to describe a CNI Configuration
25-
// installable via Flux resources.
26-
func CNIForCluster(cluster *clusterv1.Cluster) ([]unstructured.Unstructured, error) {
27-
vals, _ := yaml.YAMLToJSON([]byte(`
24+
var calicoHelmReleaseValues, _ = yaml.YAMLToJSON([]byte(`
2825
installation:
2926
cni:
3027
type: Calico
@@ -41,6 +38,8 @@ installation:
4138
typhaMetricsPort: 9093
4239
`))
4340

41+
// CNIForCluster returns a set of objects to describe a CNI Configuration installable via Flux resources.
42+
func CNIForCluster(cluster *clusterv1.Cluster) ([]unstructured.Unstructured, error) {
4443
objs := []client.Object{
4544
&corev1.Namespace{
4645
TypeMeta: metav1.TypeMeta{
@@ -64,61 +63,27 @@ installation:
6463
URL: "https://docs.tigera.io/calico/charts",
6564
},
6665
},
67-
&fluxhelmv2beta1.HelmRelease{
68-
TypeMeta: metav1.TypeMeta{
69-
APIVersion: fluxhelmv2beta1.GroupVersion.String(),
70-
Kind: fluxhelmv2beta1.HelmReleaseKind,
71-
},
72-
ObjectMeta: metav1.ObjectMeta{
73-
Name: cluster.Name + "-tigera-operator",
74-
Namespace: cluster.Namespace,
75-
OwnerReferences: []metav1.OwnerReference{{
76-
APIVersion: cluster.APIVersion,
77-
Kind: cluster.Kind,
78-
Name: cluster.Name,
79-
UID: cluster.UID,
80-
Controller: pointer.Bool(true),
81-
}},
82-
},
83-
Spec: fluxhelmv2beta1.HelmReleaseSpec{
84-
KubeConfig: &fluxhelmv2beta1.KubeConfig{
85-
SecretRef: meta.SecretKeyReference{
86-
Name: fmt.Sprintf("%s-kubeconfig", cluster.Name),
87-
Key: "value",
88-
},
89-
},
90-
TargetNamespace: "tigera-operator",
91-
ReleaseName: "tigera-operator",
92-
Chart: fluxhelmv2beta1.HelmChartTemplate{
93-
Spec: fluxhelmv2beta1.HelmChartTemplateSpec{
94-
SourceRef: fluxhelmv2beta1.CrossNamespaceObjectReference{
95-
APIVersion: fluxsourcev1beta2.GroupVersion.String(),
96-
Kind: fluxsourcev1beta2.HelmRepositoryKind,
97-
Namespace: "flux-helmrelease-addons",
98-
Name: "projectcalico",
99-
},
100-
Chart: "tigera-operator",
101-
Version: " v3.25.0",
102-
},
103-
},
104-
Values: &apiextensionsv1.JSON{Raw: vals},
105-
Install: &fluxhelmv2beta1.Install{
106-
CreateNamespace: true,
107-
CRDs: fluxhelmv2beta1.CreateReplace,
108-
Remediation: &fluxhelmv2beta1.InstallRemediation{
109-
Retries: 30,
110-
},
111-
},
112-
Upgrade: &fluxhelmv2beta1.Upgrade{
113-
CRDs: fluxhelmv2beta1.CreateReplace,
114-
Remediation: &fluxhelmv2beta1.UpgradeRemediation{
115-
Retries: 30,
116-
},
117-
},
118-
},
119-
},
66+
calicoHelmReleaseForCluster(cluster),
67+
}
68+
69+
unstrObjs := make([]unstructured.Unstructured, 0, len(objs))
70+
for _, obj := range objs {
71+
unstrObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
72+
if err != nil {
73+
return nil, err
74+
}
75+
unstrObjs = append(unstrObjs, unstructured.Unstructured{Object: unstrObj})
12076
}
12177

78+
return unstrObjs, nil
79+
}
80+
81+
// CNIPatchesForClusterDelete returns a set of patches to apply before cluster deletion.
82+
func CNIPatchesForClusterDelete(cluster *clusterv1.Cluster) ([]unstructured.Unstructured, error) {
83+
hr := calicoHelmReleaseForCluster(cluster)
84+
hr.Spec.Suspend = true
85+
objs := []client.Object{hr}
86+
12287
unstrObjs := make([]unstructured.Unstructured, 0, len(objs))
12388
for _, obj := range objs {
12489
unstrObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
@@ -130,3 +95,59 @@ installation:
13095

13196
return unstrObjs, nil
13297
}
98+
99+
func calicoHelmReleaseForCluster(cluster *clusterv1.Cluster) *fluxhelmv2beta1.HelmRelease {
100+
return &fluxhelmv2beta1.HelmRelease{
101+
TypeMeta: metav1.TypeMeta{
102+
APIVersion: fluxhelmv2beta1.GroupVersion.String(),
103+
Kind: fluxhelmv2beta1.HelmReleaseKind,
104+
},
105+
ObjectMeta: metav1.ObjectMeta{
106+
Name: cluster.Name + "-tigera-operator",
107+
Namespace: cluster.Namespace,
108+
OwnerReferences: []metav1.OwnerReference{{
109+
APIVersion: cluster.APIVersion,
110+
Kind: cluster.Kind,
111+
Name: cluster.Name,
112+
UID: cluster.UID,
113+
Controller: pointer.Bool(true),
114+
}},
115+
},
116+
Spec: fluxhelmv2beta1.HelmReleaseSpec{
117+
KubeConfig: &fluxhelmv2beta1.KubeConfig{
118+
SecretRef: meta.SecretKeyReference{
119+
Name: fmt.Sprintf("%s-kubeconfig", cluster.Name),
120+
Key: "value",
121+
},
122+
},
123+
TargetNamespace: "tigera-operator",
124+
ReleaseName: "tigera-operator",
125+
Chart: fluxhelmv2beta1.HelmChartTemplate{
126+
Spec: fluxhelmv2beta1.HelmChartTemplateSpec{
127+
SourceRef: fluxhelmv2beta1.CrossNamespaceObjectReference{
128+
APIVersion: fluxsourcev1beta2.GroupVersion.String(),
129+
Kind: fluxsourcev1beta2.HelmRepositoryKind,
130+
Namespace: "flux-helmrelease-addons",
131+
Name: "projectcalico",
132+
},
133+
Chart: "tigera-operator",
134+
Version: " v3.25.0",
135+
},
136+
},
137+
Values: &apiextensionsv1.JSON{Raw: calicoHelmReleaseValues},
138+
Install: &fluxhelmv2beta1.Install{
139+
CreateNamespace: true,
140+
CRDs: fluxhelmv2beta1.CreateReplace,
141+
Remediation: &fluxhelmv2beta1.InstallRemediation{
142+
Retries: 30,
143+
},
144+
},
145+
Upgrade: &fluxhelmv2beta1.Upgrade{
146+
CRDs: fluxhelmv2beta1.CreateReplace,
147+
Remediation: &fluxhelmv2beta1.UpgradeRemediation{
148+
Retries: 30,
149+
},
150+
},
151+
},
152+
}
153+
}

pkg/handlers/lifecycle/handlers.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,13 @@ func (m *ExtensionHandlers) DoAfterControlPlaneInitialized(
6464

6565
genericResourcesClient := k8sclient.NewGenericResourcesClient(m.client, log)
6666

67-
err := applyCNICRS(ctx, m.addonProvider, &request.Cluster, genericResourcesClient, m.client)
67+
err := applyCNIResources(
68+
ctx,
69+
m.addonProvider,
70+
&request.Cluster,
71+
genericResourcesClient,
72+
m.client,
73+
)
6874
if err != nil {
6975
response.Status = runtimehooksv1.ResponseStatusFailure
7076
response.Message = err.Error()
@@ -87,9 +93,47 @@ func (m *ExtensionHandlers) DoBeforeClusterDelete(
8793
) {
8894
log := ctrl.LoggerFrom(ctx)
8995
log.Info("BeforeClusterDelete is called")
96+
97+
genericResourcesClient := k8sclient.NewGenericResourcesClient(m.client, log)
98+
99+
err := applyCNIResourcesForDelete(
100+
ctx,
101+
m.addonProvider,
102+
&request.Cluster,
103+
genericResourcesClient,
104+
)
105+
if err != nil {
106+
response.Status = runtimehooksv1.ResponseStatusFailure
107+
response.Message = err.Error()
108+
}
109+
}
110+
111+
func applyCNIResourcesForDelete(
112+
ctx context.Context,
113+
addonProvider AddonProvider,
114+
cluster *v1beta1.Cluster,
115+
genericResourcesClient *k8sclient.GenericResourcesClient,
116+
) error {
117+
var (
118+
err error
119+
objs []unstructured.Unstructured
120+
)
121+
switch addonProvider {
122+
case ClusterResourceSetAddonProvider:
123+
// Nothing to do.
124+
case FluxHelmReleaseAddonProvider:
125+
objs, err = fluxhelmrelease.CNIPatchesForClusterDelete(cluster)
126+
default:
127+
err = fmt.Errorf("unsupported provider: %q", addonProvider)
128+
}
129+
if err != nil {
130+
return err
131+
}
132+
133+
return genericResourcesClient.Apply(ctx, objs...)
90134
}
91135

92-
func applyCNICRS(
136+
func applyCNIResources(
93137
ctx context.Context,
94138
addonProvider AddonProvider,
95139
cluster *v1beta1.Cluster,

0 commit comments

Comments
 (0)