Skip to content

Commit 9953aa9

Browse files
authored
ACM-10165 Fix KubeVirt bulk destroy (stolostron#3642)
* Fix KubeVirt bulk destroy Signed-off-by: fxiang1 <fxiang@redhat.com> * Fix unit test Signed-off-by: fxiang1 <fxiang@redhat.com> * Add unit test Signed-off-by: fxiang1 <fxiang@redhat.com> --------- Signed-off-by: fxiang1 <fxiang@redhat.com>
1 parent 1028189 commit 9953aa9

File tree

2 files changed

+290
-8
lines changed

2 files changed

+290
-8
lines changed

frontend/src/lib/delete-cluster.test.ts

+248-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
InfraEnvKind,
1313
ManagedClusterApiVersion,
1414
ManagedClusterKind,
15+
NodePoolApiVersion,
16+
NodePoolKind,
1517
SecretApiVersion,
1618
SecretKind,
1719
} from '../resources'
@@ -137,7 +139,7 @@ const mockCluster3: Cluster = {
137139
isManaged: true,
138140
isCurator: true,
139141
hasAutomationTemplate: false,
140-
isHostedCluster: true,
142+
isHostedCluster: false,
141143
isHypershift: false,
142144
isSNOCluster: false,
143145
owner: {},
@@ -146,6 +148,198 @@ const mockCluster3: Cluster = {
146148
isRegionalHubCluster: false,
147149
}
148150

151+
const mockHostedCluster: Cluster = {
152+
name: 'hosted-cluster1',
153+
displayName: 'hosted-cluster1',
154+
namespace: 'clusters',
155+
uid: 'hosted-cluster1-uid',
156+
provider: Provider.kubevirt,
157+
status: ClusterStatus.ready,
158+
distribution: {
159+
ocp: {
160+
version: '4.11.12',
161+
availableUpdates: [],
162+
desiredVersion: '4.11.12',
163+
upgradeFailed: false,
164+
},
165+
isManagedOpenShift: false,
166+
},
167+
labels: { abc: '123' },
168+
nodes: undefined,
169+
kubeApiServer: '',
170+
consoleURL: '',
171+
hive: {
172+
isHibernatable: false,
173+
clusterPool: undefined,
174+
secrets: {
175+
installConfig: '',
176+
},
177+
},
178+
hypershift: {
179+
agent: false,
180+
hostingNamespace: 'clusters',
181+
nodePools: [
182+
{
183+
apiVersion: 'hypershift.openshift.io/v1beta1',
184+
kind: 'NodePool',
185+
metadata: {
186+
annotations: {
187+
'hypershift.openshift.io/nodePoolCurrentConfig': '814967cb',
188+
'hypershift.openshift.io/nodePoolCurrentConfigVersion': '0e8b8078',
189+
'hypershift.openshift.io/nodePoolPlatformMachineTemplate': 'hosted-cluster1-304faa18',
190+
},
191+
finalizers: ['hypershift.openshift.io/finalizer'],
192+
labels: {
193+
'hypershift.openshift.io/auto-created-for-infra': 'hosted-cluster1-qvl8m',
194+
},
195+
name: 'hosted-cluster1-nodepool',
196+
namespace: 'clusters',
197+
},
198+
spec: {
199+
clusterName: 'hosted-cluster1',
200+
management: {
201+
autoRepair: false,
202+
replace: {
203+
rollingUpdate: {
204+
maxSurge: 1,
205+
maxUnavailable: 0,
206+
},
207+
strategy: 'RollingUpdate',
208+
},
209+
upgradeType: 'Replace',
210+
},
211+
platform: {
212+
aws: {
213+
instanceProfile: 'test',
214+
instanceType: 'test',
215+
rootVolume: {
216+
size: 10,
217+
type: 'Persistent',
218+
},
219+
securityGroups: [],
220+
subnet: {
221+
id: 'string',
222+
},
223+
},
224+
type: 'AWS',
225+
},
226+
release: {
227+
image: 'quay.io/openshift-release-dev/ocp-release:4.15.10-x86_64',
228+
},
229+
replicas: 2,
230+
},
231+
status: {
232+
conditions: [
233+
{
234+
lastTransitionTime: '2024-06-14T15:55:12Z',
235+
observedGeneration: 1,
236+
reason: 'AsExpected',
237+
status: 'False',
238+
type: 'AutoscalingEnabled',
239+
},
240+
{
241+
lastTransitionTime: '2024-06-14T15:55:12Z',
242+
observedGeneration: 1,
243+
reason: 'AsExpected',
244+
status: 'True',
245+
type: 'UpdateManagementEnabled',
246+
},
247+
{
248+
lastTransitionTime: '2024-06-18T00:17:55Z',
249+
message: 'Using release image: quay.io/openshift-release-dev/ocp-release:4.15.10-x86_64',
250+
observedGeneration: 1,
251+
reason: 'AsExpected',
252+
status: 'True',
253+
type: 'ValidReleaseImage',
254+
},
255+
{
256+
lastTransitionTime: '2024-06-14T15:58:54Z',
257+
message: 'Payload generated successfully',
258+
observedGeneration: 1,
259+
reason: 'AsExpected',
260+
status: 'True',
261+
type: 'ValidGeneratedPayload',
262+
},
263+
{
264+
lastTransitionTime: '2024-06-14T15:59:47Z',
265+
observedGeneration: 1,
266+
reason: 'AsExpected',
267+
status: 'True',
268+
type: 'ReachedIgnitionEndpoint',
269+
},
270+
{
271+
lastTransitionTime: '2024-06-14T15:57:52Z',
272+
observedGeneration: 1,
273+
reason: 'AsExpected',
274+
status: 'True',
275+
type: 'ValidTuningConfig',
276+
},
277+
{
278+
lastTransitionTime: '2024-06-14T15:57:52Z',
279+
message: 'Reconciliation active on resource',
280+
observedGeneration: 1,
281+
reason: 'ReconciliationActive',
282+
status: 'True',
283+
type: 'ReconciliationActive',
284+
},
285+
{
286+
lastTransitionTime: '2024-07-10T07:58:00Z',
287+
message: 'All is well',
288+
observedGeneration: 1,
289+
reason: 'AsExpected',
290+
status: 'True',
291+
type: 'AllMachinesReady',
292+
},
293+
{
294+
lastTransitionTime: '2024-06-14T16:07:05Z',
295+
message: 'All is well',
296+
observedGeneration: 1,
297+
reason: 'AsExpected',
298+
status: 'True',
299+
type: 'AllNodesHealthy',
300+
},
301+
{
302+
lastTransitionTime: '2024-06-14T15:57:52Z',
303+
observedGeneration: 1,
304+
reason: 'AsExpected',
305+
status: 'False',
306+
type: 'AutorepairEnabled',
307+
},
308+
{
309+
lastTransitionTime: '2024-06-14T16:07:05Z',
310+
observedGeneration: 1,
311+
reason: 'AsExpected',
312+
status: 'True',
313+
type: 'Ready',
314+
},
315+
{
316+
lastTransitionTime: '2024-07-10T15:39:26Z',
317+
observedGeneration: 1,
318+
reason: 'AsExpected',
319+
status: 'True',
320+
type: 'ValidMachineConfig',
321+
},
322+
],
323+
replicas: 2,
324+
version: '4.15.10',
325+
},
326+
},
327+
],
328+
secretNames: ['secret1'],
329+
},
330+
isHive: false,
331+
isManaged: true,
332+
isCurator: true,
333+
hasAutomationTemplate: false,
334+
isHostedCluster: true,
335+
isHypershift: true,
336+
isSNOCluster: false,
337+
owner: {},
338+
kubeadmin: '',
339+
kubeconfig: '',
340+
isRegionalHubCluster: false,
341+
}
342+
149343
const getDetatchNocks = (name: string, namespace: string) => [
150344
nockPatch(
151345
{
@@ -372,3 +566,56 @@ describe('deleteCluster', () => {
372566
await waitForNocks(deleteNocks)
373567
})
374568
})
569+
570+
const deleteHostedClusterNocks = () => [
571+
nockDelete({
572+
apiVersion: ManagedClusterApiVersion,
573+
kind: ManagedClusterKind,
574+
metadata: {
575+
name: mockHostedCluster.name,
576+
},
577+
}),
578+
nockDelete({
579+
apiVersion: HostedClusterApiVersion,
580+
kind: HostedClusterKind,
581+
metadata: {
582+
name: mockHostedCluster.name,
583+
namespace: mockHostedCluster.namespace,
584+
},
585+
}),
586+
nockDelete({
587+
apiVersion: NodePoolApiVersion,
588+
kind: NodePoolKind,
589+
metadata: {
590+
name: 'hosted-cluster1-nodepool',
591+
namespace: 'clusters',
592+
},
593+
}),
594+
nockDelete({
595+
apiVersion: SecretApiVersion,
596+
kind: SecretKind,
597+
metadata: {
598+
name: 'secret1',
599+
namespace: 'clusters',
600+
},
601+
}),
602+
]
603+
604+
describe('deleteCluster hostedcluster', () => {
605+
beforeEach(() => {
606+
jest.clearAllMocks()
607+
nockIgnoreApiPaths()
608+
})
609+
610+
it('delete Hosted cluster', async () => {
611+
const nocks = deleteHostedClusterNocks()
612+
deleteCluster({
613+
cluster: mockHostedCluster,
614+
deletePullSecret: false,
615+
infraEnvs: [],
616+
ignoreClusterDeploymentNotFound: true,
617+
})
618+
619+
await waitForNocks(nocks)
620+
})
621+
})

frontend/src/lib/delete-cluster.ts

+42-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
IResource,
1616
ManagedClusterApiVersion,
1717
ManagedClusterKind,
18+
NodePoolApiVersion,
19+
NodePoolKind,
1820
patchResource,
1921
ResourceError,
2022
ResourceErrorCode,
@@ -39,13 +41,15 @@ export function deleteCluster({
3941
let resources: IResource[] = []
4042

4143
if (clusterDestroyable(cluster)) {
42-
resources = [
43-
{
44-
apiVersion: ClusterDeploymentApiVersion,
45-
kind: ClusterDeploymentKind,
46-
metadata: { name: cluster.name!, namespace: cluster.namespace! },
47-
},
48-
]
44+
resources = !(cluster.isHypershift || cluster.isHostedCluster)
45+
? [
46+
{
47+
apiVersion: ClusterDeploymentApiVersion,
48+
kind: ClusterDeploymentKind,
49+
metadata: { name: cluster.name!, namespace: cluster.namespace! },
50+
},
51+
]
52+
: []
4953
if (cluster.isManaged) {
5054
resources.push({
5155
apiVersion: ManagedClusterApiVersion,
@@ -75,6 +79,37 @@ export function deleteCluster({
7579
})
7680
}
7781

82+
// clean up Hypershift artifacts
83+
if (cluster.isHostedCluster || cluster.isHypershift) {
84+
resources.push({
85+
apiVersion: HostedClusterApiVersion,
86+
kind: HostedClusterKind,
87+
metadata: {
88+
name: cluster.name,
89+
namespace: cluster.namespace,
90+
},
91+
})
92+
93+
cluster.hypershift?.nodePools?.forEach((np) => {
94+
resources.push({
95+
apiVersion: NodePoolApiVersion,
96+
kind: NodePoolKind,
97+
metadata: {
98+
name: np.metadata?.name,
99+
namespace: cluster.namespace,
100+
},
101+
})
102+
})
103+
104+
cluster.hypershift?.secretNames?.forEach((name) => {
105+
resources.push({
106+
apiVersion: SecretApiVersion,
107+
kind: SecretKind,
108+
metadata: { name, namespace: cluster.namespace },
109+
})
110+
})
111+
}
112+
78113
if (cluster.provider === Provider.hostinventory) {
79114
const infraEnv = infraEnvs.find((ie) => {
80115
const clusterRef = ie.spec?.clusterRef

0 commit comments

Comments
 (0)