Skip to content

Commit 2535caa

Browse files
leon-apeapecloud-bot
authored andcommitted
chore: keep topology template compDef resolution constrained (#10372)
(cherry picked from commit 6960b1f)
1 parent a4b246b commit 2535caa

2 files changed

Lines changed: 178 additions & 2 deletions

File tree

controllers/apps/cluster/transformer_cluster_normalization.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ func (t *clusterNormalizationTransformer) resolveDefinitions4ComponentWithObj(tr
433433
if len(tpl.ServiceVersion) == 0 && len(tpl.CompDef) == 0 {
434434
continue
435435
}
436-
compDef, serviceVersion, err = t.resolveCompDefinitionNServiceVersionWithTemplate(transCtx, comp, &tpl)
436+
compDef, serviceVersion, err = t.resolveCompDefinitionNServiceVersionWithTemplate(transCtx, comp, &tpl, compSpec.ComponentDef)
437437
if err != nil {
438438
return nil, err
439439
}
@@ -458,7 +458,7 @@ func (t *clusterNormalizationTransformer) resolveCompDefinitionNServiceVersionWi
458458
}
459459

460460
func (t *clusterNormalizationTransformer) resolveCompDefinitionNServiceVersionWithTemplate(transCtx *clusterTransformContext,
461-
comp *appsv1.Component, protoTpl *appsv1.InstanceTemplate) (*appsv1.ComponentDefinition, string, error) {
461+
comp *appsv1.Component, protoTpl *appsv1.InstanceTemplate, defaultCompDefName string) (*appsv1.ComponentDefinition, string, error) {
462462
var (
463463
ctx = transCtx.Context
464464
cli = transCtx.Client
@@ -474,6 +474,9 @@ func (t *clusterNormalizationTransformer) resolveCompDefinitionNServiceVersionWi
474474
}
475475
serviceVersion := protoTpl.ServiceVersion
476476
compDefName := protoTpl.CompDef
477+
if len(compDefName) == 0 {
478+
compDefName = defaultCompDefName
479+
}
477480
if comp == nil || runningTpl == nil || t.checkTemplateUpgrade(serviceVersion, compDefName, runningTpl) {
478481
return resolveCompDefinitionNServiceVersion(ctx, cli, compDefName, serviceVersion)
479482
}

controllers/apps/cluster/transformer_cluster_normalization_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ var _ = Describe("resolve CompDefinition and ServiceVersion", func() {
5656
// non-namespaced
5757
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ComponentDefinitionSignature, true, ml)
5858
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ComponentVersionSignature, true, ml)
59+
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ShardingDefinitionSignature, true, ml)
5960

6061
// namespaced
6162
}
@@ -456,6 +457,178 @@ var _ = Describe("resolve CompDefinition and ServiceVersion", func() {
456457
Expect(resolvedServiceVersion).Should(Equal(testapps.ServiceVersion("v4")))
457458
updateNCheckCompDefinitionImages(compDef, resolvedServiceVersion, "r6", "") // app is r6 and another one is ""
458459
})
460+
461+
It("resolves topology cluster instance template within topology compDef pattern", func() {
462+
const (
463+
mysqlCompDef = "mysql-8.0-1.0.5"
464+
mysqlOrcCompDef = "mysql-orc-8.0-1.0.5"
465+
compName = "mysql"
466+
serviceVersion = "8.0.37"
467+
)
468+
topologyCompDef := `^mysql-\d+\.\d+.*$`
469+
470+
By("creating mysql and mysql-orc definitions with the same supported service version")
471+
for _, name := range []string{mysqlCompDef, mysqlOrcCompDef} {
472+
compDef := testapps.NewComponentDefinitionFactory(name).
473+
SetServiceVersion("8.0.33").
474+
SetRuntime(&corev1.Container{Name: compName, Image: testapps.AppImage(compName, "8.0.33")}).
475+
Create(&testCtx).
476+
GetObject()
477+
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDef),
478+
func(g Gomega, compDef *appsv1.ComponentDefinition) {
479+
g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation))
480+
})).Should(Succeed())
481+
}
482+
483+
for _, item := range []struct {
484+
name string
485+
compDef string
486+
}{
487+
{name: "mysql", compDef: mysqlCompDef},
488+
{name: "mysql-orc", compDef: mysqlOrcCompDef},
489+
} {
490+
compVersion := testapps.NewComponentVersionFactory(item.name).
491+
AddCompatibilityRule([]string{item.compDef}, []string{serviceVersion}).
492+
AddRelease(serviceVersion, "", serviceVersion, map[string]string{
493+
compName: testapps.AppImage(compName, serviceVersion),
494+
}).
495+
Create(&testCtx).
496+
GetObject()
497+
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersion),
498+
func(g Gomega, compVersion *appsv1.ComponentVersion) {
499+
g.Expect(compVersion.Status.ObservedGeneration).Should(Equal(compVersion.Generation))
500+
g.Expect(compVersion.Status.Phase).Should(Equal(appsv1.AvailablePhase))
501+
})).Should(Succeed())
502+
}
503+
504+
By("resolving a topology cluster with a serviceVersion-matched instance template")
505+
clusterObj := testapps.NewClusterFactory(testCtx.DefaultNamespace, "topology-instance-template", "mysql").
506+
SetTopology("semisync").
507+
AddComponent(compName, "").
508+
GetObject()
509+
clusterObj.Spec.ComponentSpecs[0].ServiceVersion = serviceVersion
510+
clusterObj.Spec.ComponentSpecs[0].Instances = []appsv1.InstanceTemplate{{
511+
Name: "canary",
512+
ServiceVersion: serviceVersion,
513+
}}
514+
515+
transformer := &clusterNormalizationTransformer{}
516+
comps, err := transformer.resolveCompsFromTopology(appsv1.ClusterTopology{
517+
Name: "semisync",
518+
Components: []appsv1.ClusterTopologyComponent{{
519+
Name: compName,
520+
CompDef: topologyCompDef,
521+
}},
522+
}, clusterObj)
523+
Expect(err).Should(Succeed())
524+
Expect(comps).Should(HaveLen(1))
525+
Expect(comps[0].ComponentDef).Should(Equal(topologyCompDef))
526+
527+
_, err = transformer.resolveDefinitions4ComponentWithObj(&clusterTransformContext{
528+
Context: testCtx.Ctx,
529+
Client: testCtx.Cli,
530+
Cluster: clusterObj,
531+
}, comps[0], nil)
532+
Expect(err).Should(Succeed())
533+
534+
Expect(comps[0].ComponentDef).Should(Equal(mysqlCompDef))
535+
Expect(comps[0].ServiceVersion).Should(Equal(serviceVersion))
536+
Expect(comps[0].Instances).Should(HaveLen(1))
537+
Expect(comps[0].Instances[0].CompDef).Should(Equal(mysqlCompDef))
538+
Expect(comps[0].Instances[0].ServiceVersion).Should(Equal(serviceVersion))
539+
})
540+
541+
It("resolves topology sharding instance template within sharding template compDef pattern", func() {
542+
const (
543+
mysqlCompDef = "mysql-8.0-1.0.5"
544+
mysqlOrcCompDef = "mysql-orc-8.0-1.0.5"
545+
shardingDefName = "mysql-sharding-1.0.5"
546+
shardingName = "mysql"
547+
compName = "mysql"
548+
serviceVersion = "8.0.37"
549+
)
550+
topologyCompDef := `^mysql-\d+\.\d+.*$`
551+
552+
By("creating mysql and mysql-orc definitions with the same supported service version")
553+
for _, name := range []string{mysqlCompDef, mysqlOrcCompDef} {
554+
compDef := testapps.NewComponentDefinitionFactory(name).
555+
SetServiceVersion("8.0.33").
556+
SetRuntime(&corev1.Container{Name: compName, Image: testapps.AppImage(compName, "8.0.33")}).
557+
Create(&testCtx).
558+
GetObject()
559+
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDef),
560+
func(g Gomega, compDef *appsv1.ComponentDefinition) {
561+
g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation))
562+
})).Should(Succeed())
563+
}
564+
565+
for _, item := range []struct {
566+
name string
567+
compDef string
568+
}{
569+
{name: "mysql", compDef: mysqlCompDef},
570+
{name: "mysql-orc", compDef: mysqlOrcCompDef},
571+
} {
572+
compVersion := testapps.NewComponentVersionFactory(item.name).
573+
AddCompatibilityRule([]string{item.compDef}, []string{serviceVersion}).
574+
AddRelease(serviceVersion, "", serviceVersion, map[string]string{
575+
compName: testapps.AppImage(compName, serviceVersion),
576+
}).
577+
Create(&testCtx).
578+
GetObject()
579+
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersion),
580+
func(g Gomega, compVersion *appsv1.ComponentVersion) {
581+
g.Expect(compVersion.Status.ObservedGeneration).Should(Equal(compVersion.Generation))
582+
g.Expect(compVersion.Status.Phase).Should(Equal(appsv1.AvailablePhase))
583+
})).Should(Succeed())
584+
}
585+
586+
By("creating a sharding definition that constrains its component definition family")
587+
shardingDef := testapps.NewShardingDefinitionFactory(shardingDefName, topologyCompDef).
588+
Create(&testCtx).
589+
GetObject()
590+
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(shardingDef),
591+
func(g Gomega, shardingDef *appsv1.ShardingDefinition) {
592+
g.Expect(shardingDef.Status.ObservedGeneration).Should(Equal(shardingDef.Generation))
593+
})).Should(Succeed())
594+
595+
By("resolving a topology sharding with a serviceVersion-matched instance template")
596+
clusterObj := testapps.NewClusterFactory(testCtx.DefaultNamespace, "topology-sharding-template", "mysql").
597+
SetTopology("semisync").
598+
AddSharding(shardingName, "", "").
599+
SetShardingServiceVersion(serviceVersion).
600+
AddShardingInstances(appsv1.InstanceTemplate{
601+
Name: "canary",
602+
ServiceVersion: serviceVersion,
603+
}).
604+
GetObject()
605+
606+
transformer := &clusterNormalizationTransformer{}
607+
shardings, err := transformer.resolveShardingsFromTopology(appsv1.ClusterTopology{
608+
Name: "semisync",
609+
Shardings: []appsv1.ClusterTopologySharding{{
610+
Name: shardingName,
611+
ShardingDef: shardingDefName,
612+
}},
613+
}, clusterObj)
614+
Expect(err).Should(Succeed())
615+
Expect(shardings).Should(HaveLen(1))
616+
Expect(shardings[0].ShardingDef).Should(Equal(shardingDefName))
617+
618+
_, _, err = transformer.resolveDefinitions4Sharding(&clusterTransformContext{
619+
Context: testCtx.Ctx,
620+
Client: testCtx.Cli,
621+
Cluster: clusterObj,
622+
}, shardings[0])
623+
Expect(err).Should(Succeed())
624+
625+
Expect(shardings[0].ShardingDef).Should(Equal(shardingDefName))
626+
Expect(shardings[0].Template.ComponentDef).Should(Equal(mysqlCompDef))
627+
Expect(shardings[0].Template.ServiceVersion).Should(Equal(serviceVersion))
628+
Expect(shardings[0].Template.Instances).Should(HaveLen(1))
629+
Expect(shardings[0].Template.Instances[0].CompDef).Should(Equal(mysqlCompDef))
630+
Expect(shardings[0].Template.Instances[0].ServiceVersion).Should(Equal(serviceVersion))
631+
})
459632
})
460633

461634
Context("resolve component definition, service version without serviceVersion in componentDefinition", func() {

0 commit comments

Comments
 (0)