Skip to content

Commit 84359ef

Browse files
authored
Merge pull request #6533 from abhi0324/add-UnitedDeployment
feat: add resource interpreter customization for UnitedDeployment
2 parents 95802b0 + 7bf8413 commit 84359ef

File tree

5 files changed

+313
-0
lines changed

5 files changed

+313
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
apiVersion: config.karmada.io/v1alpha1
2+
kind: ResourceInterpreterCustomization
3+
metadata:
4+
name: declarative-configuration-uniteddeployment
5+
spec:
6+
target:
7+
apiVersion: apps.kruise.io/v1alpha1
8+
kind: UnitedDeployment
9+
customizations:
10+
replicaResource:
11+
luaScript: >
12+
local kube = require("kube")
13+
function GetReplicas(obj)
14+
local replica = obj.spec.replicas
15+
local requirement = kube.accuratePodRequirements(obj.spec.template)
16+
return replica, requirement
17+
end
18+
replicaRevision:
19+
luaScript: >
20+
function ReviseReplica(obj, desiredReplica)
21+
obj.spec.replicas = desiredReplica
22+
return obj
23+
end
24+
statusAggregation:
25+
luaScript: >
26+
function AggregateStatus(desiredObj, statusItems)
27+
if desiredObj.status == nil then
28+
desiredObj.status = {}
29+
end
30+
if desiredObj.metadata.generation == nil then
31+
desiredObj.metadata.generation = 0
32+
end
33+
if desiredObj.status.observedGeneration == nil then
34+
desiredObj.status.observedGeneration = 0
35+
end
36+
37+
-- Initialize status fields if status does not exist
38+
-- If the UnitedDeployment is not spread to any cluster,
39+
-- its status also should be aggregated
40+
if statusItems == nil then
41+
desiredObj.status.observedGeneration = desiredObj.metadata.generation
42+
desiredObj.status.replicas = 0
43+
desiredObj.status.readyReplicas = 0
44+
desiredObj.status.updatedReplicas = 0
45+
desiredObj.status.availableReplicas = 0
46+
desiredObj.status.unavailableReplicas = 0
47+
return desiredObj
48+
end
49+
50+
local generation = desiredObj.metadata.generation
51+
local observedGeneration = desiredObj.status.observedGeneration
52+
local replicas = 0
53+
local updatedReplicas = 0
54+
local readyReplicas = 0
55+
local availableReplicas = 0
56+
local unavailableReplicas = 0
57+
58+
-- Use a map to merge conditions by type
59+
local conditionsMap = {}
60+
61+
-- Count all members that their status is updated to the latest generation
62+
local observedResourceTemplateGenerationCount = 0
63+
64+
for i = 1, #statusItems do
65+
local itemStatus = statusItems[i].status
66+
if itemStatus ~= nil then
67+
replicas = replicas + (itemStatus.replicas or 0)
68+
updatedReplicas = updatedReplicas + (itemStatus.updatedReplicas or 0)
69+
readyReplicas = readyReplicas + (itemStatus.readyReplicas or 0)
70+
availableReplicas = availableReplicas + (itemStatus.availableReplicas or 0)
71+
unavailableReplicas = unavailableReplicas + (itemStatus.unavailableReplicas or 0)
72+
73+
-- Merge conditions from all clusters using a map
74+
if itemStatus.conditions ~= nil then
75+
for _, condition in ipairs(itemStatus.conditions) do
76+
conditionsMap[condition.type] = condition
77+
end
78+
end
79+
80+
-- Check if the member's status is updated to the latest generation
81+
local resourceTemplateGeneration = itemStatus.resourceTemplateGeneration or 0
82+
local memberGeneration = itemStatus.generation or 0
83+
local memberObservedGeneration = itemStatus.observedGeneration or 0
84+
if resourceTemplateGeneration == generation and memberGeneration == memberObservedGeneration then
85+
observedResourceTemplateGenerationCount = observedResourceTemplateGenerationCount + 1
86+
end
87+
end
88+
end
89+
90+
-- Convert conditionsMap back to a list
91+
local conditions = {}
92+
for _, condition in pairs(conditionsMap) do
93+
table.insert(conditions, condition)
94+
end
95+
96+
-- Update the observed generation based on the observedResourceTemplateGenerationCount
97+
if observedResourceTemplateGenerationCount == #statusItems then
98+
desiredObj.status.observedGeneration = generation
99+
else
100+
desiredObj.status.observedGeneration = observedGeneration
101+
end
102+
103+
desiredObj.status.replicas = replicas
104+
desiredObj.status.updatedReplicas = updatedReplicas
105+
desiredObj.status.readyReplicas = readyReplicas
106+
desiredObj.status.availableReplicas = availableReplicas
107+
desiredObj.status.unavailableReplicas = unavailableReplicas
108+
109+
if #conditions > 0 then
110+
desiredObj.status.conditions = conditions
111+
end
112+
113+
return desiredObj
114+
end
115+
statusReflection:
116+
luaScript: >
117+
function ReflectStatus(observedObj)
118+
local status = {}
119+
if observedObj == nil or observedObj.status == nil then
120+
return status
121+
end
122+
123+
status.replicas = observedObj.status.replicas
124+
status.updatedReplicas = observedObj.status.updatedReplicas
125+
status.readyReplicas = observedObj.status.readyReplicas
126+
status.availableReplicas = observedObj.status.availableReplicas
127+
status.unavailableReplicas = observedObj.status.unavailableReplicas
128+
status.observedGeneration = observedObj.status.observedGeneration
129+
status.conditions = observedObj.status.conditions
130+
131+
-- handle member resource generation report
132+
if observedObj.metadata ~= nil then
133+
status.generation = observedObj.metadata.generation
134+
135+
-- handle resource template generation report
136+
if observedObj.metadata.annotations ~= nil then
137+
local resourceTemplateGeneration = tonumber(observedObj.metadata.annotations["resourcetemplate.karmada.io/generation"])
138+
if resourceTemplateGeneration ~= nil then
139+
status.resourceTemplateGeneration = resourceTemplateGeneration
140+
end
141+
end
142+
end
143+
144+
return status
145+
end
146+
healthInterpretation:
147+
luaScript: >
148+
function InterpretHealth(observedObj)
149+
if observedObj == nil or observedObj.status == nil or observedObj.metadata == nil or observedObj.spec == nil then
150+
return false
151+
end
152+
if observedObj.status.observedGeneration ~= observedObj.metadata.generation then
153+
return false
154+
end
155+
if observedObj.spec.replicas ~= nil then
156+
if observedObj.status.updatedReplicas < observedObj.spec.replicas then
157+
return false
158+
end
159+
end
160+
if observedObj.status.availableReplicas < observedObj.status.updatedReplicas then
161+
return false
162+
end
163+
return true
164+
end
165+
dependencyInterpretation:
166+
luaScript: >
167+
local kube = require("kube")
168+
function GetDependencies(desiredObj)
169+
local refs = kube.getPodDependencies(desiredObj.spec.template, desiredObj.metadata.namespace)
170+
return refs
171+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests:
2+
- desiredInputPath: testdata/desired-uniteddeployment.yaml
3+
statusInputPath: testdata/status-file.yaml
4+
operation: AggregateStatus
5+
- desiredInputPath: testdata/desired-uniteddeployment.yaml
6+
operation: InterpretDependency
7+
- observedInputPath: testdata/observed-uniteddeployment.yaml
8+
operation: InterpretReplica
9+
- observedInputPath: testdata/observed-uniteddeployment.yaml
10+
operation: ReviseReplica
11+
desiredReplicas: 1
12+
- observedInputPath: testdata/observed-uniteddeployment.yaml
13+
operation: InterpretHealth
14+
- observedInputPath: testdata/observed-uniteddeployment.yaml
15+
operation: InterpretStatus
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
apiVersion: apps.kruise.io/v1alpha1
2+
kind: UnitedDeployment
3+
metadata:
4+
name: sample-uniteddeployment
5+
namespace: test-namespace
6+
generation: 1
7+
spec:
8+
replicas: 3
9+
selector:
10+
matchLabels:
11+
app: sample
12+
template:
13+
metadata:
14+
labels:
15+
app: sample
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:latest
20+
env:
21+
- name: CONFIG_DATA
22+
valueFrom:
23+
configMapKeyRef:
24+
name: app-config
25+
key: config
26+
- name: SECRET_DATA
27+
valueFrom:
28+
secretKeyRef:
29+
name: app-secret
30+
key: token
31+
volumeMounts:
32+
- name: config-volume
33+
mountPath: /etc/config
34+
volumes:
35+
- name: config-volume
36+
configMap:
37+
name: app-config
38+
topologySpread:
39+
- topologyKey: kubernetes.io/hostname
40+
maxSkew: 1
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: apps.kruise.io/v1alpha1
2+
kind: UnitedDeployment
3+
metadata:
4+
name: sample-uniteddeployment
5+
namespace: test-namespace
6+
generation: 1
7+
resourceVersion: "12345"
8+
uid: "a1b2c3d4-5678-90ef-ghij-klmnopqrstuv"
9+
spec:
10+
replicas: 3
11+
selector:
12+
matchLabels:
13+
app: sample
14+
template:
15+
metadata:
16+
labels:
17+
app: sample
18+
spec:
19+
containers:
20+
- name: nginx
21+
image: nginx:latest
22+
env:
23+
- name: CONFIG_DATA
24+
valueFrom:
25+
configMapKeyRef:
26+
name: app-config
27+
key: config
28+
- name: SECRET_DATA
29+
valueFrom:
30+
secretKeyRef:
31+
name: app-secret
32+
key: token
33+
volumeMounts:
34+
- name: config-volume
35+
mountPath: /etc/config
36+
volumes:
37+
- name: config-volume
38+
configMap:
39+
name: app-config
40+
topologySpread:
41+
- topologyKey: kubernetes.io/hostname
42+
maxSkew: 1
43+
status:
44+
replicas: 3
45+
readyReplicas: 3
46+
updatedReplicas: 3
47+
availableReplicas: 3
48+
collisionCount: 0
49+
observedGeneration: 1
50+
conditions:
51+
- type: Available
52+
status: "True"
53+
lastTransitionTime: "2023-01-01T00:00:00Z"
54+
reason: MinimumReplicasAvailable
55+
message: Deployment has minimum availability.
56+
- type: Progressing
57+
status: "True"
58+
lastTransitionTime: "2023-01-01T00:00:00Z"
59+
reason: NewReplicaSetAvailable
60+
message: ReplicaSet has successfully progressed.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
apiVersion: apps.kruise.io/v1alpha1
2+
kind: UnitedDeployment
3+
metadata:
4+
name: sample-uniteddeployment
5+
namespace: test-namespace
6+
clusterName: member1
7+
status:
8+
replicas: 2
9+
readyReplicas: 2
10+
updatedReplicas: 2
11+
availableReplicas: 2
12+
collisionCount: 0
13+
observedGeneration: 1
14+
---
15+
apiVersion: apps.kruise.io/v1alpha1
16+
kind: UnitedDeployment
17+
metadata:
18+
name: sample-uniteddeployment
19+
namespace: test-namespace
20+
clusterName: member2
21+
status:
22+
replicas: 1
23+
readyReplicas: 1
24+
updatedReplicas: 1
25+
availableReplicas: 1
26+
collisionCount: 0
27+
observedGeneration: 1

0 commit comments

Comments
 (0)