mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Feat: takeover & readonly policy (#5102)
* Feat: takeover & readonly Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add tests Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Feat: add cue def for read-only and take-over Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Docs: add example doc Signed-off-by: Somefive <yd219913@alibaba-inc.com> Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
@@ -59,8 +59,13 @@ type ApplyOnceStrategy struct {
|
||||
ApplyOnceAffectStrategy ApplyOnceAffectStrategy `json:"affect"`
|
||||
}
|
||||
|
||||
// Type the type name of the policy
|
||||
func (in *ApplyOncePolicySpec) Type() string {
|
||||
return ApplyOncePolicyType
|
||||
}
|
||||
|
||||
// FindStrategy find apply-once strategy for target resource
|
||||
func (in ApplyOncePolicySpec) FindStrategy(manifest *unstructured.Unstructured) *ApplyOnceStrategy {
|
||||
func (in *ApplyOncePolicySpec) FindStrategy(manifest *unstructured.Unstructured) *ApplyOnceStrategy {
|
||||
if !in.Enable {
|
||||
return nil
|
||||
}
|
||||
@@ -18,10 +18,6 @@ package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/utils/pointer"
|
||||
"k8s.io/utils/strings/slices"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -57,59 +53,6 @@ type GarbageCollectPolicyRule struct {
|
||||
Strategy GarbageCollectStrategy `json:"strategy"`
|
||||
}
|
||||
|
||||
// ResourcePolicyRuleSelector select the targets of the rule
|
||||
// if multiple conditions are specified, combination logic is AND
|
||||
type ResourcePolicyRuleSelector struct {
|
||||
CompNames []string `json:"componentNames,omitempty"`
|
||||
CompTypes []string `json:"componentTypes,omitempty"`
|
||||
OAMResourceTypes []string `json:"oamTypes,omitempty"`
|
||||
TraitTypes []string `json:"traitTypes,omitempty"`
|
||||
ResourceTypes []string `json:"resourceTypes,omitempty"`
|
||||
ResourceNames []string `json:"resourceNames,omitempty"`
|
||||
}
|
||||
|
||||
// Match check if current rule selector match the target resource
|
||||
// If at least one condition is matched and no other condition failed (could be empty), return true
|
||||
// Otherwise, return false
|
||||
func (in *ResourcePolicyRuleSelector) Match(manifest *unstructured.Unstructured) bool {
|
||||
var compName, compType, oamType, traitType, resourceType, resourceName string
|
||||
if labels := manifest.GetLabels(); labels != nil {
|
||||
compName = labels[oam.LabelAppComponent]
|
||||
compType = labels[oam.WorkloadTypeLabel]
|
||||
oamType = labels[oam.LabelOAMResourceType]
|
||||
traitType = labels[oam.TraitTypeLabel]
|
||||
}
|
||||
resourceType = manifest.GetKind()
|
||||
resourceName = manifest.GetName()
|
||||
match := func(src []string, val string) (found *bool) {
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
return pointer.Bool(val != "" && slices.Contains(src, val))
|
||||
}
|
||||
conditions := []*bool{
|
||||
match(in.CompNames, compName),
|
||||
match(in.CompTypes, compType),
|
||||
match(in.OAMResourceTypes, oamType),
|
||||
match(in.TraitTypes, traitType),
|
||||
match(in.ResourceTypes, resourceType),
|
||||
match(in.ResourceNames, resourceName),
|
||||
}
|
||||
hasMatched := false
|
||||
for _, cond := range conditions {
|
||||
// if any non-empty condition failed, return false
|
||||
if cond != nil && !*cond {
|
||||
return false
|
||||
}
|
||||
// if condition succeed, record it
|
||||
if cond != nil && *cond {
|
||||
hasMatched = true
|
||||
}
|
||||
}
|
||||
// if at least one condition is met, return true
|
||||
return hasMatched
|
||||
}
|
||||
|
||||
// GarbageCollectStrategy the strategy for target resource to recycle
|
||||
type GarbageCollectStrategy string
|
||||
|
||||
@@ -123,8 +66,13 @@ const (
|
||||
GarbageCollectStrategyOnAppUpdate GarbageCollectStrategy = "onAppUpdate"
|
||||
)
|
||||
|
||||
// Type the type name of the policy
|
||||
func (in *GarbageCollectPolicySpec) Type() string {
|
||||
return GarbageCollectPolicyType
|
||||
}
|
||||
|
||||
// FindStrategy find gc strategy for target resource
|
||||
func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
|
||||
func (in *GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
|
||||
for _, rule := range in.Rules {
|
||||
if rule.Selector.Match(manifest) {
|
||||
return &rule.Strategy
|
||||
@@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
const (
|
||||
// TopologyPolicyType refers to the type of topology policy
|
||||
TopologyPolicyType = "topology"
|
||||
@@ -25,8 +23,6 @@ const (
|
||||
OverridePolicyType = "override"
|
||||
// DebugPolicyType refers to the type of debug policy
|
||||
DebugPolicyType = "debug"
|
||||
// SharedResourcePolicyType refers to the type of shared resource policy
|
||||
SharedResourcePolicyType = "shared-resource"
|
||||
// ReplicationPolicyType refers to the type of replication policy
|
||||
ReplicationPolicyType = "replication"
|
||||
)
|
||||
@@ -64,26 +60,6 @@ type OverridePolicySpec struct {
|
||||
Selector []string `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// SharedResourcePolicySpec defines the spec of shared-resource policy
|
||||
type SharedResourcePolicySpec struct {
|
||||
Rules []SharedResourcePolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// SharedResourcePolicyRule defines the rule for sharing resources
|
||||
type SharedResourcePolicyRule struct {
|
||||
Selector ResourcePolicyRuleSelector `json:"selector"`
|
||||
}
|
||||
|
||||
// FindStrategy return if the target resource should be shared
|
||||
func (in SharedResourcePolicySpec) FindStrategy(manifest *unstructured.Unstructured) bool {
|
||||
for _, rule := range in.Rules {
|
||||
if rule.Selector.Match(manifest) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ReplicationPolicySpec defines the spec of replication policy
|
||||
// Override policy should be used together with replication policy to select the deployment target components
|
||||
type ReplicationPolicySpec struct {
|
||||
|
||||
49
apis/core.oam.dev/v1alpha1/readonly_policy_types.go
Normal file
49
apis/core.oam.dev/v1alpha1/readonly_policy_types.go
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela 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 v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
const (
|
||||
// ReadOnlyPolicyType refers to the type of read-only policy
|
||||
ReadOnlyPolicyType = "read-only"
|
||||
)
|
||||
|
||||
// ReadOnlyPolicySpec defines the spec of read-only policy
|
||||
type ReadOnlyPolicySpec struct {
|
||||
Rules []ReadOnlyPolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// Type the type name of the policy
|
||||
func (in *ReadOnlyPolicySpec) Type() string {
|
||||
return ReadOnlyPolicyType
|
||||
}
|
||||
|
||||
// ReadOnlyPolicyRule defines the rule for read-only resources
|
||||
type ReadOnlyPolicyRule struct {
|
||||
Selector ResourcePolicyRuleSelector `json:"selector"`
|
||||
}
|
||||
|
||||
// FindStrategy return if the target resource is read-only
|
||||
func (in *ReadOnlyPolicySpec) FindStrategy(manifest *unstructured.Unstructured) bool {
|
||||
for _, rule := range in.Rules {
|
||||
if rule.Selector.Match(manifest) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
78
apis/core.oam.dev/v1alpha1/resource_policy_types.go
Normal file
78
apis/core.oam.dev/v1alpha1/resource_policy_types.go
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela 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 v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/utils/pointer"
|
||||
stringslices "k8s.io/utils/strings/slices"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// ResourcePolicyRuleSelector select the targets of the rule
|
||||
// if multiple conditions are specified, combination logic is AND
|
||||
type ResourcePolicyRuleSelector struct {
|
||||
CompNames []string `json:"componentNames,omitempty"`
|
||||
CompTypes []string `json:"componentTypes,omitempty"`
|
||||
OAMResourceTypes []string `json:"oamTypes,omitempty"`
|
||||
TraitTypes []string `json:"traitTypes,omitempty"`
|
||||
ResourceTypes []string `json:"resourceTypes,omitempty"`
|
||||
ResourceNames []string `json:"resourceNames,omitempty"`
|
||||
}
|
||||
|
||||
// Match check if current rule selector match the target resource
|
||||
// If at least one condition is matched and no other condition failed (could be empty), return true
|
||||
// Otherwise, return false
|
||||
func (in *ResourcePolicyRuleSelector) Match(manifest *unstructured.Unstructured) bool {
|
||||
var compName, compType, oamType, traitType, resourceType, resourceName string
|
||||
if labels := manifest.GetLabels(); labels != nil {
|
||||
compName = labels[oam.LabelAppComponent]
|
||||
compType = labels[oam.WorkloadTypeLabel]
|
||||
oamType = labels[oam.LabelOAMResourceType]
|
||||
traitType = labels[oam.TraitTypeLabel]
|
||||
}
|
||||
resourceType = manifest.GetKind()
|
||||
resourceName = manifest.GetName()
|
||||
match := func(src []string, val string) (found *bool) {
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
return pointer.Bool(val != "" && stringslices.Contains(src, val))
|
||||
}
|
||||
conditions := []*bool{
|
||||
match(in.CompNames, compName),
|
||||
match(in.CompTypes, compType),
|
||||
match(in.OAMResourceTypes, oamType),
|
||||
match(in.TraitTypes, traitType),
|
||||
match(in.ResourceTypes, resourceType),
|
||||
match(in.ResourceNames, resourceName),
|
||||
}
|
||||
hasMatched := false
|
||||
for _, cond := range conditions {
|
||||
// if any non-empty condition failed, return false
|
||||
if cond != nil && !*cond {
|
||||
return false
|
||||
}
|
||||
// if condition succeed, record it
|
||||
if cond != nil && *cond {
|
||||
hasMatched = true
|
||||
}
|
||||
}
|
||||
// if at least one condition is met, return true
|
||||
return hasMatched
|
||||
}
|
||||
49
apis/core.oam.dev/v1alpha1/sharedresource_policy_types.go
Normal file
49
apis/core.oam.dev/v1alpha1/sharedresource_policy_types.go
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela 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 v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
const (
|
||||
// SharedResourcePolicyType refers to the type of shared resource policy
|
||||
SharedResourcePolicyType = "shared-resource"
|
||||
)
|
||||
|
||||
// SharedResourcePolicySpec defines the spec of shared-resource policy
|
||||
type SharedResourcePolicySpec struct {
|
||||
Rules []SharedResourcePolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// Type the type name of the policy
|
||||
func (in *SharedResourcePolicySpec) Type() string {
|
||||
return SharedResourcePolicyType
|
||||
}
|
||||
|
||||
// SharedResourcePolicyRule defines the rule for sharing resources
|
||||
type SharedResourcePolicyRule struct {
|
||||
Selector ResourcePolicyRuleSelector `json:"selector"`
|
||||
}
|
||||
|
||||
// FindStrategy return if the target resource should be shared
|
||||
func (in *SharedResourcePolicySpec) FindStrategy(manifest *unstructured.Unstructured) bool {
|
||||
for _, rule := range in.Rules {
|
||||
if rule.Selector.Match(manifest) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
49
apis/core.oam.dev/v1alpha1/takeover_policy_types.go
Normal file
49
apis/core.oam.dev/v1alpha1/takeover_policy_types.go
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela 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 v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
const (
|
||||
// TakeOverPolicyType refers to the type of take-over policy
|
||||
TakeOverPolicyType = "take-over"
|
||||
)
|
||||
|
||||
// TakeOverPolicySpec defines the spec of take-over policy
|
||||
type TakeOverPolicySpec struct {
|
||||
Rules []TakeOverPolicyRule `json:"rules"`
|
||||
}
|
||||
|
||||
// Type the type name of the policy
|
||||
func (in *TakeOverPolicySpec) Type() string {
|
||||
return TakeOverPolicyType
|
||||
}
|
||||
|
||||
// TakeOverPolicyRule defines the rule for taking over resources
|
||||
type TakeOverPolicyRule struct {
|
||||
Selector ResourcePolicyRuleSelector `json:"selector"`
|
||||
}
|
||||
|
||||
// FindStrategy return if the target resource should be taken over
|
||||
func (in *TakeOverPolicySpec) FindStrategy(manifest *unstructured.Unstructured) bool {
|
||||
for _, rule := range in.Rules {
|
||||
if rule.Selector.Match(manifest) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -585,6 +585,44 @@ func (in *PolicyList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReadOnlyPolicyRule) DeepCopyInto(out *ReadOnlyPolicyRule) {
|
||||
*out = *in
|
||||
in.Selector.DeepCopyInto(&out.Selector)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadOnlyPolicyRule.
|
||||
func (in *ReadOnlyPolicyRule) DeepCopy() *ReadOnlyPolicyRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReadOnlyPolicyRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReadOnlyPolicySpec) DeepCopyInto(out *ReadOnlyPolicySpec) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]ReadOnlyPolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadOnlyPolicySpec.
|
||||
func (in *ReadOnlyPolicySpec) DeepCopy() *ReadOnlyPolicySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReadOnlyPolicySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RefObjectsComponentSpec) DeepCopyInto(out *RefObjectsComponentSpec) {
|
||||
*out = *in
|
||||
@@ -720,6 +758,44 @@ func (in *SharedResourcePolicySpec) DeepCopy() *SharedResourcePolicySpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TakeOverPolicyRule) DeepCopyInto(out *TakeOverPolicyRule) {
|
||||
*out = *in
|
||||
in.Selector.DeepCopyInto(&out.Selector)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TakeOverPolicyRule.
|
||||
func (in *TakeOverPolicyRule) DeepCopy() *TakeOverPolicyRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TakeOverPolicyRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TakeOverPolicySpec) DeepCopyInto(out *TakeOverPolicySpec) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]TakeOverPolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TakeOverPolicySpec.
|
||||
func (in *TakeOverPolicySpec) DeepCopy() *TakeOverPolicySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TakeOverPolicySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TopologyPolicySpec) DeepCopyInto(out *TopologyPolicySpec) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user