mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 03:56:36 +00:00
Feat: application support controller requirement (#3192)
* application controller version control Signed-off-by: Jian.Li <lj176172@alibaba-inc.com> * modify command arg name Signed-off-by: Jian.Li <lj176172@alibaba-inc.com>
This commit is contained in:
@@ -130,6 +130,7 @@ func main() {
|
||||
"The duration the LeaderElector clients should wait between tries of actions")
|
||||
flag.BoolVar(&enableClusterGateway, "enable-cluster-gateway", false, "Enable cluster-gateway to use multicluster, disabled by default.")
|
||||
flag.BoolVar(&controllerArgs.EnableCompatibility, "enable-asi-compatibility", false, "enable compatibility for asi")
|
||||
flag.BoolVar(&controllerArgs.IgnoreAppWithoutControllerRequirement, "ignore-app-without-controller-version", false, "If true, application controller will not process the app without 'app.oam.dev/controller-version-require' annotation")
|
||||
standardcontroller.AddOptimizeFlags()
|
||||
|
||||
flag.Parse()
|
||||
|
||||
@@ -83,4 +83,7 @@ type Args struct {
|
||||
|
||||
// EnableCompatibility indicates that will change some functions of controller to adapt to multiple platforms, such as asi.
|
||||
EnableCompatibility bool
|
||||
|
||||
// IgnoreAppWithoutControllerRequirement indicates that application controller will not process the app without 'app.oam.dev/controller-version-require' annotation.
|
||||
IgnoreAppWithoutControllerRequirement bool
|
||||
}
|
||||
|
||||
@@ -92,6 +92,8 @@ type options struct {
|
||||
appRevisionLimit int
|
||||
concurrentReconciles int
|
||||
disableStatusUpdate bool
|
||||
ignoreAppNoCtrlReq bool
|
||||
controllerVersion string
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applications,verbs=get;list;watch;create;update;patch;delete
|
||||
@@ -100,6 +102,7 @@ type options struct {
|
||||
// Reconcile process app event
|
||||
// nolint:gocyclo
|
||||
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, common2.ReconcileTimeout)
|
||||
defer cancel()
|
||||
|
||||
@@ -117,6 +120,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return r.result(client.IgnoreNotFound(err)).ret()
|
||||
}
|
||||
|
||||
if !r.matchControllerRequirement(app) {
|
||||
logCtx.Info("skip app: not match the controller requirement of app")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
timeReporter := timeReconcile(app)
|
||||
defer timeReporter()
|
||||
|
||||
@@ -590,5 +598,19 @@ func parseOptions(args core.Args) options {
|
||||
disableStatusUpdate: args.EnableCompatibility,
|
||||
appRevisionLimit: args.AppRevisionLimit,
|
||||
concurrentReconciles: args.ConcurrentReconciles,
|
||||
ignoreAppNoCtrlReq: args.IgnoreAppWithoutControllerRequirement,
|
||||
controllerVersion: version.VelaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) matchControllerRequirement(app *v1beta1.Application) bool {
|
||||
if app.Annotations != nil {
|
||||
if requireVersion, ok := app.Annotations[oam.AnnotationControllerRequirement]; ok {
|
||||
return requireVersion == r.controllerVersion
|
||||
}
|
||||
}
|
||||
if r.ignoreAppNoCtrlReq {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -2277,6 +2277,74 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Expect(*(checkWeb.Spec.Replicas)).Should(BeEquivalentTo(int32(0)))
|
||||
|
||||
})
|
||||
|
||||
It("test controller requirement", func() {
|
||||
|
||||
ns := corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-controller-requirement",
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), &ns)).Should(BeNil())
|
||||
|
||||
appWithoutCtrlReq := appwithNoTrait.DeepCopy()
|
||||
appWithoutCtrlReq.SetNamespace(ns.Name)
|
||||
appWithoutCtrlReq.SetName("app-no-ctrl-req")
|
||||
Expect(k8sClient.Create(context.Background(), appWithoutCtrlReq)).Should(BeNil())
|
||||
|
||||
appWithCtrlReqV1 := appwithNoTrait.DeepCopy()
|
||||
appWithCtrlReqV1.SetNamespace(ns.Name)
|
||||
appWithCtrlReqV1.SetName("app-with-ctrl-v1")
|
||||
appWithCtrlReqV1.Annotations = map[string]string{
|
||||
oam.AnnotationControllerRequirement: "v1",
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), appWithCtrlReqV1)).Should(BeNil())
|
||||
|
||||
appWithCtrlReqV2 := appwithNoTrait.DeepCopy()
|
||||
appWithCtrlReqV2.SetNamespace(ns.Name)
|
||||
appWithCtrlReqV2.SetName("app-with-ctrl-v2")
|
||||
appWithCtrlReqV2.Annotations = map[string]string{
|
||||
oam.AnnotationControllerRequirement: "v2",
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), appWithCtrlReqV2)).Should(BeNil())
|
||||
|
||||
v1OREmptyReconciler := *reconciler
|
||||
v1OREmptyReconciler.ignoreAppNoCtrlReq = false
|
||||
v1OREmptyReconciler.controllerVersion = "v1"
|
||||
|
||||
v2OnlyReconciler := *reconciler
|
||||
v2OnlyReconciler.ignoreAppNoCtrlReq = true
|
||||
v2OnlyReconciler.controllerVersion = "v2"
|
||||
|
||||
check := func(r reconcile.Reconciler, app *v1beta1.Application, do bool) {
|
||||
testutil.ReconcileOnceAfterFinalizer(r, reconcile.Request{NamespacedName: client.ObjectKey{
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
}})
|
||||
checkApp := &v1beta1.Application{}
|
||||
Expect(k8sClient.Get(context.Background(), client.ObjectKey{
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
}, checkApp)).Should(BeNil())
|
||||
|
||||
if do {
|
||||
Expect(checkApp.Annotations[oam.AnnotationKubeVelaVersion]).ShouldNot(BeEmpty())
|
||||
} else {
|
||||
if checkApp.Annotations == nil {
|
||||
return
|
||||
}
|
||||
Expect(checkApp.Annotations[oam.AnnotationKubeVelaVersion]).Should(BeEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
check(&v2OnlyReconciler, appWithoutCtrlReq, false)
|
||||
check(&v2OnlyReconciler, appWithCtrlReqV1, false)
|
||||
check(&v1OREmptyReconciler, appWithCtrlReqV2, false)
|
||||
|
||||
check(&v1OREmptyReconciler, appWithoutCtrlReq, true)
|
||||
check(&v1OREmptyReconciler, appWithCtrlReqV1, true)
|
||||
check(&v2OnlyReconciler, appWithCtrlReqV2, true)
|
||||
})
|
||||
})
|
||||
|
||||
const (
|
||||
|
||||
@@ -179,4 +179,7 @@ const (
|
||||
|
||||
// AnnotationWorkloadName indicates the managed workload's name by trait
|
||||
AnnotationWorkloadName = "trait.oam.dev/workload-name"
|
||||
|
||||
// AnnotationControllerRequirement indicates the controller version that can process the application.
|
||||
AnnotationControllerRequirement = "app.oam.dev/controller-version-require"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user