mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
[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 commitdacefcac80) * Fix: remove the old test case. Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commitef9fbaa22f) * Fix: e2e test Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit6f412f5b45) * Fix: optimize test cases Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit501d7cfad7) * Feat: rename 'vela pods' to 'vela status --pod' Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit2d6ad41afc) * Feat: optimize the e2e test case Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commitafa786a096) * Fix: sort the objects Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit619e9b1b5f) * Fix: optimize the e2e test case Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commitd6688c40b5) * Fix: list the pod by the labels Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commitaec1791ac1) * Fix: order the tree resource Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commitf51abadec3) * Fix: set multicluster config Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit767b0020e5) Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
co-authored by
barnettZQG
parent
1b21db979f
commit
3a9e5ccd5d
+37
-118
@@ -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
|
||||
@@ -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() {
|
||||
|
||||
+3
-1
@@ -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
-10
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user