From ec5e2b46606357aed7b74a081f490e55747b54f2 Mon Sep 17 00:00:00 2001 From: yangsoon Date: Wed, 24 Nov 2021 11:09:50 +0800 Subject: [PATCH] Fix: clean up the view api (#2779) --- .../velaql-views/component-pod-view.yaml | 53 ++++++++++------ .../templates/velaql-views/pod-view.yaml | 34 ++++++----- docs/examples/velaql-views/usage.md | 61 ++++++++++++------- go.mod | 1 - go.sum | 15 ----- pkg/stdlib/pkgs/time.cue | 1 - pkg/velaql/providers/query/handler.go | 8 ++- pkg/workflow/providers/time/date.go | 12 +--- pkg/workflow/providers/time/date_test.go | 60 ++++++++++++++++++ 9 files changed, 161 insertions(+), 84 deletions(-) diff --git a/charts/vela-core/templates/velaql-views/component-pod-view.yaml b/charts/vela-core/templates/velaql-views/component-pod-view.yaml index e16ec99b8..c76d90109 100644 --- a/charts/vela-core/templates/velaql-views/component-pod-view.yaml +++ b/charts/vela-core/templates/velaql-views/component-pod-view.yaml @@ -8,6 +8,7 @@ data: import ( "vela/ql" "vela/op" + "strings" ) parameter: { @@ -47,28 +48,44 @@ data: } } } - - podsWithCluster: [ for pods in collectedPods for podObj in pods.list { + podsWithCluster: [ for pods in collectedPods if pods.list != _|_ for podObj in pods.list { cluster: pods.cluster obj: podObj + workload: { + apiVersion: pods.value.apiVersion + kind: pods.value.kind + } }] - + podsError: [ for pods in collectedPods if pods.err != _|_ {pods.err}] status: { - podList: [ for pod in podsWithCluster { - clusterName: pod.cluster - revision: appRev - publishVersion: appPublishVersion - deployVersion: appDeployVersion - podName: pod.obj.metadata.name - podNs: pod.obj.metadata.namespace - status: pod.obj.status.phase - // refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase - if status != "Pending" && status != "Unknown" { - podIP: pod.obj.status.podIP - hostIP: pod.obj.status.hostIP - nodeName: pod.obj.spec.nodeName - } - }] + if len(podsError) == 0 { + podList: [ for pod in podsWithCluster { + cluster: pod.cluster + workload: pod.workload + metadata: { + name: pod.obj.metadata.name + namespace: pod.obj.metadata.namespace + creationTime: pod.obj.metadata.creationTimestamp + version: { + revision: appRev + publishVersion: appPublishVersion + deployVersion: appDeployVersion + } + } + status: { + phase: pod.obj.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 + } + } + }] + } + if len(podsError) != 0 { + error: strings.Join(podsError, ",") + } } } diff --git a/charts/vela-core/templates/velaql-views/pod-view.yaml b/charts/vela-core/templates/velaql-views/pod-view.yaml index 9ba8258d0..5bbb7bb60 100644 --- a/charts/vela-core/templates/velaql-views/pod-view.yaml +++ b/charts/vela-core/templates/velaql-views/pod-view.yaml @@ -36,7 +36,7 @@ data: cluster: parameter.cluster } - usageMetrics: ql.#Read & { + podMetrics: ql.#Read & { cluster: parameter.cluster value: { apiVersion: "metrics.k8s.io/v1beta1" @@ -53,21 +53,26 @@ data: containers: [ for container in pod.value.spec.containers { name: container.name image: container.image - status: {for containerStatus in pod.value.status.containerStatuses { - if containerStatus.name == container.name { - state: containerStatus.state - restartCount: containerStatus.restartCount + resources: { + if container.resources.limits != _|_ { + limits: container.resources.limits + } + if container.resources.requests != _|_ { + requests: container.resources.requests + } + if podMetrics.err == _|_ { + usage: {for containerUsage in podMetrics.value.containers { + if containerUsage.name == container.name { + cpu: containerUsage.usage.cpu + memory: containerUsage.usage.memory + } + }} } - }} - resource: container.resources - if usageMetrics.err == _|_ { - usageResource: {for containerUsage in usageMetrics.value.containers { - if containerUsage.name == container.name { - cpu: containerUsage.usage.cpu - memory: containerUsage.usage.memory - } - }} } + status: {for containerStatus in pod.value.status.containerStatuses if containerStatus.name == container.name { + state: containerStatus.state + restartCount: containerStatus.restartCount + }} }] if eventList.err == _|_ { events: eventList.list @@ -77,4 +82,3 @@ data: error: pod.err } } - diff --git a/docs/examples/velaql-views/usage.md b/docs/examples/velaql-views/usage.md index c39b69559..9fe4d7695 100644 --- a/docs/examples/velaql-views/usage.md +++ b/docs/examples/velaql-views/usage.md @@ -41,17 +41,30 @@ parameter: { ``` // query successful status: { - podList: [{ - clusterName: string - revision: string - publishVersion: string - podName: string - podNs: string - status: string - podIP: string - hostIP: string - nodeName: string - }] + podList: [{ + cluster: string + worload: { + apiVersion: string + kind: string + } + metadata: { + name: string + namespace: string + creationTime: string + version: { + revision: string + publishVersion: string + deployVersion: string + } + } + status: { + phase: "Pending" | "Running" | "Succeeded" | "Failed" | "Unknown" + // if phase == "Pending" or "Unknown": podIP, hostIP, nodeName will be empty + podIP: string + hostIP: string + nodeName: strin + } + }] } // query failed @@ -91,14 +104,10 @@ parameter: { ``` // query successful status: { - containers: [ { + containers: [{ name: string image: string - status: { - state: string - restartCount: string - } - resource: { + resources: { limits: { cpu: string memory: string @@ -107,13 +116,23 @@ status: { cpu: string memory: string } + usage: { + cpu: string + memory: string + } } - usageResource: { - cpu: string - memory: string + status: { + // state holds a possible state of container. + // only one of its members may be specified. + state: { + running: {...} + waiting: {...} + terminated: {...} + } + restartCount: string } }] - events: [...corev1.Event] + events: [...v1.Event] } // query failed diff --git a/go.mod b/go.mod index af0941a88..ce96d954d 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,6 @@ require ( github.com/emicklei/go-restful/v3 v3.0.0-rc2 github.com/evanphx/json-patch v4.11.0+incompatible github.com/fatih/color v1.12.0 - github.com/fluxcd/helm-controller/api v0.12.1 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/gertd/go-pluralize v0.1.7 github.com/getkin/kin-openapi v0.34.0 diff --git a/go.sum b/go.sum index 2cafafc28..b30343b01 100644 --- a/go.sum +++ b/go.sum @@ -480,14 +480,6 @@ github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/helm-controller/api v0.12.1 h1:rDyhMPvbhCxslqiNNG4nlfDCeYgrk6D+1ZKLsBS/Irs= -github.com/fluxcd/helm-controller/api v0.12.1/go.mod h1:zWmzV0s2SU4rEIGLPTt+dsaMs40OsNQgSgOATgJmxB0= -github.com/fluxcd/pkg/apis/kustomize v0.1.0 h1:sauL+KHmZ0zV2ZgpsLMyDzCQudBTtaFzSys+rXn9g9w= -github.com/fluxcd/pkg/apis/kustomize v0.1.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII= -github.com/fluxcd/pkg/apis/meta v0.10.0 h1:N7wVGHC1cyPdT87hrDC7UwCwRwnZdQM46PBSLjG2rlE= -github.com/fluxcd/pkg/apis/meta v0.10.0/go.mod h1:CW9X9ijMTpNe7BwnokiUOrLl/h13miwVr/3abEQLbKE= -github.com/fluxcd/pkg/runtime v0.12.0 h1:BPZZ8bBkimpqGAPXqOf3LTaw+tcw6HgbWyCuzbbsJGs= -github.com/fluxcd/pkg/runtime v0.12.0/go.mod h1:EyaTR2TOYcjL5U//C4yH3bt2tvTgIOSXpVRbWxUn/C4= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -898,7 +890,6 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -909,7 +900,6 @@ github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -2454,7 +2444,6 @@ k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M= k8s.io/apiextensions-apiserver v0.21.0/go.mod h1:gsQGNtGkc/YoDG9loKI0V+oLZM4ljRPjc/sql5tmvzc= -k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE= k8s.io/apiextensions-apiserver v0.22.1 h1:YSJYzlFNFSfUle+yeEXX0lSQyLEoxoPJySRupepb0gE= @@ -2485,7 +2474,6 @@ k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.18.6/go.mod h1:Zt2XvTHuaZjBz6EFYzpp+X4hTmgWGy8AthNVnTdm3Wg= k8s.io/apiserver v0.21.0/go.mod h1:w2YSn4/WIwYuxG5zJmcqtRdtqgW/J2JRgFAqps3bBpg= -k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw= k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU= k8s.io/apiserver v0.22.1 h1:Ul9Iv8OMB2s45h2tl5XWPpAZo1VPIJ/6N+MESeed7L8= @@ -2517,7 +2505,6 @@ k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRV k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.20.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/code-generator v0.21.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= -k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo= k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= @@ -2528,7 +2515,6 @@ k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmD k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14= k8s.io/component-base v0.20.10/go.mod h1:ZKOEin1xu68aJzxgzl5DZSp5J1IrjAOPlPN90/t6OI8= k8s.io/component-base v0.21.0/go.mod h1:qvtjz6X0USWXbgmbfXR+Agik4RZ3jv2Bgr5QnZzdPYw= -k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc= k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ= k8s.io/component-base v0.22.1 h1:SFqIXsEN3v3Kkr1bS6rstrs1wd45StJqbtgbQ4nRQdo= @@ -2610,7 +2596,6 @@ sigs.k8s.io/apiserver-runtime v1.0.3-0.20210913073608-0663f60bfee2 h1:c6RYHA1wUg sigs.k8s.io/apiserver-runtime v1.0.3-0.20210913073608-0663f60bfee2/go.mod h1:gvPfh5FX3Wi3kIRpkh7qvY0i/DQl3SDpRtvqMGZE3Vo= sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E= -sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aKdvJt9wuu0zk= sigs.k8s.io/controller-runtime v0.9.5 h1:WThcFE6cqctTn2jCZprLICO6BaKZfhsT37uAapTNfxc= sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= diff --git a/pkg/stdlib/pkgs/time.cue b/pkg/stdlib/pkgs/time.cue index f3945b6a2..a5faca6b3 100644 --- a/pkg/stdlib/pkgs/time.cue +++ b/pkg/stdlib/pkgs/time.cue @@ -15,7 +15,6 @@ timestamp: int64 layout: *"" | string - location: *"" | string date?: string ... diff --git a/pkg/velaql/providers/query/handler.go b/pkg/velaql/providers/query/handler.go index e41fa1a09..942aa9175 100644 --- a/pkg/velaql/providers/query/handler.go +++ b/pkg/velaql/providers/query/handler.go @@ -19,10 +19,10 @@ package query import ( stdctx "context" - fluxcdv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/oam-dev/kubevela/pkg/cue/model/value" @@ -35,8 +35,12 @@ import ( const ( // ProviderName is provider name for install. ProviderName = "query" + // HelmReleaseKind is the kind of HelmRelease + HelmReleaseKind = "HelmRelease" ) +var fluxcdGroupVersion = schema.GroupVersion{Group: "helm.toolkit.fluxcd.io", Version: "v2beta1"} + type provider struct { cli client.Client } @@ -113,7 +117,7 @@ func (h *provider) CollectPods(ctx wfContext.Context, v *value.Value, act types. var collector PodCollector switch obj.GroupVersionKind() { - case fluxcdv2beta1.GroupVersion.WithKind(fluxcdv2beta1.HelmReleaseKind): + case fluxcdGroupVersion.WithKind(HelmReleaseKind): collector = helmReleasePodCollector default: collector = NewPodCollector(obj.GroupVersionKind()) diff --git a/pkg/workflow/providers/time/date.go b/pkg/workflow/providers/time/date.go index bf79e64a2..5cdf58961 100644 --- a/pkg/workflow/providers/time/date.go +++ b/pkg/workflow/providers/time/date.go @@ -61,22 +61,12 @@ func (h *provider) Date(ctx wfContext.Context, v *value.Value, act types.Action) if err != nil { return err } - locationName, err := v.GetString("location") - if err != nil { - return err - } if layout == "" { layout = time.RFC3339 } - - location, err := time.LoadLocation(locationName) - if err != nil { - return err - } t := time.Unix(timestamp, 0) - t.In(location) - return v.FillObject(t.Format(layout), "date") + return v.FillObject(t.UTC().Format(layout), "date") } // Install register handlers to provider discover. diff --git a/pkg/workflow/providers/time/date_test.go b/pkg/workflow/providers/time/date_test.go index e1cd80251..62e050483 100644 --- a/pkg/workflow/providers/time/date_test.go +++ b/pkg/workflow/providers/time/date_test.go @@ -89,6 +89,66 @@ layout: "Mon, 02 Jan 2006 15:04:05 MST"`, } } +func TestDate(t *testing.T) { + testcases := map[string]struct { + from string + expected string + expectedErr error + }{ + "test convert timestamp to default time layout": { + from: `timestamp: 1636249671 +layout: "" +`, + expected: "2021-11-07T01:47:51Z", + expectedErr: nil, + }, + "test convert date to RFC3339 layout": { + from: `timestamp: 1636249671 +layout: "2006-01-02T15:04:05Z07:00" +`, + expected: "2021-11-07T01:47:51Z", + expectedErr: nil, + }, + "test convert date to RFC1123 layout": { + from: `timestamp: 1551452400 +layout: "Mon, 02 Jan 2006 15:04:05 MST" +`, + expected: "Fri, 01 Mar 2019 15:00:00 UTC", + expectedErr: nil, + }, + "test convert date without time layout": { + from: `timestamp: 1551452400`, + expected: "", + expectedErr: errors.New("var(path=layout) not exist"), + }, + "test convert without timestamp": { + from: ``, + expected: "", + expectedErr: errors.New("var(path=timestamp) not exist"), + }, + } + + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + r := require.New(t) + v, err := value.NewValue(tc.from, nil, "") + r.NoError(err) + prd := &provider{} + err = prd.Date(nil, v, nil) + if tc.expectedErr != nil { + r.Equal(tc.expectedErr.Error(), err.Error()) + return + } + r.NoError(err) + expected, err := v.LookupValue("date") + r.NoError(err) + ret, err := expected.CueValue().String() + r.NoError(err) + r.Equal(tc.expected, ret) + }) + } +} + func TestInstall(t *testing.T) { p := providers.NewProviders() Install(p)