From 48b18e08854f2462d604e058a88c5e0adcafb2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E9=87=91=E8=99=8E?= <1050780355@qq.com> Date: Mon, 1 Apr 2024 16:56:19 +0800 Subject: [PATCH] Launchpad (#4645) * update kafka monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * launchpad monitor * fix build error. Signed-off-by: yy Signed-off-by: yy --------- Signed-off-by: yy Co-authored-by: yy <56745951+lingdie@users.noreply.github.com> Co-authored-by: yy --- .github/workflows/services.yml | 4 +- .../providers/applaunchpad/deploy/Kubefile | 1 + .../deploy/manifests/deploy.yaml.tmpl | 2 + scripts/cloud/install.sh | 7 +- service/go.work | 1 + service/launchpad/Dockerfile | 9 ++ service/launchpad/Makefile | 55 +++++++ service/launchpad/README.md | 54 +++++++ service/launchpad/config/config.yml | 2 + service/launchpad/deploy/Kubefile | 5 + service/launchpad/deploy/README.md | 16 ++ .../launchpad/deploy/manifests/deploy.yaml | 86 +++++++++++ service/launchpad/go.mod | 10 ++ service/launchpad/main.go | 64 ++++++++ service/launchpad/request/req.go | 91 +++++++++++ service/launchpad/server/config.go | 29 ++++ service/launchpad/server/server.go | 143 ++++++++++++++++++ service/pkg/api/req.go | 52 ++++++- 18 files changed, 620 insertions(+), 11 deletions(-) create mode 100644 service/launchpad/Dockerfile create mode 100644 service/launchpad/Makefile create mode 100644 service/launchpad/README.md create mode 100644 service/launchpad/config/config.yml create mode 100644 service/launchpad/deploy/Kubefile create mode 100644 service/launchpad/deploy/README.md create mode 100644 service/launchpad/deploy/manifests/deploy.yaml create mode 100644 service/launchpad/go.mod create mode 100644 service/launchpad/main.go create mode 100644 service/launchpad/request/req.go create mode 100644 service/launchpad/server/config.go create mode 100644 service/launchpad/server/server.go diff --git a/.github/workflows/services.yml b/.github/workflows/services.yml index 84663dd790a..dfa2c0de0f4 100644 --- a/.github/workflows/services.yml +++ b/.github/workflows/services.yml @@ -87,7 +87,7 @@ jobs: strategy: matrix: ## TODO: add more modules - module: [database, pay, account, minio] + module: [database, pay, account, minio, launchpad] steps: - name: Checkout uses: actions/checkout@v3 @@ -182,7 +182,7 @@ jobs: strategy: matrix: ## TODO: add more modules - module: [database, pay, account, minio] + module: [database, pay, account, minio, launchpad] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/frontend/providers/applaunchpad/deploy/Kubefile b/frontend/providers/applaunchpad/deploy/Kubefile index 84190d982a7..162cfa9d750 100644 --- a/frontend/providers/applaunchpad/deploy/Kubefile +++ b/frontend/providers/applaunchpad/deploy/Kubefile @@ -10,5 +10,6 @@ ENV cloudPort="" ENV certSecretName="wildcard-cert" ENV ingressSecret="wildcard-cert" +ENv monitorUrl="http://database-monitor.sealos.svc.cluster.local:9090" CMD ["kubectl apply -f manifests"] diff --git a/frontend/providers/applaunchpad/deploy/manifests/deploy.yaml.tmpl b/frontend/providers/applaunchpad/deploy/manifests/deploy.yaml.tmpl index daed6ef667a..5ead4fa7cdf 100644 --- a/frontend/providers/applaunchpad/deploy/manifests/deploy.yaml.tmpl +++ b/frontend/providers/applaunchpad/deploy/manifests/deploy.yaml.tmpl @@ -45,6 +45,8 @@ spec: - env: - name: SEALOS_DOMAIN value: {{ .cloudDomain }} + - name: MONITOR_URL + value {{ .monitorUrl }} - name: DOMAIN_PORT value: "{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}" - name: INGRESS_SECRET diff --git a/scripts/cloud/install.sh b/scripts/cloud/install.sh index 8893b8e23e2..0db4ef129dc 100644 --- a/scripts/cloud/install.sh +++ b/scripts/cloud/install.sh @@ -29,7 +29,7 @@ openebs_version=${openebs_version:-"3.10.0"} ingress_nginx_version=${ingress_nginx_version:-"1.9.4"} kubeblocks_version=${kubeblocks_version:-"0.8.2"} metrics_server_version=${metrics_server_version:-"0.6.4"} -kube_prometheus_stack_version=${kube_prometheus_stack_version:-"0.70.0"} +victoria_metrics_k8s_stack_version=${victoria_metrics_k8s_stack_version:-"1.96.0"} # Define English and Chinese prompts @@ -256,7 +256,7 @@ init() { pull_image "kubeblocks-postgresql" "v${kubeblocks_version#v:-0.8.2}" pull_image "kubeblocks-mongodb" "v${kubeblocks_version#v:-0.8.2}" pull_image "metrics-server" "v${metrics_server_version#v:-0.6.4}" - pull_image "kube-prometheus-stack" "v${kube_prometheus_stack_version#v:-0.63.0}" + pull_image "victoria-metrics-k8s-stack" "v${victoria_metrics_k8s_stack_version#v:-1.96.0}" pull_image "sealos-cloud" "${cloud_version}" } @@ -649,7 +649,8 @@ EOF kbcli addon enable snapshot-controller get_prompt "installing_monitoring" - sealos run "${image_registry}/${image_repository}/kube-prometheus-stack:v${kube_prometheus_stack_version#v:-0.63.0}" + sealos run "${image_registry}/${image_repository}/victoria-metrics-k8s-stack:v${victoria_metrics_k8s_stack_version#v:-1.96.0}" + kubectl patch cm kb-addon-prometheus-server -n kb-system --patch-file $CLOUD_DIR/kb-addon-prometheus-server-patch.yaml get_prompt "patching_ingress" diff --git a/service/go.work b/service/go.work index cde7e3a370f..4f259e9101b 100644 --- a/service/go.work +++ b/service/go.work @@ -4,6 +4,7 @@ use ( ./database ./pay ./account + ./launchpad . ) diff --git a/service/launchpad/Dockerfile b/service/launchpad/Dockerfile new file mode 100644 index 00000000000..1352f47e5f0 --- /dev/null +++ b/service/launchpad/Dockerfile @@ -0,0 +1,9 @@ +# FROM scratch +FROM gcr.io/distroless/static:nonroot +# FROM gengweifeng/gcr-io-distroless-static-nonroot +ARG TARGETARCH +COPY bin/service-launchpad-$TARGETARCH /manager +EXPOSE 9090 +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/service/launchpad/Makefile b/service/launchpad/Makefile new file mode 100644 index 00000000000..fcb97c9aefd --- /dev/null +++ b/service/launchpad/Makefile @@ -0,0 +1,55 @@ +IMG ?= ghcr.io/labring/sealos-launchpad-service:latest + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +# only support linux, non cgo +PLATFORMS ?= linux_arm64 linux_amd64 +GOOS=linux +CGO_ENABLED=0 +GOARCH=$(shell go env GOARCH) + +GO_BUILD_FLAGS=-trimpath -ldflags "-s -w" + +.PHONY: all +all: build + +##@ General + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk commands is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Build + +.PHONY: clean +clean: + rm -f $(SERVICE_NAME) + +.PHONY: build +build: clean ## Build service-hub binary. + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) go build $(GO_BUILD_FLAGS) -o bin/manager main.go + +.PHONY: docker-build +docker-build: build + mv bin/manager bin/service-launchpad-${TARGETARCH} + docker build -t $(IMG) . + +.PHONY: docker-push +docker-push: + docker push $(IMG) diff --git a/service/launchpad/README.md b/service/launchpad/README.md new file mode 100644 index 00000000000..45dafd4f0d2 --- /dev/null +++ b/service/launchpad/README.md @@ -0,0 +1,54 @@ +# RESTServer + +## Description + +restserver for database monitoring + +## Getting Started + +### Running on the cluster + +1. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/sealos-cloud-database-monitor:tag +``` + +2. Deploy the restserver: + +```sh +kubectl apply -f deploy/manifests/ +``` + +### How it works + +To enable the database frontend application to retrieve monitoring data, you need to modify the environment variable `MONITOR_URL` of the frontend deployment to the corresponding address of the restserver. + +Additionally, to configure the data source, you need to set the environment variable `VM_SERVICE_HOST` of the restserver deployment to the correct address. + +``` +e.g. +http://prometheus.sealos.svc.cluster.local +``` + +## License + +Copyright 2023. + +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. \ No newline at end of file diff --git a/service/launchpad/config/config.yml b/service/launchpad/config/config.yml new file mode 100644 index 00000000000..cf416ad93f9 --- /dev/null +++ b/service/launchpad/config/config.yml @@ -0,0 +1,2 @@ +server: + addr: ":8428" \ No newline at end of file diff --git a/service/launchpad/deploy/Kubefile b/service/launchpad/deploy/Kubefile new file mode 100644 index 00000000000..035ec02f5a0 --- /dev/null +++ b/service/launchpad/deploy/Kubefile @@ -0,0 +1,5 @@ +FROM scratch +COPY registry registry +COPY manifests manifests + +CMD ["kubectl apply -f manifests/deploy.yaml"] \ No newline at end of file diff --git a/service/launchpad/deploy/README.md b/service/launchpad/deploy/README.md new file mode 100644 index 00000000000..8606792effb --- /dev/null +++ b/service/launchpad/deploy/README.md @@ -0,0 +1,16 @@ +### docker image build and deploy +```bash +make docker-build IMG=$(YourImageName) +# edit deploy/manifests/depoly.yaml and deploy +kubectl apply -f deploy/manifests/depoly.yaml +``` + +### cluster image build and deploy +```bash +``` + +### Victoria Metrics + +In order to prevent performance degradation or abnormal behavior caused by excessive data size in Prometheus, VictoriaMetrics is utilized for data collection. + +> By default, we use kb-prometheus-server for the data collection service. \ No newline at end of file diff --git a/service/launchpad/deploy/manifests/deploy.yaml b/service/launchpad/deploy/manifests/deploy.yaml new file mode 100644 index 00000000000..29cefd9f077 --- /dev/null +++ b/service/launchpad/deploy/manifests/deploy.yaml @@ -0,0 +1,86 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: launchpad-monitor + name: launchpad-monitor-config + namespace: sealos +data: + config.yml: | + server: + addr: ":8428" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: launchpad-monitor + name: launchpad-monitor-deployment + namespace: sealos +spec: + replicas: 1 + selector: + matchLabels: + app: launchpad-monitor + strategy: + type: Recreate + template: + metadata: + labels: + app: launchpad-monitor + spec: + containers: + - args: + - /config/config.yml + command: + - /manager + env: + - name: VM_SERVICE_HOST + value: http://vmsingle-victoria-metrics-k8s-stack.vm.svc:8429 + image: ghcr.io/labring/sealos-launchpad-service:latest + imagePullPolicy: Always + name: launchpad-monitor + ports: + - containerPort: 8428 + protocol: TCP + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /config + name: config-vol + dnsPolicy: ClusterFirst + restartPolicy: Always + volumes: + - configMap: + defaultMode: 420 + name: launchpad-monitor-config + name: config-vol +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: launchpad-monitor + name: launchpad-monitor + namespace: sealos +spec: + ports: + - name: http + port: 8428 + protocol: TCP + targetPort: 8428 + selector: + app: launchpad-monitor \ No newline at end of file diff --git a/service/launchpad/go.mod b/service/launchpad/go.mod new file mode 100644 index 00000000000..5705a45f2c0 --- /dev/null +++ b/service/launchpad/go.mod @@ -0,0 +1,10 @@ +module github.com/labring/sealos/service/launchpad + +go 1.20 + +require ( + github.com/labring/sealos/service v0.0.0-00010101000000-000000000000 + gopkg.in/yaml.v2 v2.4.0 +) + +replace github.com/labring/sealos/service => ../../service \ No newline at end of file diff --git a/service/launchpad/main.go b/service/launchpad/main.go new file mode 100644 index 00000000000..e945fd9e635 --- /dev/null +++ b/service/launchpad/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net" + "net/http" + "os" + + launchpadServer "github.com/labring/sealos/service/launchpad/server" +) + +type RestartableServer struct { + configFile string +} + +func (rs *RestartableServer) Serve(c *launchpadServer.Config) { + var vs, err = launchpadServer.NewVMServer(c) + if err != nil { + fmt.Printf("Failed to create auth server: %s\n", err) + return + } + + hs := &http.Server{ + Addr: c.Server.ListenAddress, + Handler: vs, + } + + var listener net.Listener + listener, err = net.Listen("tcp", c.Server.ListenAddress) + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("Serve on %s\n", c.Server.ListenAddress) + + if err := hs.Serve(listener); err != nil { + fmt.Println(err) + return + } +} + +func main() { + log.SetOutput(os.Stdout) // 将日志输出定向到标准输出(stdout) + log.SetFlags(log.LstdFlags | log.Lshortfile) + flag.Parse() + + cf := flag.Arg(0) + if cf == "" { + fmt.Println("Config file not sepcified") + return + } + + config, err := launchpadServer.InitConfig(cf) + if err != nil { + fmt.Println(err) + return + } + rs := RestartableServer{ + configFile: cf, + } + rs.Serve(config) +} diff --git a/service/launchpad/request/req.go b/service/launchpad/request/req.go new file mode 100644 index 00000000000..482d4100f58 --- /dev/null +++ b/service/launchpad/request/req.go @@ -0,0 +1,91 @@ +package request + +import ( + "bytes" + "fmt" + "github.com/labring/sealos/service/pkg/api" + "io" + "log" + "net/http" + "net/url" + "os" + "strings" +) + +func Request(addr string, params *bytes.Buffer) ([]byte, error) { + resp, err := http.Post(addr, "application/x-www-form-urlencoded", params) + + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + log.Printf("%v\n", resp) + return nil, fmt.Errorf("victoria metrics server: %s", resp.Status) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return body, nil +} + +func GetQuery(query *api.VMRequest) (string, error) { + var result string + switch query.Type { + case "cpu": + result = "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$pod.*\", namespace=\"$namespace\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{pod=~\"$pod.*\", namespace=\"$namespace\"}) by (pod)" + case "memory": + result = "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", pod=~\"$pod.*\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{pod=~\"$pod.*\", namespace=\"$namespace\"}) by (pod)" + case "average_cpu": + result = "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$pod.*\", namespace=\"$namespace\"}) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{pod=~\"$pod.*\", namespace=\"$namespace\"})" + case "average_memory": + result = "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", pod=~\"$pod.*\", namespace=\"$namespace\",container!=\"\", image!=\"\"}) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{pod=~\"$pod.*\", namespace=\"$namespace\"})" + default: + log.Println(query.Type) + } + podName := getPodName(query.LaunchPadName) + result = strings.ReplaceAll(strings.ReplaceAll(result, "$namespace", query.NS), "$pod", podName) + return result, nil +} + +func getPodName(str string) string { + index := strings.LastIndex(str, "-") + firstPart := str[:index] + return firstPart +} + +func VMNew(query *api.VMRequest) ([]byte, error) { + + result, _ := GetQuery(query) + + formData := url.Values{} + formData.Set("query", result) + if query.Range.Start != "" { + formData.Set("start", query.Range.Start) + formData.Set("end", query.Range.End) + formData.Set("step", query.Range.Step) + } else if query.Range.Time != "" { + formData.Set("time", query.Range.Time) + } + fmt.Println() + bf := bytes.NewBufferString(formData.Encode()) + + vmHost := GetVMServerFromEnv() + + if vmHost == "" { + return nil, api.ErrNoVMHost + } + + if len(formData.Get("start")) == 0 { + return Request(vmHost+"/api/v1/query", bf) + } + return Request(vmHost+"/api/v1/query_range", bf) +} + +func GetVMServerFromEnv() string { + return os.Getenv("VM_SERVICE_HOST") +} diff --git a/service/launchpad/server/config.go b/service/launchpad/server/config.go new file mode 100644 index 00000000000..6f69c92617d --- /dev/null +++ b/service/launchpad/server/config.go @@ -0,0 +1,29 @@ +package server + +import ( + "fmt" + "os" + + "gopkg.in/yaml.v2" +) + +type Config struct { + Server ServeConfig `yaml:"server"` +} + +type ServeConfig struct { + ListenAddress string `yaml:"addr"` +} + +func InitConfig(configPath string) (*Config, error) { + configData, err := os.ReadFile(configPath) + if err != nil { + return nil, fmt.Errorf("could not read %s: %s", configPath, err) + } + c := &Config{} + if err := yaml.Unmarshal(configData, c); err != nil { + return nil, fmt.Errorf("could not parse config: %s", err) + } + + return c, nil +} diff --git a/service/launchpad/server/server.go b/service/launchpad/server/server.go new file mode 100644 index 00000000000..affa8c8a8bd --- /dev/null +++ b/service/launchpad/server/server.go @@ -0,0 +1,143 @@ +package server + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "net/url" + "text/template" + + "github.com/labring/sealos/service/pkg/auth" + + "github.com/labring/sealos/service/launchpad/request" + "github.com/labring/sealos/service/pkg/api" +) + +type VMServer struct { + Config *Config +} + +func NewVMServer(c *Config) (*VMServer, error) { + vs := &VMServer{ + Config: c, + } + return vs, nil +} + +func (vs *VMServer) Authenticate(vr *api.VMRequest) error { + return auth.Authenticate(vr.NS, vr.Pwd) +} + +func (vs *VMServer) DBReq(vr *api.VMRequest) (*api.LaunchpadQueryResult, error) { + body, err := request.VMNew(vr) + if err != nil { + return nil, err + } + var result *api.LaunchpadQueryResult + if err := json.Unmarshal(body, &result); err != nil { + return nil, err + } + log.Print(result) + return result, nil +} + +func (vs *VMServer) ParseRequest(req *http.Request) (*api.VMRequest, error) { + vr := &api.VMRequest{} + + auth := req.Header.Get("Authorization") + + if pwd, err := url.PathUnescape(auth); err == nil { + vr.Pwd = pwd + } else { + return nil, err + } + if vr.Pwd == "" { + return nil, api.ErrEmptyKubeconfig + } + + if err := req.ParseForm(); err != nil { + return nil, err + } + + for key, val := range req.Form { + switch key { + case "step": + vr.Range.Step = val[0] + case "start": + vr.Range.Start = val[0] + case "end": + vr.Range.End = val[0] + case "time": + vr.Range.Time = val[0] + case "namespace": + vr.NS = val[0] + case "type": + vr.Type = val[0] + case "launchPadName": + vr.LaunchPadName = val[0] + } + } + + if vr.NS == "" { + return nil, api.ErrUncompleteParam + } + + return vr, nil +} + +// 获取客户端请求的信息 +func (vs *VMServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + pathPrefix := "" + switch { + case req.URL.Path == pathPrefix+"/query": + vs.doReqNew(rw, req) + default: + http.Error(rw, "Not found", http.StatusNotFound) + return + } +} + +func (vs *VMServer) doReqNew(rw http.ResponseWriter, req *http.Request) { + vr, err := vs.ParseRequest(req) + if err != nil { + http.Error(rw, fmt.Sprintf("Bad request (%s)", err), http.StatusBadRequest) + log.Printf("Bad request (%s)\n", err) + return + } + + if err := vs.Authenticate(vr); err != nil { + http.Error(rw, fmt.Sprintf("Authentication failed (%s)", err), http.StatusInternalServerError) + log.Printf("Authentication failed (%s)\n", err) + return + } + + res, err := vs.DBReq(vr) + if err != nil { + http.Error(rw, fmt.Sprintf("Query failed (%s)", err), http.StatusInternalServerError) + log.Printf("Query failed (%s)\n", err) + return + } + + result, err := json.Marshal(res) + if err != nil { + http.Error(rw, "Result failed (invalid query expression)", http.StatusInternalServerError) + log.Printf("Reulst failed (%s)\n", err) + return + } + + rw.Header().Set("Content-Type", "application/json") + + tmpl := template.New("responseTemplate").Delims("{{", "}}") + tmpl, err = tmpl.Parse(`{{.}}`) + if err != nil { + log.Printf("template failed: %s\n", err) + http.Error(rw, "Internal Server Error", http.StatusInternalServerError) + return + } + if err = tmpl.Execute(rw, string(result)); err != nil { + log.Printf("Reulst failed: %s\n", err) + http.Error(rw, "Internal Server Error", http.StatusInternalServerError) + return + } +} diff --git a/service/pkg/api/req.go b/service/pkg/api/req.go index ad21dba5be7..417f1680500 100644 --- a/service/pkg/api/req.go +++ b/service/pkg/api/req.go @@ -31,12 +31,44 @@ type QueryResult struct { } `json:"data"` } -var ( - ErrNoPromHost = errors.New("unable to get the prometheus host") - ErrUncompleteParam = errors.New("at least provide both namespace and query") - ErrEmptyKubeconfig = errors.New("empty kubeconfig") - ErrNilNs = errors.New("namespace not found") -) +type VMRequest struct { + User string + Pwd string + NS string + Type string + LaunchPadName string + Range VMRange +} + +type VMRange struct { + Start string `mapstructure:"start"` + End string `mapstructure:"end"` + Step string `mapstructure:"step"` + Time string `mapstructure:"time"` +} + +type LaunchpadQueryResult struct { + Status string `json:"status"` + IsPartial bool `json:"isPartial"` + Data Data `json:"data"` + Stats Stats `json:"stats"` +} + +type Data struct { + ResultType string `json:"resultType"` + Result []Result `json:"result"` +} + +type Result struct { + Metric map[string]string `json:"metric"` + Value []interface{} `json:"value"` + Values [][]interface{} `json:"values"` +} + +type Stats struct { + SeriesFetched string `json:"seriesFetched"` + ExecutionTimeMsec int `json:"executionTimeMsec"` +} var ( Mysql = map[string]string{ @@ -125,3 +157,11 @@ var ( "disk_used": "(max by (persistentvolumeclaim,namespace) (kubelet_volume_stats_used_bytes {namespace=~\"#\", persistentvolumeclaim=~\"data-@-(kafka-broker|kafka-server)-\\\\d\"}))", } ) + +var ( + ErrNoVMHost = errors.New("unable to get the victoria-metrics host") + ErrNoPromHost = errors.New("unable to get the prometheus host") + ErrUncompleteParam = errors.New("at least provide both namespace and query") + ErrEmptyKubeconfig = errors.New("empty kubeconfig") + ErrNilNs = errors.New("namespace not found") +)