Feat: allow select resource by resource type for gc policy (#3598)

* Feat: allow select resource by resource type for gc policy

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>

* Modify match label key

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>

* Unified label key

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>
This commit is contained in:
Kunshuai Zhu
2022-04-12 18:51:07 +08:00
committed by GitHub
parent 0e97aa2291
commit 0c35753530
4 changed files with 102 additions and 5 deletions
@@ -45,12 +45,13 @@ type GarbageCollectPolicyRule struct {
}
// GarbageCollectPolicyRuleSelector select the targets of the rule
// if both traitTypes and componentTypes are specified, combination logic is OR
// if both traitTypes, oamTypes and componentTypes are specified, combination logic is OR
// if one resource is specified with conflict strategies, strategy as component go first.
type GarbageCollectPolicyRuleSelector struct {
CompNames []string `json:"componentNames"`
CompTypes []string `json:"componentTypes"`
TraitTypes []string `json:"traitTypes"`
CompNames []string `json:"componentNames"`
CompTypes []string `json:"componentTypes"`
OAMResourceTypes []string `json:"oamTypes"`
TraitTypes []string `json:"traitTypes"`
}
// GarbageCollectStrategy the strategy for target resource to recycle
@@ -69,10 +70,11 @@ const (
// FindStrategy find gc strategy for target resource
func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
for _, rule := range in.Rules {
var compName, compType, traitType string
var compName, compType, oamType, traitType string
if labels := manifest.GetLabels(); labels != nil {
compName = labels[oam.LabelAppComponent]
compType = labels[oam.WorkloadTypeLabel]
oamType = labels[oam.LabelOAMResourceType]
traitType = labels[oam.TraitTypeLabel]
}
match := func(src []string, val string) (found bool) {
@@ -83,6 +85,7 @@ func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructu
}
if match(rule.Selector.CompNames, compName) ||
match(rule.Selector.CompTypes, compType) ||
match(rule.Selector.OAMResourceTypes, oamType) ||
match(rule.Selector.TraitTypes, traitType) {
return &rule.Strategy
}
@@ -109,6 +109,18 @@ func TestGarbageCollectPolicySpec_FindStrategy(t *testing.T) {
}},
expectStrategy: GarbageCollectStrategyNever,
},
"resource type rule match": {
rules: []GarbageCollectPolicyRule{{
Selector: GarbageCollectPolicyRuleSelector{OAMResourceTypes: []string{"TRAIT"}},
Strategy: GarbageCollectStrategyNever,
}},
input: &unstructured.Unstructured{Object: map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{oam.LabelOAMResourceType: "TRAIT"},
},
}},
expectStrategy: GarbageCollectStrategyNever,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
@@ -291,6 +291,11 @@ func (in *GarbageCollectPolicyRuleSelector) DeepCopyInto(out *GarbageCollectPoli
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.OAMResourceTypes != nil {
in, out := &in.OAMResourceTypes, &out.OAMResourceTypes
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.TraitTypes != nil {
in, out := &in.TraitTypes, &out.TraitTypes
*out = make([]string, len(*in))
@@ -2,6 +2,8 @@
By leveraging the garbage-collect policy, users can persist some resources, which skip the normal garbage-collect process when application is updated.
### traitTypes
Take the following app as an example, in the garbage-collect policy, a rule is added which marks all the resources created by the `expose` trait to use the `onAppDelete` strategy. This will keep those services until application is deleted.
```shell
$ cat <<EOF | kubectl apply -f -
@@ -78,6 +80,8 @@ hello-world ClusterIP 10.96.160.208 <none> 8000/TCP 5m56s
hello-world-new ClusterIP 10.96.20.4 <none> 8000/TCP 13s
```
### componentTypes
Users can also keep component if they are deploying job-like components. Resources dispatched by `job-like-component` type component will be kept after application is deleted.
```yaml
@@ -100,6 +104,8 @@ spec:
strategy: never
```
### componentNames
A more straightforward way is to specify `compNames` to match specified components.
```yaml
apiVersion: core.oam.dev/v1beta1
@@ -124,3 +130,74 @@ spec:
- example-addon-namespace
strategy: never
```
### oamTypes
Users can also persist resources using `oamTypes`, where the values of `oamTypes` can be `TRAIT` and `WORKLOAD`.
```shell
$ cat <<EOF | kubectl apply -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: garbage-collect-app
spec:
components:
- name: hello-world
type: webservice
properties:
image: crccheck/hello-world
traits:
- type: expose
properties:
port: [8000]
policies:
- name: garbage-collect
type: garbage-collect
properties:
rules:
- selector:
oamTypes:
- TRAIT
strategy: onAppDelete
EOF
```
And then, let's modify the component name.
```shell
$ cat <<EOF | kubectl apply -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: garbage-collect-app
spec:
components:
- name: hello-world-new
type: webservice
properties:
image: crccheck/hello-world
traits:
- type: expose
properties:
port: [8000]
policies:
- name: garbage-collect
type: garbage-collect
properties:
rules:
- selector:
oamTypes:
- TRAIT
strategy: onAppDelete
EOF
```
List the service in cluster, you will find:
```shell
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world ClusterIP 10.96.31.209 <none> 8000/TCP 31s
hello-world-new ClusterIP 10.96.17.103 <none> 8000/TCP 5s
```