mirror of
https://github.com/kubevela/kubevela.git
synced 2026-05-06 09:27:16 +00:00
* Feat: support per-application reconciliation interval override via annotation Add the app.oam.dev/reconcile-interval annotation that lets operators override the global ApplicationReSyncPeriod on a per-application basis. This is useful when different applications have different drift-detection needs: a production app might need reconciliation every minute while a dev/staging app can safely use a longer interval to reduce API server load. When the annotation is present and contains a valid Go duration string (e.g. "1m", "15m", "30s") at or above the 10s minimum floor, the controller uses that value as RequeueAfter instead of the global default. Invalid or below-minimum values are logged as warnings and silently fall back to the global default, preserving full backward compatibility. The implementation adds a forApp() chain method to reconcileResult so that only the return paths where the default resync period matters (normal completion and error recovery) need to be annotated, leaving all explicit requeue() calls untouched. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * test: add e2e coverage for app reconcile interval Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * chore: trigger ci rerun Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix: address reconcile interval review feedback Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix: satisfy reconcile interval lint Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> --------- Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
285 lines
13 KiB
Go
285 lines
13 KiB
Go
/*
|
|
Copyright 2019 The Crossplane Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package oam
|
|
|
|
import "strings"
|
|
|
|
// Label key strings.
|
|
// AppConfig controller will add these labels into workloads.
|
|
const (
|
|
// LabelAppName records the name of AppConfig
|
|
LabelAppName = "app.oam.dev/name"
|
|
// LabelAppRevision records the name of Application, it's equal to name of AppConfig created by Application
|
|
LabelAppRevision = "app.oam.dev/appRevision"
|
|
// LabelAppComponent records the name of Component
|
|
LabelAppComponent = "app.oam.dev/component"
|
|
// LabelReplicaKey records the replica key of Component
|
|
LabelReplicaKey = "app.oam.dev/replicaKey"
|
|
// LabelAppComponentRevision records the revision name of Component
|
|
LabelAppComponentRevision = "app.oam.dev/revision"
|
|
// LabelOAMResourceType whether a CR is workload or trait
|
|
LabelOAMResourceType = "app.oam.dev/resourceType"
|
|
// LabelAppRevisionHash records the Hash value of the application revision
|
|
LabelAppRevisionHash = "app.oam.dev/app-revision-hash"
|
|
// LabelAppNamespace records the namespace of Application
|
|
LabelAppNamespace = "app.oam.dev/namespace"
|
|
// LabelAppCluster records the cluster of Application
|
|
LabelAppCluster = "app.oam.dev/cluster"
|
|
// LabelAppUID records the uid of Application
|
|
LabelAppUID = "app.oam.dev/uid"
|
|
|
|
// WorkloadTypeLabel indicates the type of the workloadDefinition
|
|
WorkloadTypeLabel = "workload.oam.dev/type"
|
|
// TraitTypeLabel indicates the type of the traitDefinition
|
|
TraitTypeLabel = "trait.oam.dev/type"
|
|
// TraitResource indicates which resource it is when a trait is composed by multiple resources in KubeVela
|
|
TraitResource = "trait.oam.dev/resource"
|
|
|
|
// LabelComponentDefinitionName records the name of ComponentDefinition
|
|
LabelComponentDefinitionName = "componentdefinition.oam.dev/name"
|
|
// LabelTraitDefinitionName records the name of TraitDefinition
|
|
LabelTraitDefinitionName = "trait.oam.dev/name"
|
|
// LabelManageWorkloadTrait indicates if the trait will manage the lifecycle of the workload
|
|
LabelManageWorkloadTrait = "trait.oam.dev/manage-workload"
|
|
// LabelPolicyDefinitionName records the name of PolicyDefinition
|
|
LabelPolicyDefinitionName = "policydefinition.oam.dev/name"
|
|
// LabelWorkflowStepDefinitionName records the name of WorkflowStepDefinition
|
|
LabelWorkflowStepDefinitionName = "workflowstepdefinition.oam.dev/name"
|
|
|
|
// LabelControllerRevisionComponent indicate which component the revision belong to
|
|
LabelControllerRevisionComponent = "controller.oam.dev/component"
|
|
|
|
// LabelAddonName indicates the name of the corresponding Addon
|
|
LabelAddonName = "addons.oam.dev/name"
|
|
|
|
// LabelAddonAuxiliaryName indicates the name of the auxiliary resource in addon app template
|
|
LabelAddonAuxiliaryName = "addons.oam.dev/auxiliary-name"
|
|
|
|
// LabelAddonVersion indicates the version of the corresponding installed Addon
|
|
LabelAddonVersion = "addons.oam.dev/version"
|
|
|
|
// LabelAddonRegistry indicates the name of addon-registry
|
|
LabelAddonRegistry = "addons.oam.dev/registry"
|
|
|
|
// LabelNamespaceOfEnvName records the env name of namespace
|
|
LabelNamespaceOfEnvName = "namespace.oam.dev/env"
|
|
|
|
// LabelNamespaceOfTargetName records the target name of namespace
|
|
LabelNamespaceOfTargetName = "namespace.oam.dev/target"
|
|
|
|
// LabelControlPlaneNamespaceUsage mark the usage of the namespace in control plane cluster.
|
|
LabelControlPlaneNamespaceUsage = "usage.oam.dev/control-plane"
|
|
|
|
// LabelRuntimeNamespaceUsage mark the usage of the namespace in runtime cluster.
|
|
// A control plane cluster can also be used as runtime cluster
|
|
LabelRuntimeNamespaceUsage = "usage.oam.dev/runtime"
|
|
|
|
// LabelConfigType means the config type
|
|
LabelConfigType = "config.oam.dev/type"
|
|
|
|
// LabelProject recorde the project the resource belong to
|
|
LabelProject = "core.oam.dev/project"
|
|
|
|
// LabelResourceRules defines the configmap is representing the resource topology rules
|
|
LabelResourceRules = "rules.oam.dev/resources"
|
|
|
|
// LabelResourceRuleFormat defines the resource format of the resource topology rules
|
|
LabelResourceRuleFormat = "rules.oam.dev/resource-format"
|
|
|
|
// LabelControllerName indicates the controller name
|
|
LabelControllerName = "controller.oam.dev/name"
|
|
|
|
// LabelPreCheck indicates if the target resource is for pre-check test
|
|
LabelPreCheck = "core.oam.dev/pre-check"
|
|
)
|
|
|
|
const (
|
|
// VelaNamespaceUsageEnv mark the usage of the namespace is used by env.
|
|
VelaNamespaceUsageEnv = "env"
|
|
// VelaNamespaceUsageTarget mark the usage of the namespace is used as delivery target.
|
|
VelaNamespaceUsageTarget = "target"
|
|
)
|
|
|
|
const (
|
|
// ResourceTypeTrait mark this K8s Custom Resource is an OAM trait
|
|
ResourceTypeTrait = "TRAIT"
|
|
// ResourceTypeWorkload mark this K8s Custom Resource is an OAM workload
|
|
ResourceTypeWorkload = "WORKLOAD"
|
|
)
|
|
|
|
const (
|
|
// AnnotationLastAppliedConfig records the previous configuration of a
|
|
// resource for use in a three-way diff during a patching apply
|
|
AnnotationLastAppliedConfig = "app.oam.dev/last-applied-configuration"
|
|
|
|
// AnnotationLastAppliedTime indicates the last applied time
|
|
AnnotationLastAppliedTime = "app.oam.dev/last-applied-time"
|
|
|
|
// AnnotationInplaceUpgrade indicates the workload should upgrade with the the same name
|
|
// the name of the workload instance should not changing along with the revision
|
|
AnnotationInplaceUpgrade = "app.oam.dev/inplace-upgrade"
|
|
|
|
// AnnotationAppRevision indicates that the object is an application revision
|
|
// its controller should not try to reconcile it
|
|
AnnotationAppRevision = "app.oam.dev/app-revision"
|
|
|
|
// AnnotationKubeVelaVersion is used to record current KubeVela version
|
|
AnnotationKubeVelaVersion = "oam.dev/kubevela-version"
|
|
|
|
// AnnotationFilterAnnotationKeys is used to filter annotations passed to workload and trait, split by comma
|
|
AnnotationFilterAnnotationKeys = "filter.oam.dev/annotation-keys"
|
|
|
|
// AnnotationFilterLabelKeys is used to filter labels passed to workload and trait, split by comma
|
|
AnnotationFilterLabelKeys = "filter.oam.dev/label-keys"
|
|
|
|
// AnnotationDefinitionRevisionName is used to specify the name of DefinitionRevision in component/trait definition
|
|
AnnotationDefinitionRevisionName = "definitionrevision.oam.dev/name"
|
|
|
|
// AnnotationLastAppliedConfiguration is kubectl annotations for 3-way merge
|
|
AnnotationLastAppliedConfiguration = "kubectl.kubernetes.io/last-applied-configuration"
|
|
|
|
// AnnotationDeployVersion know the version number of the deployment.
|
|
AnnotationDeployVersion = "app.oam.dev/deployVersion"
|
|
|
|
// AnnotationPublishVersion is annotation that record the application workflow version.
|
|
AnnotationPublishVersion = "app.oam.dev/publishVersion"
|
|
|
|
// AnnotationAutoUpdate is annotation that let application auto update when it finds definition changes
|
|
AnnotationAutoUpdate = "app.oam.dev/autoUpdate"
|
|
|
|
// AnnotationAutoRevision controls whether policy-rendered spec changes create new ApplicationRevisions.
|
|
// When set to "true", policies can modify Application.Spec and trigger new revisions.
|
|
// This is orthogonal to AnnotationAutoUpdate which controls definition version updates.
|
|
AnnotationAutoRevision = "policy.oam.dev/auto-revision"
|
|
|
|
// AnnotationSkipGlobalPolicies controls whether global (vela-system) policies are skipped for an Application.
|
|
// When set to "true", only explicitly declared spec.policies are evaluated.
|
|
AnnotationSkipGlobalPolicies = "policy.oam.dev/skip-global"
|
|
// AnnotationForceParamMutations bypasses all immutable parameter field validation when set to "true".
|
|
AnnotationForceParamMutations = "app.oam.dev/force-param-mutations"
|
|
|
|
// AnnotationWorkflowName specifies the workflow name for execution.
|
|
AnnotationWorkflowName = "app.oam.dev/workflowName"
|
|
|
|
// AnnotationWorkflowRestart triggers a workflow restart when set. Supported values:
|
|
// - "true": Immediate restart (sets restart time to current time + 1 second).
|
|
// Annotation is automatically removed after being processed.
|
|
// - RFC3339 timestamp (e.g., "2025-01-15T14:30:00Z"): One-time restart at specified time.
|
|
// Annotation is automatically removed after being processed.
|
|
// - Duration (e.g., "5m", "1h", "30s"): Recurring restart with minimum interval after each completion.
|
|
// Annotation persists; automatically reschedules after each workflow completion.
|
|
// All modes are GitOps-safe: the schedule is stored in status.workflowRestartScheduledAt.
|
|
AnnotationWorkflowRestart = "app.oam.dev/restart-workflow"
|
|
|
|
// AnnotationAppName specifies the name for application in db.
|
|
// Note: the annotation is only created by velaUX, please don't use it in other Source of Truth.
|
|
AnnotationAppName = "app.oam.dev/appName"
|
|
|
|
// AnnotationAppAlias specifies the alias for application in db.
|
|
AnnotationAppAlias = "app.oam.dev/appAlias"
|
|
|
|
// AnnotationControllerRequirement indicates the controller version that can process the application/definition.
|
|
AnnotationControllerRequirement = "app.oam.dev/controller-version-require"
|
|
|
|
// AnnotationApplicationServiceAccountName indicates the name of the ServiceAccount to use to apply Components and run Workflow.
|
|
// ServiceAccount will be used in the local cluster only.
|
|
AnnotationApplicationServiceAccountName = "app.oam.dev/service-account-name"
|
|
|
|
// AnnotationApplicationUsername indicates the username of the Application to use to apply resources
|
|
AnnotationApplicationUsername = "app.oam.dev/username"
|
|
|
|
// AnnotationApplicationGroup indicates the group of the Application to use to apply resources
|
|
AnnotationApplicationGroup = "app.oam.dev/group"
|
|
|
|
// AnnotationAppSharedBy records who share the application
|
|
AnnotationAppSharedBy = "app.oam.dev/shared-by"
|
|
|
|
// AnnotationResourceURL records the source url of the Kubernetes object
|
|
AnnotationResourceURL = "app.oam.dev/resource-url"
|
|
|
|
// AnnotationIgnoreWithoutCompKey indicates the bond component.
|
|
// Deprecated: please use AnnotationAddonDefinitionBindCompKey.
|
|
AnnotationIgnoreWithoutCompKey = "addon.oam.dev/ignore-without-component"
|
|
|
|
// AnnotationAddonDefinitionBondCompKey indicates the definition in addon bond component.
|
|
AnnotationAddonDefinitionBondCompKey = "addon.oam.dev/bind-component"
|
|
|
|
// AnnotationSkipResume annotation indicates that the resource does not need to be resumed.
|
|
AnnotationSkipResume = "controller.core.oam.dev/skip-resume"
|
|
|
|
// AnnotationReconcileInterval overrides the global ApplicationReSyncPeriod on a
|
|
// per-application basis. The value must be a valid Go duration string (e.g.
|
|
// "1m", "15m", "30s"). Values below 10s are ignored and fall back to the
|
|
// global default. Invalid values are also ignored.
|
|
AnnotationReconcileInterval = "app.oam.dev/reconcile-interval"
|
|
)
|
|
|
|
const (
|
|
// ResourceTopologyFormatYAML mark the format of resource topology is yaml, by default, it's yaml.
|
|
ResourceTopologyFormatYAML = "yaml"
|
|
// ResourceTopologyFormatJSON mark the format of resource topology is json.
|
|
ResourceTopologyFormatJSON = "json"
|
|
)
|
|
|
|
const (
|
|
// FinalizerResourceTracker is the application finalizer for gc
|
|
FinalizerResourceTracker = "app.oam.dev/resource-tracker-finalizer"
|
|
// FinalizerOrphanResource indicates that the gc process should orphan managed
|
|
// resources instead of deleting them
|
|
FinalizerOrphanResource = "app.oam.dev/orphan-resource"
|
|
)
|
|
|
|
// policyContextKeyType is a private type for Go context keys, preventing collisions.
|
|
type policyContextKeyType string
|
|
|
|
// PolicyAdditionalContextKey is the Go context key for storing policy output.ctx data.
|
|
const PolicyAdditionalContextKey policyContextKeyType = "kubevela.oam.dev/policy-additional-context"
|
|
|
|
// internalMetadataPrefixes lists key prefixes that are stripped when exposing Application
|
|
// labels/annotations to policy CUE templates. Add prefixes here to prevent policies from
|
|
// reading internal platform metadata.
|
|
var internalMetadataPrefixes = map[string]struct{}{
|
|
"app.oam.dev/": {},
|
|
"oam.dev/": {},
|
|
"kubectl.kubernetes.io/": {},
|
|
"kubernetes.io/": {},
|
|
"k8s.io/": {},
|
|
"helm.sh/": {},
|
|
"app.kubernetes.io/": {},
|
|
}
|
|
|
|
// FilterInternalMetadata returns a copy of metadata with internal platform keys removed.
|
|
// Returns nil when the result would be empty.
|
|
func FilterInternalMetadata(metadata map[string]string) map[string]string {
|
|
if len(metadata) == 0 {
|
|
return nil
|
|
}
|
|
filtered := make(map[string]string, len(metadata))
|
|
for k, v := range metadata {
|
|
if idx := strings.IndexByte(k, '/'); idx > 0 {
|
|
if _, isInternal := internalMetadataPrefixes[k[:idx+1]]; isInternal {
|
|
continue
|
|
}
|
|
}
|
|
filtered[k] = v
|
|
}
|
|
if len(filtered) == 0 {
|
|
return nil
|
|
}
|
|
return filtered
|
|
}
|