@@ -189,7 +189,7 @@ var _ = Describe("object rbac transformer test.", func() {
189189 // sa should be created
190190 serviceAccount := factory .BuildServiceAccount (synthesizedComp , serviceAccountName )
191191
192- dagExpected := mockDAG (graphCli , compObj )
192+ dagExpected := mockDAGWithUpdate (graphCli , compObj )
193193 graphCli .Create (dagExpected , serviceAccount )
194194
195195 Expect (dag .Equals (dagExpected , model .DefaultLess )).Should (BeTrue ())
@@ -204,7 +204,7 @@ var _ = Describe("object rbac transformer test.", func() {
204204 Name : constant .RBACRoleName ,
205205 }, serviceAccountName )
206206 serviceAccount := factory .BuildServiceAccount (synthesizedComp , serviceAccountName )
207- dagExpected := mockDAG (graphCli , compObj )
207+ dagExpected := mockDAGWithUpdate (graphCli , compObj )
208208 graphCli .Create (dagExpected , serviceAccount )
209209 graphCli .Create (dagExpected , clusterPodRoleBinding )
210210 graphCli .DependOn (dagExpected , clusterPodRoleBinding , serviceAccount )
@@ -225,7 +225,7 @@ var _ = Describe("object rbac transformer test.", func() {
225225 Name : cmpdRole .Name ,
226226 }, serviceAccountName )
227227 serviceAccount := factory .BuildServiceAccount (synthesizedComp , serviceAccountName )
228- dagExpected := mockDAG (graphCli , compObj )
228+ dagExpected := mockDAGWithUpdate (graphCli , compObj )
229229 graphCli .Create (dagExpected , serviceAccount )
230230 graphCli .Create (dagExpected , cmpdRoleBinding )
231231 graphCli .Create (dagExpected , cmpdRole )
@@ -242,6 +242,111 @@ var _ = Describe("object rbac transformer test.", func() {
242242 Expect (reflect .DeepEqual (rb .Subjects , cmpdRoleBinding .Subjects )).To (BeTrue ())
243243 Expect (reflect .DeepEqual (rb .RoleRef , cmpdRoleBinding .RoleRef )).To (BeTrue ())
244244 })
245+
246+ Context ("rollback behavior" , func () {
247+ It ("tests needRollbackServiceAccount" , func () {
248+ init (true , false )
249+ ctx := transCtx .(* componentTransformContext )
250+
251+ By ("create another cmpd" )
252+ anotherTpl := testapps .NewComponentDefinitionFactory (compDefName ).
253+ WithRandomName ().
254+ SetDefaultSpec ().
255+ Create (& testCtx ).
256+ GetObject ()
257+ hash , err := computeServiceAccountRuleHash (ctx )
258+ Expect (err ).ShouldNot (HaveOccurred ())
259+
260+ // Case: No label, should return false
261+ needRollback , err := needRollbackServiceAccount (ctx )
262+ Expect (err ).Should (BeNil ())
263+ Expect (needRollback ).Should (BeFalse ())
264+
265+ // Case: With same cmpd
266+ ctx .Component .Annotations [constant .ComponentLastServiceAccountRuleHashAnnotationKey ] = hash
267+ ctx .Component .Annotations [constant .ComponentLastServiceAccountNameAnnotationKey ] = constant .GenerateDefaultServiceAccountName (synthesizedComp .CompDefName )
268+ needRollback , err = needRollbackServiceAccount (ctx )
269+ Expect (err ).Should (BeNil ())
270+ Expect (needRollback ).Should (BeTrue ())
271+
272+ // Case: Different cmpd, same spec
273+ another := anotherTpl .DeepCopy ()
274+ ctx .SynthesizeComponent , err = component .BuildSynthesizedComponent (ctx , k8sClient , another , compObj )
275+ Expect (err ).Should (Succeed ())
276+ needRollback , err = needRollbackServiceAccount (ctx )
277+ Expect (err ).Should (BeNil ())
278+ Expect (needRollback ).Should (BeTrue ())
279+
280+ // Case: Different cmpd, different policy rules
281+ another = anotherTpl .DeepCopy ()
282+ another .Spec .PolicyRules = []rbacv1.PolicyRule {
283+ {
284+ APIGroups : []string {"" },
285+ Resources : []string {"pods" },
286+ Verbs : []string {"get" },
287+ },
288+ }
289+ ctx .SynthesizeComponent , err = component .BuildSynthesizedComponent (ctx , k8sClient , another , compObj )
290+ Expect (err ).Should (Succeed ())
291+ needRollback , err = needRollbackServiceAccount (ctx )
292+ Expect (err ).Should (BeNil ())
293+ Expect (needRollback ).Should (BeFalse ())
294+
295+ // Case: Different cmpd, different lifecycle action
296+ another = anotherTpl .DeepCopy ()
297+ another .Spec .PolicyRules = nil
298+ another .Spec .LifecycleActions = nil
299+ ctx .SynthesizeComponent , err = component .BuildSynthesizedComponent (ctx , k8sClient , another , compObj )
300+ Expect (err ).Should (Succeed ())
301+ needRollback , err = needRollbackServiceAccount (ctx )
302+ Expect (err ).Should (BeNil ())
303+ Expect (needRollback ).Should (BeFalse ())
304+ })
305+
306+ mockDAGWithUpdate := func (graphCli model.GraphClient , comp * appsv1.Component ) * graph.DAG {
307+ d := graph .NewDAG ()
308+ graphCli .Root (d , comp , comp , model .ActionUpdatePtr ())
309+ its := & workloads.InstanceSet {}
310+ graphCli .Create (d , its )
311+ return d
312+ }
313+
314+ less := func (v1 , v2 graph.Vertex ) bool {
315+ o1 , ok1 := v1 .(* model.ObjectVertex )
316+ o2 , ok2 := v2 .(* model.ObjectVertex )
317+ if ! ok1 || ! ok2 {
318+ return false
319+ }
320+ if o1 .String () != o2 .String () {
321+ return o1 .String () < o2 .String ()
322+ }
323+ if ! reflect .DeepEqual (o1 .Obj .GetLabels (), o2 .Obj .GetLabels ()) {
324+ return true
325+ }
326+ return ! reflect .DeepEqual (o1 .Obj .GetAnnotations (), o2 .Obj .GetAnnotations ())
327+ }
328+
329+ It ("adds labels for an old component" , func () {
330+ init (false , false )
331+ // mock a running workload
332+ ctx := transCtx .(* componentTransformContext )
333+ ctx .RunningWorkload = & workloads.InstanceSet {}
334+ expectedComp := compObj .DeepCopy ()
335+ Expect (transformer .Transform (transCtx , dag )).Should (BeNil ())
336+ // sa should be created
337+ oldSAName := constant .GenerateDefaultServiceAccountName (compDefObj .Name )
338+ serviceAccount := factory .BuildServiceAccount (synthesizedComp , oldSAName )
339+
340+ hash , err := computeServiceAccountRuleHash (ctx )
341+ Expect (err ).ShouldNot (HaveOccurred ())
342+ expectedComp .Annotations [constant .ComponentLastServiceAccountRuleHashAnnotationKey ] = hash
343+ expectedComp .Annotations [constant .ComponentLastServiceAccountNameAnnotationKey ] = constant .GenerateDefaultServiceAccountName (synthesizedComp .CompDefName )
344+ dagExpected := mockDAGWithUpdate (graphCli , expectedComp )
345+ graphCli .Create (dagExpected , serviceAccount )
346+
347+ Expect (dag .Equals (dagExpected , less )).Should (BeTrue ())
348+ })
349+ })
245350 })
246351})
247352
@@ -252,3 +357,11 @@ func mockDAG(graphCli model.GraphClient, comp *appsv1.Component) *graph.DAG {
252357 graphCli .Create (d , its )
253358 return d
254359}
360+
361+ func mockDAGWithUpdate (graphCli model.GraphClient , comp * appsv1.Component ) * graph.DAG {
362+ d := graph .NewDAG ()
363+ graphCli .Root (d , comp , comp , model .ActionUpdatePtr ())
364+ its := & workloads.InstanceSet {}
365+ graphCli .Create (d , its )
366+ return d
367+ }
0 commit comments