[Backport release-1.5] Feat: refactor CLI commands related to resources (#4514)

* Feat: refactor CLI commands related to resources

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit dacefcac80)

* Fix: remove the old test case.

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit ef9fbaa22f)

* Fix: e2e test

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 6f412f5b45)

* Fix: optimize test cases

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 501d7cfad7)

* Feat: rename 'vela pods' to 'vela status --pod'

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 2d6ad41afc)

* Feat: optimize the e2e test case

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit afa786a096)

* Fix: sort the objects

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 619e9b1b5f)

* Fix: optimize the e2e test case

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit d6688c40b5)

* Fix: list the pod by the labels

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit aec1791ac1)

* Fix: order the tree resource

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit f51abadec3)

* Fix: set multicluster config

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 767b0020e5)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
github-actions[bot]
2022-08-01 19:46:20 +08:00
committed by GitHub
co-authored by barnettZQG
parent 1b21db979f
commit 3a9e5ccd5d
36 changed files with 1919 additions and 1059 deletions
+37 -118
View File
@@ -7,119 +7,45 @@ data:
template: |
import (
"vela/ql"
"vela/op"
"strings"
)
)
parameter: {
appName: string
appNs: string
name?: string
cluster?: string
clusterNs?: string
}
parameter: {
appName: string
appNs: string
name?: string
cluster?: string
clusterNs?: string
}
annotationDeployVersion: "app.oam.dev/deployVersion"
annotationPublishVersion: "app.oam.dev/publishVersion"
labelComponentName: "app.oam.dev/component"
ignoreCollectPodKindMap: {
"ConfigMap": true
"Endpoints": true
"LimitRange": true
"Namespace": true
"Node": true
"PersistentVolumeClaim": true
"PersistentVolume": true
"ReplicationController": true
"ResourceQuota": true
"ServiceAccount": true
"Service": true
"Event": true
"Ingress": true
"StorageClass": true
"NetworkPolicy": true
"PodDisruptionBudget": true
"PodSecurityPolicy": true
"PriorityClass": true
"CustomResourceDefinition": true
"HorizontalPodAutoscaler": true
"CertificateSigningRequest": true
"ManagedCluster": true
"ManagedClusterSetBinding": true
"ManagedClusterSet": true
"ApplicationRevision": true
"ComponentDefinition": true
"DefinitionRevision": true
"EnvBinding": true
"PolicyDefinition": true
"ResourceTracker": true
"ScopeDefinition": true
"TraitDefinition": true
"WorkflowStepDefinition": true
"WorkloadDefinition": true
"GitRepository": true
"HelmRepository": true
"ComponentStatus": true
}
resources: ql.#ListResourcesInApp & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
if parameter.cluster != _|_ {
cluster: parameter.cluster
}
if parameter.clusterNs != _|_ {
clusterNamespace: parameter.clusterNs
}
if parameter.name != _|_ {
components: [parameter.name]
result: ql.#CollectPods & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
if parameter.cluster != _|_ {
cluster: parameter.cluster
}
if parameter.clusterNs != _|_ {
clusterNamespace: parameter.clusterNs
}
if parameter.name != _|_ {
components: [parameter.name]
}
}
}
}
}
if resources.err == _|_ {
collectedPods: op.#Steps & {
for i, resource in resources.list if ignoreCollectPodKindMap[resource.object.kind] == _|_ {
"\(i)": ql.#CollectPods & {
value: resource.object
cluster: resource.cluster
}
}
}
podsWithCluster: [ for pods in collectedPods if pods.list != _|_ && pods.list != null for podObj in pods.list {
cluster: pods.cluster
obj: podObj
workload: {
apiVersion: pods.value.apiVersion
kind: pods.value.kind
name: pods.value.metadata.name
namespace: pods.value.metadata.namespace
}
if pods.value.metadata.labels[labelComponentName] != _|_ {
component: pods.value.metadata.labels[labelComponentName]
}
if pods.value.metadata.annotations[annotationPublishVersion] != _|_ {
publishVersion: pods.value.metadata.annotations[annotationPublishVersion]
}
if pods.value.metadata.annotations[annotationDeployVersion] != _|_ {
deployVersion: pods.value.metadata.annotations[annotationDeployVersion]
}
}]
podsError: [ for pods in collectedPods if pods.err != _|_ {pods.err}]
status: {
if len(podsError) == 0 && podsWithCluster != _|_ {
podList: [ for pod in podsWithCluster {
if result.err == _|_ {
status: {
podList: [ for pod in result.list if pod.object != _|_ {
cluster: pod.cluster
workload: pod.workload
component: pod.component
metadata: {
name: pod.obj.metadata.name
namespace: pod.obj.metadata.namespace
creationTime: pod.obj.metadata.creationTimestamp
name: pod.object.metadata.name
namespace: pod.object.metadata.namespace
creationTime: pod.object.metadata.creationTimestamp
labels: pod.object.metadata.labels
version: {
if pod.publishVersion != _|_ {
publishVersion: pod.publishVersion
@@ -130,27 +56,20 @@ data:
}
}
status: {
phase: pod.obj.status.phase
phase: pod.object.status.phase
// refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
if phase != "Pending" && phase != "Unknown" {
podIP: pod.obj.status.podIP
hostIP: pod.obj.status.hostIP
nodeName: pod.obj.spec.nodeName
podIP: pod.object.status.podIP
hostIP: pod.object.status.hostIP
nodeName: pod.object.spec.nodeName
}
}
}]
}
if len(podsError) != 0 {
error: strings.Join(podsError, ",")
}
if podsWithCluster == _|_ {
podList: []
}
}
}
if resources.err != _|_ {
status: {
error: resources.err
if result.err != _|_ {
status: {
error: result.err
}
}
}
@@ -0,0 +1,48 @@
apiVersion: v1
data:
template: |
import (
"vela/ql"
)
parameter: {
appName: string
appNs: string
name?: string
cluster?: string
clusterNs?: string
}
result: ql.#CollectServices & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
if parameter.cluster != _|_ {
cluster: parameter.cluster
}
if parameter.clusterNs != _|_ {
clusterNamespace: parameter.clusterNs
}
if parameter.name != _|_ {
components: [parameter.name]
}
}
}
}
if result.err == _|_ {
status: {
services: result.list
}
}
if result.err != _|_ {
status: {
error: result.err
}
}
kind: ConfigMap
metadata:
name: test-component-service-view
namespace: vela-system
+21 -5
View File
@@ -52,6 +52,11 @@ type Status struct {
Error string `json:"error,omitempty"`
}
type Services struct {
Services []types2.ResourceItem `json:"services,omitempty"`
Error string `json:"error,omitempty"`
}
var _ = Describe("Test velaQL rest api", func() {
namespace := "test-velaql"
appName := "example-app"
@@ -85,7 +90,7 @@ var _ = Describe("Test velaQL rest api", func() {
return errors.Errorf("expect the applied resources number is %d, but get %d", 3, len(oldApp.Status.AppliedResources))
}
return nil
}, 3*time.Second).WithTimeout(time.Minute * 1).Should(BeNil())
}).WithTimeout(time.Minute * 1).WithPolling(3 * time.Second).Should(BeNil())
queryRes := get(fmt.Sprintf("/query?velaql=%s{name=%s,namespace=%s}.%s", "read-view", appName, namespace, "output.value.spec"))
var appSpec v1beta1.ApplicationSpec
@@ -102,11 +107,14 @@ var _ = Describe("Test velaQL rest api", func() {
Expect(queryRes.StatusCode).Should(Equal(400))
})
It("Test query application component view", func() {
It("Test query application pod and service view", func() {
componentView := new(corev1.ConfigMap)
serviceView := new(corev1.ConfigMap)
Expect(common.ReadYamlToObject("./testdata/component-pod-view.yaml", componentView)).Should(BeNil())
Expect(common.ReadYamlToObject("./testdata/component-service-view.yaml", serviceView)).Should(BeNil())
Expect(k8sClient.Delete(context.Background(), componentView)).Should(SatisfyAny(BeNil(), &util.NotFoundMatcher{}))
Expect(k8sClient.Create(context.Background(), componentView)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
Expect(k8sClient.Create(context.Background(), serviceView)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
oldApp := new(v1beta1.Application)
Eventually(func() error {
@@ -117,7 +125,7 @@ var _ = Describe("Test velaQL rest api", func() {
return errors.Errorf("expect the applied resources number is %d, but get %d", 3, len(oldApp.Status.AppliedResources))
}
return nil
}, 3*time.Second).WithTimeout(time.Minute * 3).Should(BeNil())
}).WithTimeout(time.Minute * 2).WithPolling(3 * time.Second).Should(BeNil())
Eventually(func(g Gomega) {
queryRes := get(fmt.Sprintf("/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component1Name, "status"))
@@ -125,7 +133,7 @@ var _ = Describe("Test velaQL rest api", func() {
g.Expect(decodeResponseBody(queryRes, status)).Should(Succeed())
g.Expect(len(status.PodList)).Should(Equal(1))
g.Expect(status.PodList[0].Component).Should(Equal(component1Name))
}, 3*time.Second).WithTimeout(time.Minute * 3).Should(BeNil())
}, time.Minute*3, 3*time.Second).Should(BeNil())
Eventually(func() error {
queryRes1 := get(fmt.Sprintf("/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component2Name, "status"))
@@ -145,7 +153,15 @@ var _ = Describe("Test velaQL rest api", func() {
return errors.New("container name is not correct")
}
return nil
}, 3*time.Second).WithTimeout(time.Minute * 1).Should(BeNil())
}, time.Minute*1, 3*time.Second).Should(BeNil())
Eventually(func(g Gomega) {
queryRes := get(fmt.Sprintf("/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-service-view", appName, namespace, component1Name, "status"))
status := new(Services)
g.Expect(decodeResponseBody(queryRes, status)).Should(Succeed())
g.Expect(len(status.Services)).Should(Equal(1))
g.Expect(status.Services[0].Component).Should(Equal(component1Name))
}, time.Minute*1, 3*time.Second).Should(BeNil())
})
It("Test collect pod from cronJob", func() {
@@ -57,12 +57,14 @@ var _ = Describe("Test multicluster CLI commands", func() {
Expect(err).Should(Succeed())
Eventually(func(g Gomega) {
pods := &v1.PodList{}
g.Expect(k8sClient.List(workerCtx, pods, client.InNamespace(namespace))).Should(Succeed())
g.Expect(k8sClient.List(workerCtx, pods, client.InNamespace(namespace), client.MatchingLabels(map[string]string{
"app.oam.dev/name": app.Name,
}))).Should(Succeed())
g.Expect(len(pods.Items)).Should(Equal(1))
g.Expect(pods.Items[0].Status.Phase).Should(Equal(v1.PodRunning))
g.Expect(k8sClient.Get(hubCtx, client.ObjectKeyFromObject(app), app)).Should(Succeed())
g.Expect(len(app.Status.AppliedResources)).ShouldNot(Equal(0))
}, 2*time.Minute).Should(Succeed())
}, 2*time.Minute, time.Second*3).Should(Succeed())
})
AfterEach(func() {
@@ -76,8 +78,8 @@ var _ = Describe("Test multicluster CLI commands", func() {
It("Test vela exec", func() {
command := exec.Command("vela", "exec", app.Name, "-n", namespace, "-i=false", "-t=false", "--", "pwd")
outputs, err := command.CombinedOutput()
Expect(err).Should(Succeed())
Expect(string(outputs)).Should(ContainSubstring("/"))
Expect(err).Should(Succeed())
})
It("Test vela port-forward", func() {
@@ -9,7 +9,9 @@ spec:
type: webservice
properties:
image: crccheck/hello-world
port: 8000
ports:
- port: 8000
expose: true
traits:
- type: scaler
properties:
@@ -9,7 +9,9 @@ spec:
type: webservice
properties:
image: crccheck/hello-world
port: 8000
ports:
- port: 8000
expose: true
traits:
- type: scaler
properties:
@@ -9,20 +9,19 @@ spec:
type: webservice
properties:
image: crccheck/hello-world
port: 8000
ports:
- port: 8000
expose: true
policies:
- name: env-policy
type: env-binding
type: topology
properties:
envs:
- name: test
placement:
clusterSelector:
name: cluster-worker
clusters:
- cluster-worker
workflow:
steps:
- name: deploy-test
type: deploy2env
type: deploy
properties:
policy: env-policy
env: test
policies:
- env-policy
@@ -9,7 +9,9 @@ spec:
type: webservice
properties:
image: crccheck/hello-world
port: 8000
ports:
- port: 8000
expose: true
type: webservice
traits:
- type: rollout