├── .github └── workflows │ ├── build.yml │ ├── image-develop.yml │ ├── image-release.yml │ └── unittest.yml ├── .gitignore ├── Dockerfile ├── Dockerfile.local ├── LICENSE ├── Makefile ├── README.md ├── README_CN.md ├── api ├── api.go ├── api_test.go ├── application.go ├── application_test.go ├── certificate.go ├── certificate_test.go ├── config.go ├── config_test.go ├── function.go ├── function_test.go ├── init.go ├── init_test.go ├── module.go ├── module_test.go ├── namespace.go ├── namespace_test.go ├── node.go ├── node_test.go ├── object.go ├── object_deprecated.go ├── object_deprecated_test.go ├── object_test.go ├── property.go ├── property_test.go ├── quota.go ├── quota_test.go ├── registry.go ├── registry_test.go ├── secret.go ├── secret_test.go ├── sync.go ├── sync_test.go ├── validate.go ├── yaml.go ├── yaml_app_test.go └── yaml_test.go ├── cachemsg └── cache.go ├── common ├── config.go ├── constants.go ├── context.go ├── context_test.go ├── error.go ├── error_test.go ├── global.go ├── global_test.go ├── log.go ├── log_test.go ├── message.go ├── string.go ├── string_test.go ├── util │ ├── aes.go │ ├── aes_test.go │ ├── rsa.go │ └── rsa_test.go ├── utils.go ├── utils_test.go └── validate.go ├── config ├── config.go └── config_test.go ├── docs ├── baetyl-arch-v2.svg ├── contributing.md ├── contributing_cn.md └── logo_with_name.png ├── facade ├── application.go ├── application_test.go ├── config.go ├── config_test.go ├── facade.go ├── facade_test.go ├── secret.go └── secret_test.go ├── go.mod ├── go.sum ├── hack ├── boilerplate.go.txt └── update-codegen.sh ├── main.go ├── mock ├── api │ └── sync.go ├── facade │ └── facade.go ├── plugin │ ├── application.go │ ├── auth.go │ ├── cache.go │ ├── configuration.go │ ├── cron.go │ ├── csrf.go │ ├── decryption.go │ ├── function.go │ ├── index.go │ ├── jwt.go │ ├── license.go │ ├── lock.go │ ├── module.go │ ├── node.go │ ├── object.go │ ├── pki.go │ ├── property.go │ ├── pubsub.go │ ├── quota.go │ ├── resource.go │ ├── secret.go │ ├── shadow.go │ ├── sign.go │ ├── task.go │ └── tx_factory.go └── service │ ├── application.go │ ├── auth.go │ ├── cache.go │ ├── config.go │ ├── cron.go │ ├── function.go │ ├── index.go │ ├── init.go │ ├── license.go │ ├── locker.go │ ├── module.go │ ├── namespace.go │ ├── node.go │ ├── object.go │ ├── pki.go │ ├── property.go │ ├── quota.go │ ├── secret.go │ ├── sign.go │ ├── sync.go │ ├── system_app.go │ ├── task.go │ └── template.go ├── models ├── access_template.go ├── activation.go ├── application.go ├── application_status.go ├── batch.go ├── cache.go ├── callback.go ├── certificate.go ├── configuration.go ├── cron.go ├── device.go ├── device_driver.go ├── device_model.go ├── device_uplink.go ├── dmp.go ├── driver.go ├── duplicate.go ├── filter.go ├── function.go ├── gpu.go ├── index.go ├── listview.go ├── lock.go ├── mis.go ├── module.go ├── monitor.go ├── namespace.go ├── node.go ├── node_configuration.go ├── node_device.go ├── object.go ├── object_deprecated.go ├── property.go ├── quota.go ├── record.go ├── registry.go ├── remote.go ├── resource.go ├── secret.go ├── shadow.go ├── sync.go ├── sys_config.go ├── task.go └── yaml.go ├── plugin ├── application.go ├── auth.go ├── awss3 │ ├── awss3.go │ ├── awss3_config.go │ └── awss3_test.go ├── cache.go ├── cache │ └── localcache │ │ ├── cache.go │ │ ├── cache_config.go │ │ └── cache_test.go ├── configuration.go ├── cron.go ├── csrf.go ├── database │ ├── access_template.go │ ├── access_template_test.go │ ├── application.go │ ├── application_test.go │ ├── batch.go │ ├── batch_test.go │ ├── configuration.go │ ├── configuration_test.go │ ├── cron.go │ ├── cron_test.go │ ├── db.go │ ├── db_config.go │ ├── db_test.go │ ├── device.go │ ├── device_driver.go │ ├── device_driver_test.go │ ├── device_model.go │ ├── device_model_test.go │ ├── device_test.go │ ├── device_uplink.go │ ├── device_uplink_test.go │ ├── driver.go │ ├── driver_test.go │ ├── entities │ │ ├── access_template.go │ │ ├── access_template_test.go │ │ ├── application.go │ │ ├── application_test.go │ │ ├── batch.go │ │ ├── batch_test.go │ │ ├── configuration.go │ │ ├── configuration_test.go │ │ ├── cron_app.go │ │ ├── device.go │ │ ├── device_driver.go │ │ ├── device_driver_test.go │ │ ├── device_model.go │ │ ├── device_model_test.go │ │ ├── device_test.go │ │ ├── device_uplink.go │ │ ├── driver.go │ │ ├── driver_test.go │ │ ├── lock.go │ │ ├── module.go │ │ ├── namesapce.go │ │ ├── namespace_test.go │ │ ├── node.go │ │ ├── node_configuration.go │ │ ├── node_device.go │ │ ├── node_device_test.go │ │ ├── node_test.go │ │ ├── secret.go │ │ ├── secret_test.go │ │ ├── shadow.go │ │ ├── shadow_test.go │ │ ├── task.go │ │ └── task_test.go │ ├── index.go │ ├── index_test.go │ ├── lock.go │ ├── lock_test.go │ ├── module.go │ ├── module_test.go │ ├── namespace.go │ ├── namespace_test.go │ ├── node.go │ ├── node_configuration.go │ ├── node_configuration_test.go │ ├── node_device.go │ ├── node_device_test.go │ ├── node_test.go │ ├── pki.go │ ├── pki_test.go │ ├── property.go │ ├── property_test.go │ ├── record.go │ ├── record_test.go │ ├── secret.go │ ├── secret_test.go │ ├── shadow.go │ ├── shadow_test.go │ ├── task.go │ └── task_test.go ├── decryption.go ├── decryption │ ├── config.go │ ├── decryption.go │ └── decryption_test.go ├── default │ ├── auth │ │ ├── auth.go │ │ ├── auth_test.go │ │ └── config.go │ ├── csrf │ │ ├── config.go │ │ ├── csrf.go │ │ └── csrf_test.go │ ├── license │ │ ├── license.go │ │ └── license_test.go │ ├── lock │ │ ├── config.go │ │ ├── empty_lock.go │ │ └── empty_lock_test.go │ ├── pki │ │ ├── config.go │ │ ├── config_test.go │ │ ├── pki.go │ │ └── pki_test.go │ ├── quota │ │ ├── quota.go │ │ └── quota_test.go │ ├── sign │ │ ├── config.go │ │ ├── sign.go │ │ └── sign_test.go │ ├── task │ │ └── default_task.go │ └── transaction │ │ └── default_tx_factory.go ├── function.go ├── index.go ├── jwt.go ├── kube │ ├── apis │ │ └── cloud │ │ │ ├── register.go │ │ │ └── v1alpha1 │ │ │ ├── doc.go │ │ │ ├── register.go │ │ │ ├── types.go │ │ │ └── zz_generated.deepcopy.go │ ├── application.go │ ├── application_test.go │ ├── client.go │ ├── client │ │ └── clientset │ │ │ └── versioned │ │ │ ├── clientset.go │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── clientset_generated.go │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ ├── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ └── typed │ │ │ └── cloud │ │ │ └── v1alpha1 │ │ │ ├── application.go │ │ │ ├── cloud_client.go │ │ │ ├── configuration.go │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ ├── fake_application.go │ │ │ ├── fake_cloud_client.go │ │ │ ├── fake_configuration.go │ │ │ ├── fake_node.go │ │ │ ├── fake_nodedesire.go │ │ │ ├── fake_nodereport.go │ │ │ └── fake_secret.go │ │ │ ├── generated_expansion.go │ │ │ ├── node.go │ │ │ ├── nodedesire.go │ │ │ ├── nodereport.go │ │ │ └── secret.go │ ├── client_test.go │ ├── config.go │ ├── configuration.go │ ├── configuration_test.go │ ├── namespace.go │ ├── namespace_test.go │ ├── node.go │ ├── node_test.go │ ├── secret.go │ ├── secret_test.go │ ├── shadow.go │ └── shadow_test.go ├── license.go ├── link │ └── httplink │ │ ├── config.go │ │ ├── httplink.go │ │ ├── httplink_test.go │ │ └── wrapper.go ├── lock.go ├── module.go ├── namespace.go ├── node.go ├── object.go ├── pki.go ├── property.go ├── pubsub.go ├── quota.go ├── register.go ├── resource.go ├── secret.go ├── shadow.go ├── sign.go ├── sign │ ├── config.go │ ├── sign.go │ └── sign_test.go ├── sync_link.go ├── task.go └── tx_factory.go ├── scripts ├── charts │ └── baetyl-cloud │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── apply │ │ ├── crds.yml │ │ └── rbac_v1beta1.yml │ │ ├── apply_1.27.2 │ │ ├── crds.yml │ │ └── rbac.yml │ │ ├── apply_v1beta1 │ │ ├── crds_v1beta1.yml │ │ └── rbac.yml │ │ ├── certs │ │ ├── client_ca.crt │ │ ├── client_ca.key │ │ ├── server.crt │ │ ├── server.key │ │ └── server_ca.crt │ │ ├── conf │ │ ├── cloud.yml │ │ └── token.key │ │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yml │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ ├── secret.yml │ │ ├── service.yaml │ │ ├── serviceaccount.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ │ └── values.yaml ├── k8s │ ├── apply │ │ ├── baetyl-cloud-configmap.yml │ │ ├── baetyl-cloud-crds.yml │ │ ├── baetyl-cloud-deployment.yml │ │ ├── baetyl-cloud-rbac.yml │ │ ├── baetyl-cloud-service-account.yml │ │ └── baetyl-cloud-service.yml │ └── apply_v1beta1 │ │ ├── baetyl-cloud-configmap.yml │ │ ├── baetyl-cloud-crds_v1beta1.yml │ │ ├── baetyl-cloud-deployment.yml │ │ ├── baetyl-cloud-rbac.yml │ │ ├── baetyl-cloud-service-account.yml │ │ └── baetyl-cloud-service.yml ├── native │ ├── apply │ │ └── crds.yml │ ├── apply_v1beta1 │ │ └── crds_v1beta1.yml │ ├── certs │ │ ├── client_ca.crt │ │ ├── client_ca.key │ │ ├── server.crt │ │ ├── server.key │ │ └── server_ca.crt │ ├── conf │ │ ├── conf.yml │ │ ├── kubeconfig.yml │ │ └── token.key │ └── templates │ │ ├── baetyl-broker-app.yml │ │ ├── baetyl-broker-conf.yml │ │ ├── baetyl-core-app.yml │ │ ├── baetyl-core-conf.yml │ │ ├── baetyl-ekuiper-app.yml │ │ ├── baetyl-function-app.yml │ │ ├── baetyl-function-conf.yml │ │ ├── baetyl-init-app.yml │ │ ├── baetyl-init-conf.yml │ │ ├── baetyl-init-deployment.yml │ │ ├── baetyl-install.ps1 │ │ ├── baetyl-install.sh │ │ ├── baetyl-nodejs10-program.yml │ │ ├── baetyl-python3-opencv-program.yml │ │ ├── baetyl-python3-program.yml │ │ ├── baetyl-rule-app.yml │ │ ├── baetyl-rule-conf.yml │ │ └── baetyl-sql-program.yml └── sql │ ├── data.sql │ └── tables.sql ├── server ├── admin_server.go ├── admin_server_test.go ├── handler.go ├── init_server.go ├── init_server_test.go ├── mis_server.go ├── mis_server_test.go └── sync_server.go ├── service ├── application.go ├── application_test.go ├── auth.go ├── auth_test.go ├── cache.go ├── cache_test.go ├── config.go ├── config_test.go ├── cron.go ├── cron_test.go ├── function.go ├── function_test.go ├── index.go ├── index_test.go ├── init.go ├── init_test.go ├── license.go ├── license_test.go ├── locker.go ├── module.go ├── namespace.go ├── namespace_test.go ├── node.go ├── node_test.go ├── object.go ├── object_test.go ├── pki.go ├── pki_test.go ├── property.go ├── property_test.go ├── quota.go ├── quota_test.go ├── resource.go ├── secret.go ├── secret_test.go ├── service_test.go ├── sign.go ├── sync.go ├── sync_test.go ├── system_app.go ├── system_app_test.go ├── task.go ├── task_test.go ├── template.go ├── template_test.go ├── wrapper.go └── wrapper_test.go └── triggerfunc ├── trigger.go └── trigger_test.go /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: push 3 | 4 | jobs: 5 | build: 6 | name: build 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Setup Go 10 | uses: actions/setup-go@v1 11 | with: 12 | go-version: 1.20 13 | - name: Checkout code 14 | uses: actions/checkout@v1 15 | - name: Run unittest 16 | run: make test 17 | - name: Build 18 | run: make all 19 | - name: Upload coverage to Codecov 20 | uses: codecov/codecov-action@v1 21 | with: 22 | token: ${{ secrets.CODECOV_TOKEN }} 23 | file: ./coverage.txt -------------------------------------------------------------------------------- /.github/workflows/image-develop.yml: -------------------------------------------------------------------------------- 1 | name: image-develop 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | image: 9 | name: docker build images of function 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Install deps 13 | run: sudo apt update -y && sudo apt install -y qemu qemu-user-static 14 | - name: Install Docker CE for buildx 15 | run: | 16 | sudo apt update 17 | sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 18 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 19 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 20 | sudo apt update 21 | sudo apt install docker-ce 22 | docker -v 23 | - name: Checkout code 24 | uses: actions/checkout@v1 25 | - name: docker login 26 | run: | 27 | docker login -u ${{ secrets.DOCKER_REGISTRY_ID }} -p ${{ secrets.DOCKER_REGISTRY_PASS }} 28 | - name: build and publish image 29 | run: | 30 | make image PLATFORMS=all XFLAGS='--push --cache-to=type=local,dest=/tmp/main' REGISTRY=baetyltechtest/ 31 | -------------------------------------------------------------------------------- /.github/workflows/image-release.yml: -------------------------------------------------------------------------------- 1 | name: image-release 2 | on: 3 | push: 4 | tags: 5 | - 'v*' 6 | 7 | jobs: 8 | image: 9 | name: docker build images 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Install deps 13 | run: sudo apt update -y && sudo apt install -y qemu qemu-user-static 14 | - name: Install Docker CE for buildx 15 | run: | 16 | sudo apt update 17 | sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 18 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 19 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 20 | sudo apt update 21 | sudo apt install docker-ce 22 | docker -v 23 | - name: Checkout code 24 | uses: actions/checkout@v1 25 | - name: docker login 26 | run: | 27 | docker login -u ${{ secrets.DOCKER_REGISTRY_ID }} -p ${{ secrets.DOCKER_REGISTRY_PASS }} 28 | - name: build and publish image 29 | run: | 30 | make image PLATFORMS=all XFLAGS='--push --cache-to=type=local,dest=/tmp/main' REGISTRY=baetyltech/ 31 | -------------------------------------------------------------------------------- /.github/workflows/unittest.yml: -------------------------------------------------------------------------------- 1 | name: unittest 2 | on: pull_request 3 | 4 | jobs: 5 | test: 6 | name: unittest 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Setup Go 10 | uses: actions/setup-go@v1 11 | with: 12 | go-version: 1.20 13 | - name: Checkout code 14 | uses: actions/checkout@v1 15 | - name: Build 16 | run: make all 17 | - name: Run unittest 18 | run: make test 19 | - name: Upload coverage to Codecov 20 | uses: codecov/codecov-action@v1 21 | with: 22 | token: ${{ secrets.CODECOV_TOKEN }} 23 | file: ./coverage.txt 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | .svn 17 | .tmp 18 | .download 19 | .*.swp 20 | .*.swo 21 | .idea 22 | .vscode 23 | .DS_Store 24 | /vendor 25 | /output* 26 | coverage.* 27 | /etc 28 | /var 29 | output 30 | /baetyl-cloud 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:alpine AS builder 2 | ARG GOPROXY 3 | ARG GIT_REV 4 | ARG VERSION 5 | ARG TARGETARCH 6 | ARG TARGETOS 7 | COPY / /go/src/baetyl-cloud 8 | WORKDIR /go/src/baetyl-cloud 9 | ENV GOPROXY=${GOPROXY:-direct} 10 | RUN --mount=type=cache,id=gomod,target=/go/pkg/mod \ 11 | go mod download -x 12 | RUN --mount=type=cache,id=gomod,target=/go/pkg/mod \ 13 | GOARCH=${TARGETARCH} CGO_ENABLED=0 \ 14 | go build -ldflags "-s -w -X github.com/baetyl/baetyl-go/v2/utils.REVISION=${GIT_REV} -X github.com/baetyl/baetyl-go/v2/utils.VERSION=${VERSION}" . 15 | 16 | FROM scratch 17 | COPY /scripts/native/templates /etc/templates 18 | COPY --from=builder /go/src/baetyl-cloud/baetyl-cloud /bin/baetyl-cloud 19 | ENTRYPOINT ["/bin/baetyl-cloud"] 20 | -------------------------------------------------------------------------------- /Dockerfile.local: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | ARG GOPROXY 3 | ARG GIT_REV 4 | ARG VERSION 5 | COPY / /go/src/baetyl-cloud 6 | WORKDIR /go/src/baetyl-cloud 7 | ENV GOPROXY=${GOPROXY:-direct} 8 | RUN go mod download -x 9 | RUN CGO_ENABLED=0 \ 10 | go build -ldflags "-s -w -X github.com/baetyl/baetyl-go/v2/utils.REVISION=${GIT_REV} -X github.com/baetyl/baetyl-go/v2/utils.VERSION=${VERSION}" . 11 | 12 | FROM scratch 13 | COPY /scripts/native/templates /etc/templates 14 | COPY --from=builder /go/src/baetyl-cloud/baetyl-cloud /bin/baetyl-cloud 15 | ENTRYPOINT ["/bin/baetyl-cloud"] 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MODULE:=baetyl-cloud 2 | SRC_FILES:=$(shell find . -type f -name '*.go') 3 | 4 | export DOCKER_CLI_EXPERIMENTAL=enabled 5 | 6 | GIT_TAG:=$(shell git tag --contains HEAD|awk 'END {print}') 7 | GIT_REV:=git-$(shell git rev-parse --short HEAD) 8 | VERSION:=$(if $(GIT_TAG),$(GIT_TAG),$(GIT_REV)) 9 | 10 | GO_FLAGS:=-s -w -X github.com/baetyl/baetyl-go/v2/utils.REVISION=$(GIT_REV) -X github.com/baetyl/baetyl-go/v2/utils.VERSION=$(VERSION) 11 | GO_PROXY:=https://goproxy.cn 12 | GO_TEST_FLAGS:=-race -short -covermode=atomic -coverprofile=coverage.txt 13 | GO_TEST_PKGS:=$(shell go list ./...) 14 | 15 | REGISTRY?= 16 | 17 | .PHONY: all 18 | all: build 19 | 20 | .PHONY: build 21 | build: $(SRC_FILES) 22 | env GO111MODULE=on GOPROXY=$(GO_PROXY) CGO_ENABLED=0 go build -o output/$(MODULE) -ldflags "$(GO_FLAGS)" . 23 | 24 | .PHONY: local 25 | local: 26 | docker build \ 27 | -t $(MODULE):$(VERSION) \ 28 | --build-arg GOPROXY="$(GO_PROXY)" \ 29 | --build-arg GIT_REV="$(GIT_REV)" \ 30 | --build-arg VERSION="$(VERSION)" \ 31 | -f Dockerfile.local . 32 | 33 | .PHONY: image 34 | image: 35 | @echo "BUILDX: $(REGISTRY)$(MODULE):$(VERSION)" 36 | @-docker buildx create --name $(MODULE) 37 | @docker buildx use $(MODULE) 38 | docker buildx build --push \ 39 | --platform linux/amd64,linux/arm64,linux/arm/v7 \ 40 | -t $(REGISTRY)$(MODULE):$(VERSION) \ 41 | --build-arg GOPROXY="$(GO_PROXY)" \ 42 | --build-arg GIT_REV="$(GIT_REV)" \ 43 | --build-arg VERSION="$(VERSION)" \ 44 | -f Dockerfile . 45 | 46 | .PHONY: test 47 | test: fmt 48 | @go test ${GO_TEST_FLAGS} ${GO_TEST_PKGS} 49 | @go tool cover -func=coverage.txt | grep total 50 | 51 | .PHONY: fmt 52 | fmt: 53 | go fmt ./... 54 | 55 | .PHONY: clean 56 | clean: 57 | @rm -rf output 58 | -------------------------------------------------------------------------------- /api/namespace.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/log" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/common" 7 | "github.com/baetyl/baetyl-cloud/v2/models" 8 | ) 9 | 10 | // CreateNamespace create one namespace 11 | func (api *API) CreateNamespace(c *common.Context) (interface{}, error) { 12 | ns, err := api.NS.Create(&models.Namespace{ 13 | Name: c.GetNamespace(), 14 | }) 15 | if err != nil { 16 | return ns, err 17 | } 18 | if e := api.InitQuotas(ns.Name); e != nil { 19 | log.L().Error("InitQuotas error", log.Error(e)) 20 | } 21 | return ns, nil 22 | } 23 | 24 | // GetNamespace get one namespace 25 | func (api *API) GetNamespace(c *common.Context) (interface{}, error) { 26 | res, err := api.NS.Get(c.GetNamespace()) 27 | if res == nil { 28 | return nil, common.Error(common.ErrResourceNotFound, 29 | common.Field("type", "namespace"), 30 | common.Field("name", c.GetNamespace())) 31 | } 32 | return res, err 33 | } 34 | 35 | func (api *API) DeleteNamespace(c *common.Context) (interface{}, error) { 36 | ns := c.GetNamespace() 37 | _, err := api.NS.Get(ns) 38 | if err != nil { 39 | return nil, err 40 | } 41 | _, err = api.Task.AddTaskWithKey("DeleteNamespaceTask", map[string]interface{}{"ns": ns}) 42 | 43 | return nil, err 44 | } 45 | -------------------------------------------------------------------------------- /api/object_deprecated.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/common" 5 | "github.com/baetyl/baetyl-cloud/v2/models" 6 | ) 7 | 8 | // Deprecated 9 | // ListObjectSources ListObjectSources 10 | func (api *API) ListObjectSources(c *common.Context) (interface{}, error) { 11 | res2 := api.Obj.ListSources() 12 | res := []models.ObjectStorageSource{} 13 | for k := range res2 { 14 | res = append(res, models.ObjectStorageSource{ 15 | Name: k, 16 | }) 17 | } 18 | return &models.ObjectStorageSourceView{Sources: res}, nil 19 | } 20 | 21 | // Deprecated 22 | // ListBuckets ListBuckets 23 | func (api *API) ListBuckets(c *common.Context) (interface{}, error) { 24 | res, err := api.Obj.ListInternalBuckets(c.GetUser().ID, c.Param("source")) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return &models.BucketsView{Buckets: res}, err 29 | } 30 | 31 | // Deprecated 32 | // ListBucketObjects ListBucketObjects 33 | func (api *API) ListBucketObjects(c *common.Context) (interface{}, error) { 34 | id, bucket, source := c.GetUser().ID, c.Param("bucket"), c.Param("source") 35 | res, err := api.Obj.ListInternalBucketObjects(id, bucket, source) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | var objects []models.ObjectView 41 | for _, v := range res.Contents { 42 | view := models.ObjectView{Name: v.Key} 43 | objects = append(objects, view) 44 | } 45 | return &models.ObjectsView{Objects: objects}, err 46 | } 47 | -------------------------------------------------------------------------------- /api/property.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/common" 5 | "github.com/baetyl/baetyl-cloud/v2/models" 6 | ) 7 | 8 | func (api *API) GetProperty(c *common.Context) (interface{}, error) { 9 | return api.Prop.GetProperty(c.Param("name")) 10 | } 11 | 12 | func (api *API) CreateProperty(c *common.Context) (interface{}, error) { 13 | property := &models.Property{} 14 | err := c.LoadBody(property) 15 | if err != nil { 16 | return nil, err 17 | } 18 | return nil, api.Prop.CreateProperty(property) 19 | } 20 | 21 | func (api *API) DeleteProperty(c *common.Context) (interface{}, error) { 22 | return nil, api.Prop.DeleteProperty(c.Param("name")) 23 | } 24 | 25 | func (api *API) ListProperty(c *common.Context) (interface{}, error) { 26 | params := &models.Filter{} 27 | if err := c.Bind(params); err != nil { 28 | return nil, err 29 | } 30 | properties, err := api.Prop.ListProperty(params) 31 | if err != nil { 32 | return nil, err 33 | } 34 | count, err := api.Prop.CountProperty(params.Name) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return models.MisData{ 39 | Count: count, 40 | Rows: properties, 41 | }, nil 42 | } 43 | 44 | func (api *API) UpdateProperty(c *common.Context) (interface{}, error) { 45 | property := &models.Property{ 46 | Name: c.Param("name"), 47 | } 48 | err := c.LoadBody(property) 49 | if err != nil { 50 | return nil, err 51 | } 52 | return nil, api.Prop.UpdateProperty(property) 53 | } 54 | -------------------------------------------------------------------------------- /api/validate.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | 7 | "github.com/baetyl/baetyl-go/v2/json" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/common" 10 | ) 11 | 12 | // ValidateResourceForCreating validate when resource create 13 | func (api *API) ValidateResourceForCreating(c *common.Context) (interface{}, error) { 14 | resource := struct { 15 | Name string `json:"name,omitempty"` 16 | }{} 17 | 18 | buf, err := ioutil.ReadAll(c.Request.Body) 19 | if err != nil { 20 | return nil, err 21 | } 22 | c.Request.Body = ioutil.NopCloser(bytes.NewReader(buf[:])) 23 | 24 | err = json.Unmarshal(buf, &resource) 25 | if err != nil { 26 | return nil, common.Error(common.ErrRequestParamInvalid, common.Field("error", err.Error())) 27 | } 28 | 29 | if !common.ValidNonBaetyl(resource.Name) { 30 | return nil, common.Error(common.ErrInvalidName, common.Field("nonBaetyl", "Name")) 31 | } 32 | return nil, nil 33 | } 34 | 35 | // ValidateResourceForDeleting validate when resource delete 36 | func (api *API) ValidateResourceForDeleting(c *common.Context) (interface{}, error) { 37 | name := c.GetNameFromParam() 38 | if !common.ValidNonBaetyl(name) { 39 | return nil, common.Error(common.ErrInvalidName, common.Field("nonBaetyl", "Name")) 40 | } 41 | return nil, nil 42 | } 43 | -------------------------------------------------------------------------------- /cachemsg/cache.go: -------------------------------------------------------------------------------- 1 | package cachemsg 2 | 3 | import "fmt" 4 | 5 | const ( 6 | // AllShadowReportTimeCache set report time , type is map. ex :shadow-time : "{ "aaa": "0001-01-01T00:00:00Z", "d-33949349": "0001-01-01T00:00:00Z"}" 7 | AllShadowReportTimeCache = "shadow-%s-time" 8 | // ShadowReportDataCache set report cache ex: shadow-aaa-report : "{"apps": []}" 9 | ShadowReportDataCache = "shadow-%s-%s-report" 10 | // CacheReportSetLock set report cache running flag key 11 | CacheReportSetLock = "cache-report-lock" 12 | // CacheUpdateReportTimeLock set update report time cache running flag key 13 | CacheUpdateReportTimeLock = "cache-report-time-lock" 14 | ) 15 | 16 | // GetShadowReportTimeCacheKey GetShadowReportTime get namesapce report time key 17 | func GetShadowReportTimeCacheKey(namespace string) string { 18 | return fmt.Sprintf(AllShadowReportTimeCache, namespace) 19 | } 20 | 21 | // GetShadowReportCacheKey get node report key 22 | func GetShadowReportCacheKey(namespace, nodeName string) string { 23 | return fmt.Sprintf(ShadowReportDataCache, namespace, nodeName) 24 | } 25 | -------------------------------------------------------------------------------- /common/config.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/utils" 5 | ) 6 | 7 | func LoadConfig(cfg interface{}, files ...string) error { 8 | f := GetConfFile() 9 | if len(files) > 0 && len(files[0]) > 0 { 10 | f = files[0] 11 | } 12 | return utils.LoadYAML(f, cfg) 13 | } 14 | -------------------------------------------------------------------------------- /common/error.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "text/template" 7 | 8 | "github.com/baetyl/baetyl-go/v2/errors" 9 | ) 10 | 11 | // Field returns a field 12 | func Field(k string, v interface{}) *F { 13 | return &F{k, v} 14 | } 15 | 16 | // Error returns an error with code and fields 17 | func Error(c Code, fs ...*F) error { 18 | m := c.String() 19 | if strings.Contains(m, "{{") { 20 | vs := map[string]interface{}{} 21 | for _, f := range fs { 22 | vs[f.k] = f.v 23 | } 24 | t, err := template.New(string(c)).Option("missingkey=zero").Parse(m) 25 | if err != nil { 26 | panic(err) 27 | } 28 | b := bytes.NewBuffer(nil) 29 | err = t.Execute(b, vs) 30 | if err != nil { 31 | panic(err) 32 | } 33 | m = b.String() 34 | } 35 | return errors.CodeError(string(c), m) 36 | } 37 | 38 | // Field field 39 | type F struct { 40 | k string 41 | v interface{} 42 | } 43 | -------------------------------------------------------------------------------- /common/global.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/gin-contrib/cache/persistence" 7 | ) 8 | 9 | const ( 10 | KeyConfFile = "ConfFile" 11 | ValueConfFile = "etc/baetyl/cloud.yml" 12 | KeyTraceKey = "TraceKey" 13 | ValueTraceKey = "requestId" 14 | KeyTraceHeader = "TraceHeader" 15 | ValueTraceHeader = "x-bce-request-id" // TODO: change to x-baetyl-request-id when support configuration 16 | 17 | RegistryAuth = "system-registry-auth" 18 | ) 19 | 20 | var cache = persistence.NewInMemoryStore(time.Minute * 10) 21 | 22 | func SetConfFile(v string) { 23 | cache.Set(KeyConfFile, v, -1) 24 | } 25 | 26 | func GetConfFile() string { 27 | res := ValueConfFile 28 | cache.Get(KeyConfFile, &res) 29 | return res 30 | } 31 | 32 | func SetTraceKey(v string) { 33 | cache.Set(KeyTraceKey, v, -1) 34 | } 35 | 36 | func GetTraceKey() string { 37 | res := ValueTraceKey 38 | cache.Get(KeyTraceKey, &res) 39 | return res 40 | } 41 | 42 | func SetTraceHeader(v string) { 43 | cache.Set(KeyTraceHeader, v, -1) 44 | } 45 | 46 | func GetTraceHeader() string { 47 | res := ValueTraceHeader 48 | cache.Get(KeyTraceHeader, &res) 49 | return res 50 | } 51 | -------------------------------------------------------------------------------- /common/global_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGlobalDefault(t *testing.T) { 10 | assert.Equal(t, "etc/baetyl/cloud.yml", GetConfFile()) 11 | assert.Equal(t, "requestId", GetTraceKey()) 12 | assert.Equal(t, "x-bce-request-id", GetTraceHeader()) 13 | 14 | SetConfFile("a.log") 15 | SetTraceKey("b") 16 | SetTraceHeader("c") 17 | 18 | assert.Equal(t, "a.log", GetConfFile()) 19 | assert.Equal(t, "b", GetTraceKey()) 20 | assert.Equal(t, "c", GetTraceHeader()) 21 | } 22 | -------------------------------------------------------------------------------- /common/log.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "github.com/baetyl/baetyl-go/v2/log" 4 | 5 | func LogDirtyData(err error, fields ...log.Field) { 6 | fields = append(fields, log.Error(err)) 7 | log.L().Error("dirty data", fields...) 8 | } 9 | -------------------------------------------------------------------------------- /common/log_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/baetyl/baetyl-go/v2/log" 7 | "github.com/pkg/errors" 8 | ) 9 | 10 | func TestLogDirtyData(t *testing.T) { 11 | err := errors.New("custom") 12 | LogDirtyData(err, log.Any("name", "baetyl")) 13 | } 14 | -------------------------------------------------------------------------------- /common/string.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "math/rand" 5 | "strings" 6 | "time" 7 | "unsafe" 8 | ) 9 | 10 | var randSource rand.Source 11 | 12 | const ( 13 | bits = 6 14 | mask = 1<= 0; { 31 | if remain == 0 { 32 | cache, remain = randSource.Int63(), maxIndex 33 | } 34 | if idx := int(cache & mask); idx < len(characters) { 35 | b[i] = characters[idx] 36 | i-- 37 | } 38 | cache >>= bits 39 | remain-- 40 | } 41 | 42 | return strings.ToLower(*(*string)(unsafe.Pointer(&b))) 43 | } 44 | -------------------------------------------------------------------------------- /common/string_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestRandString(t *testing.T) { 10 | test1, test2 := RandString(10), RandString(10) 11 | assert.NotEqual(t, test1, test2) 12 | } 13 | -------------------------------------------------------------------------------- /common/util/aes_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestAES(t *testing.T) { 10 | testmap := map[string][]byte{ 11 | "key-a": []byte("hello"), 12 | "key-b": []byte("world"), 13 | } 14 | emap, _ := EncryptMap(testmap, []byte("0123456789abcdef")) 15 | dmap, _ := DecryptMap(emap, []byte("0123456789abcdef")) 16 | 17 | assert.Equal(t, testmap["key-a"], dmap["key-a"]) 18 | assert.Equal(t, testmap["key-b"], dmap["key-b"]) 19 | 20 | itext, _ := Encrypt([]byte("hello world"), []byte("0123456789abcdef")) 21 | otext, _ := Decrypt(itext, []byte("0123456789abcdef")) 22 | assert.Equal(t, "hello world", string(otext)) 23 | } 24 | -------------------------------------------------------------------------------- /common/utils.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "strings" 5 | 6 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 7 | uuid2 "github.com/google/uuid" 8 | ) 9 | 10 | // TODO: use uuid v4 11 | 12 | // UUIDPrune generate uuid without '-' 13 | func UUIDPrune() string { 14 | uuid, err := uuid2.NewUUID() 15 | if err != nil { 16 | panic(err) 17 | } 18 | return strings.ReplaceAll(uuid.String(), "-", "") 19 | } 20 | 21 | // UUID generate uuid 22 | func UUID() string { 23 | uuid, err := uuid2.NewUUID() 24 | if err != nil { 25 | panic(err) 26 | } 27 | return uuid.String() 28 | } 29 | 30 | func CompareNumericalString(a, b string) int { 31 | lengthA := len(a) 32 | lengthB := len(b) 33 | if lengthA > lengthB { 34 | return 1 35 | } else if lengthA < lengthB { 36 | return -1 37 | } else { 38 | return strings.Compare(a, b) 39 | } 40 | 41 | } 42 | 43 | func AddSystemLabel(labels map[string]string, infos map[string]string) map[string]string { 44 | if labels == nil { 45 | labels = make(map[string]string) 46 | } 47 | 48 | for name, value := range infos { 49 | labels[name] = value 50 | } 51 | 52 | return labels 53 | } 54 | 55 | func UpdateSysAppByAccelerator(accelerator string, sysApps []string) []string { 56 | found := false 57 | index := 0 58 | for i, app := range sysApps { 59 | if strings.Contains(app, v1.BaetylGPUMetrics) { 60 | found = true 61 | index = i 62 | break 63 | } 64 | } 65 | if v1.IsLegalAcceleratorType(accelerator) { 66 | if !found { 67 | sysApps = append(sysApps, v1.BaetylGPUMetrics) 68 | } 69 | } else { 70 | if found { 71 | sysApps = append(sysApps[:index], sysApps[index+1:]...) 72 | } 73 | } 74 | return sysApps 75 | } 76 | -------------------------------------------------------------------------------- /common/validate.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "regexp" 5 | "strconv" 6 | "strings" 7 | 8 | "github.com/baetyl/baetyl-go/v2/log" 9 | "github.com/baetyl/baetyl-go/v2/utils" 10 | "github.com/gin-gonic/gin/binding" 11 | "github.com/go-playground/validator/v10" 12 | ) 13 | 14 | var ( 15 | validate *validator.Validate 16 | ) 17 | 18 | func init() { 19 | var ok bool 20 | validate, ok = binding.Validator.Engine().(*validator.Validate) 21 | if !ok { 22 | log.L().Error("failed to get binding validator") 23 | return 24 | } 25 | utils.RegisterValidate(validate) 26 | } 27 | 28 | func ValidNonBaetyl(name string) bool { 29 | return !strings.Contains(name, "baetyl") 30 | } 31 | 32 | func ValidIsInvisible(labels map[string]string) bool { 33 | v, ok := labels[ResourceInvisible] 34 | if !ok { 35 | return false 36 | } 37 | if res, _ := strconv.ParseBool(v); !res { 38 | return false 39 | } 40 | return true 41 | } 42 | 43 | func ValidateResourceName(s string) error { 44 | resourceRegex, _ := regexp.Compile("^[a-z0-9][-a-z0-9.]{0,61}[a-z0-9]$") 45 | if !resourceRegex.MatchString(s) { 46 | return Error(ErrRequestParamInvalid, Field("error", "resource name invalid")) 47 | } 48 | return nil 49 | } 50 | 51 | func ValidateKeyValue(k string) error { 52 | resourceRegex, _ := regexp.Compile("^[-._a-zA-Z0-9]+$") 53 | if !resourceRegex.MatchString(k) { 54 | return Error(ErrRequestParamInvalid, Field("error", "config data key value invalid")) 55 | } 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /docs/logo_with_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baetyl/baetyl-cloud/6074244ae6bca924d0633889f697104ff6dd262b/docs/logo_with_name.png -------------------------------------------------------------------------------- /facade/facade_test.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/baetyl/baetyl-go/v2/errors" 7 | "github.com/golang/mock/gomock" 8 | 9 | mp "github.com/baetyl/baetyl-cloud/v2/mock/plugin" 10 | ms "github.com/baetyl/baetyl-cloud/v2/mock/service" 11 | ) 12 | 13 | var ( 14 | unknownErr = errors.New("unknown") 15 | ) 16 | 17 | type MockAppFacade struct { 18 | sNode *ms.MockNodeService 19 | sApp *ms.MockApplicationService 20 | sConfig *ms.MockConfigService 21 | sSecret *ms.MockSecretService 22 | sIndex *ms.MockIndexService 23 | sCron *ms.MockCronService 24 | txFactory *mp.MockTransactionFactory 25 | } 26 | 27 | func InitMockEnvironment(t *testing.T) (*MockAppFacade, *gomock.Controller) { 28 | mockCtl := gomock.NewController(t) 29 | return &MockAppFacade{ 30 | sNode: ms.NewMockNodeService(mockCtl), 31 | sApp: ms.NewMockApplicationService(mockCtl), 32 | sConfig: ms.NewMockConfigService(mockCtl), 33 | sSecret: ms.NewMockSecretService(mockCtl), 34 | sIndex: ms.NewMockIndexService(mockCtl), 35 | sCron: ms.NewMockCronService(mockCtl), 36 | txFactory: mp.NewMockTransactionFactory(mockCtl), 37 | }, mockCtl 38 | } 39 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /hack/update-codegen.sh: -------------------------------------------------------------------------------- 1 | set -o errexit 2 | set -o nounset 3 | set -o pipefail 4 | 5 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 6 | CODEGEN_PKG=$GOPATH/src/k8s.io/code-generator 7 | 8 | bash $CODEGEN_PKG/generate-groups.sh \ 9 | "deepcopy,client" \ 10 | github.com/baetyl/baetyl-cloud/v2/plugin/kube/client \ 11 | github.com/baetyl/baetyl-cloud/v2/plugin/kube/apis \ 12 | cloud:v1alpha1 \ 13 | --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt 14 | 15 | # 注意 code-generator 库的版本要和 go.mod 中引用的 k8s 库保持一致 16 | # 期望生成的函数列表 deepcopy,defaulter,client,lister,informer 17 | # 生成代码的目标目录,格式为 go.mod 中的项目名称+输出路径 18 | # CRD 所在目录,格式为 go.mod 中的项目名称+apis目录 19 | # CRD的group name和version -------------------------------------------------------------------------------- /mock/plugin/csrf.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: github.com/baetyl/baetyl-cloud/v2/plugin (interfaces: CsrfValidator) 3 | 4 | // Package plugin is a generated GoMock package. 5 | package plugin 6 | 7 | import ( 8 | common "github.com/baetyl/baetyl-cloud/v2/common" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockCsrfValidator is a mock of CsrfValidator interface. 14 | type MockCsrfValidator struct { 15 | ctrl *gomock.Controller 16 | recorder *MockCsrfValidatorMockRecorder 17 | } 18 | 19 | // MockCsrfValidatorMockRecorder is the mock recorder for MockCsrfValidator. 20 | type MockCsrfValidatorMockRecorder struct { 21 | mock *MockCsrfValidator 22 | } 23 | 24 | // NewMockCsrfValidator creates a new mock instance. 25 | func NewMockCsrfValidator(ctrl *gomock.Controller) *MockCsrfValidator { 26 | mock := &MockCsrfValidator{ctrl: ctrl} 27 | mock.recorder = &MockCsrfValidatorMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use. 32 | func (m *MockCsrfValidator) EXPECT() *MockCsrfValidatorMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Close mocks base method. 37 | func (m *MockCsrfValidator) Close() error { 38 | m.ctrl.T.Helper() 39 | ret := m.ctrl.Call(m, "Close") 40 | ret0, _ := ret[0].(error) 41 | return ret0 42 | } 43 | 44 | // Close indicates an expected call of Close. 45 | func (mr *MockCsrfValidatorMockRecorder) Close() *gomock.Call { 46 | mr.mock.ctrl.T.Helper() 47 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockCsrfValidator)(nil).Close)) 48 | } 49 | 50 | // Verify mocks base method. 51 | func (m *MockCsrfValidator) Verify(arg0 *common.Context) error { 52 | m.ctrl.T.Helper() 53 | ret := m.ctrl.Call(m, "Verify", arg0) 54 | ret0, _ := ret[0].(error) 55 | return ret0 56 | } 57 | 58 | // Verify indicates an expected call of Verify. 59 | func (mr *MockCsrfValidatorMockRecorder) Verify(arg0 interface{}) *gomock.Call { 60 | mr.mock.ctrl.T.Helper() 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockCsrfValidator)(nil).Verify), arg0) 62 | } 63 | -------------------------------------------------------------------------------- /mock/plugin/decryption.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: github.com/baetyl/baetyl-cloud/v2/plugin (interfaces: Decrypt) 3 | 4 | // Package plugin is a generated GoMock package. 5 | package plugin 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockDecrypt is a mock of Decrypt interface 13 | type MockDecrypt struct { 14 | ctrl *gomock.Controller 15 | recorder *MockDecryptMockRecorder 16 | } 17 | 18 | // MockDecryptMockRecorder is the mock recorder for MockDecrypt 19 | type MockDecryptMockRecorder struct { 20 | mock *MockDecrypt 21 | } 22 | 23 | // NewMockDecrypt creates a new mock instance 24 | func NewMockDecrypt(ctrl *gomock.Controller) *MockDecrypt { 25 | mock := &MockDecrypt{ctrl: ctrl} 26 | mock.recorder = &MockDecryptMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockDecrypt) EXPECT() *MockDecryptMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Close mocks base method 36 | func (m *MockDecrypt) Close() error { 37 | m.ctrl.T.Helper() 38 | ret := m.ctrl.Call(m, "Close") 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Close indicates an expected call of Close 44 | func (mr *MockDecryptMockRecorder) Close() *gomock.Call { 45 | mr.mock.ctrl.T.Helper() 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDecrypt)(nil).Close)) 47 | } 48 | 49 | // Decrypt mocks base method 50 | func (m *MockDecrypt) Decrypt(arg0 string) (string, error) { 51 | m.ctrl.T.Helper() 52 | ret := m.ctrl.Call(m, "Decrypt", arg0) 53 | ret0, _ := ret[0].(string) 54 | ret1, _ := ret[1].(error) 55 | return ret0, ret1 56 | } 57 | 58 | // Decrypt indicates an expected call of Decrypt 59 | func (mr *MockDecryptMockRecorder) Decrypt(arg0 interface{}) *gomock.Call { 60 | mr.mock.ctrl.T.Helper() 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decrypt", reflect.TypeOf((*MockDecrypt)(nil).Decrypt), arg0) 62 | } 63 | -------------------------------------------------------------------------------- /models/activation.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Activation struct { 4 | FingerprintValue string `json:"fingerprintValue,omitempty" db:"fingerprint_value"` 5 | PenetrateData map[string]string `json:"penetrateData,omitempty" db:"penetrate_data"` 6 | } 7 | 8 | type PackageParam struct { 9 | Platform string `form:"platform"` 10 | } 11 | 12 | type Package struct { 13 | Url string `json:"url,omitempty"` 14 | MD5 string `json:"md5,omitempty"` 15 | Cmd string `json:"cmd,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /models/application_status.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | ) 6 | 7 | type AppStatusParams struct { 8 | App []AppStatusParamsItem `json:"appParams" binding:"required"` 9 | } 10 | 11 | type AppStatusParamsItem struct { 12 | Name string `json:"name" binding:"required"` 13 | Nodes []string `json:"nodes" binding:"required"` 14 | } 15 | 16 | type AppNodeStatusReturn struct { 17 | Items map[string]AppNodeStatusItem `json:"items"` 18 | } 19 | 20 | type AppNodeStatusItem struct { 21 | AppInfo *AppItem `json:"app_info"` 22 | NodeReport map[string]*specV1.AppStats `json:"node_report"` 23 | } 24 | -------------------------------------------------------------------------------- /models/batch.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/common" 8 | ) 9 | 10 | type Batch struct { 11 | Name string `json:"name,omitempty" binding:"omitempty,res_name"` 12 | Namespace string `json:"namespace,omitempty"` 13 | Description string `json:"description,omitempty"` 14 | Accelerator string `json:"accelerator,omitempty"` 15 | SysApps []string `json:"sysApps,omitempty"` 16 | QuotaNum string `json:"quotaNum,omitempty"` 17 | EnableWhitelist int `json:"enableWhitelist,omitempty"` 18 | Cluster int `json:"cluster,omitempty"` 19 | SecurityType common.Security `json:"securityType,omitempty"` 20 | SecurityKey string `json:"securityKey,omitempty"` 21 | CallbackName string `json:"callbackName,omitempty"` 22 | Labels map[string]string `json:"labels,omitempty" binding:"omitempty,label"` 23 | Fingerprint Fingerprint `json:"fingerprint,omitempty"` 24 | CreateTime time.Time `json:"createTime,omitempty"` 25 | UpdateTime time.Time `json:"updateTime,omitempty"` 26 | } 27 | 28 | type Fingerprint struct { 29 | Type int `json:"type,omitempty" validate:"oneof=1 2 4 8 16 32"` 30 | SnPath string `json:"snPath,omitempty"` 31 | InputField string `json:"inputField,omitempty"` 32 | } 33 | 34 | type BatchList struct { 35 | Total int `json:"total"` 36 | *ListOptions `json:",inline"` 37 | Items []Batch `json:"items"` 38 | } 39 | -------------------------------------------------------------------------------- /models/cache.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type NodeDeviceCacheView struct { 4 | FilePath string `yaml:"filePath" json:"filePath" default:"/var/lib/baetyl/store"` 5 | Enable bool `yaml:"enable" json:"enable"` 6 | CacheDuration string `yaml:"cacheDuration" json:"cacheDuration" default:"24h"` 7 | CacheType string `yaml:"cacheType" json:"cacheType" default:"disk"` 8 | Clear bool `yaml:"clear" json:"clear"` 9 | MaxMemoryUse string `yaml:"maxMemoryUse" json:"maxMemoryUse" default:"100MB"` 10 | SendMessageInterval string `yaml:"sendMessageInterval" json:"sendMessageInterval" default:"3s"` 11 | MaxInterval string `yaml:"maxInterval" json:"maxInterval" default:"60s"` 12 | Interval string `yaml:"interval" json:"interval" default:"3s"` 13 | MinInterval string `yaml:"minInterval" json:"minInterval" default:"2s"` 14 | FailChanSize int `yaml:"failChanSize" json:"failChanSize" default:"100"` 15 | } 16 | -------------------------------------------------------------------------------- /models/callback.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | import "time" 5 | 6 | type Callback struct { 7 | Name string `json:"name,omitempty" binding:"omitempty,res_name"` 8 | Namespace string `json:"namespace,omitempty"` 9 | Method string `json:"method,omitempty" binding:"required"` 10 | URL string `json:"url,omitempty" binding:"required"` 11 | Params map[string]string `json:"params,omitempty"` 12 | Header map[string]string `json:"header,omitempty"` 13 | Body map[string]string `json:"body,omitempty"` 14 | Description string `json:"description,omitempty"` 15 | CreateTime time.Time `json:"createTime,omitempty"` 16 | UpdateTime time.Time `json:"updateTime,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /models/cron.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "time" 4 | 5 | type Cron struct { 6 | Id uint64 `json:"id,omitempty"` 7 | Namespace string `json:"namespace,omitempty"` 8 | Name string `json:"name,omitempty" binding:"res_name"` 9 | Selector string `json:"selector,omitempty"` 10 | CronTime time.Time `json:"cronTime,omitempty"` 11 | } 12 | -------------------------------------------------------------------------------- /models/duplicate.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | import specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | type APPDuplicate struct { 7 | specV1.Application `json:",inline"` 8 | Configs map[string]*specV1.Configuration `json:"configs,omitempty"` 9 | Secrets map[string]*specV1.Secret `json:"secrets,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /models/function.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Function struct { 4 | Name string `yaml:"name,omitempty" json:"name,omitempty" binding:"omitempty,res_name,nonbaetyl"` 5 | Handler string `yaml:"handler,omitempty" json:"handler,omitempty"` 6 | Version string `yaml:"version,omitempty" json:"version,omitempty"` 7 | Runtime string `yaml:"runtime,omitempty" json:"runtime,omitempty"` 8 | Code FunctionCode `yaml:"code,omitempty" json:"code,omitempty"` 9 | } 10 | 11 | type FunctionView struct { 12 | Functions []Function `json:"functions"` 13 | } 14 | 15 | type FunctionSourceView struct { 16 | Sources []FunctionSource `json:"sources"` 17 | Runtimes map[string]string `json:"runtimes"` 18 | } 19 | 20 | type FunctionSource struct { 21 | Name string `json:"name,omitempty"` 22 | } 23 | 24 | type FunctionCode struct { 25 | Size int32 `yaml:"size,omitempty" json:"size,omitempty"` 26 | Sha256 string `yaml:"sha256,omitempty" json:"sha256,omitempty"` 27 | Location string `yaml:"location,omitempty" json:"location,omitempty"` 28 | } 29 | -------------------------------------------------------------------------------- /models/gpu.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type GPUInfoInput struct { 5 | GPUMetrics bool `json:"gpuMetrics"` 6 | Subs []string `json:"subs"` 7 | } 8 | 9 | type GPUInfo struct { 10 | GPUMetrics bool `json:"gpuMetrics"` 11 | Subs []SubNodeGPUInfo `json:"subs,omitempty"` 12 | } 13 | 14 | type SubNodeGPUInfo struct { 15 | NodeName string `json:"nodeName"` 16 | GPUMetrics bool `json:"gpuMetrics"` 17 | Ready bool `json:"ready"` 18 | Labels map[string]string `json:"labels"` 19 | } 20 | -------------------------------------------------------------------------------- /models/index.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type Index struct { 4 | a string `json:"a" db:"a"` 5 | b string `json:"b" db:"b"` 6 | } 7 | -------------------------------------------------------------------------------- /models/listview.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type ListView struct { 5 | Items interface{} `json:"items"` 6 | *ListOptions `json:",inline"` 7 | Total int `json:"total"` 8 | } 9 | 10 | type MenuItem struct { 11 | Text string `json:"text"` 12 | Key string `json:"key"` 13 | Unit string `json:"unit"` 14 | Extra string `json:"extra"` 15 | } 16 | -------------------------------------------------------------------------------- /models/lock.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type Lock struct { 5 | Name string `json:"name,omitempty"` 6 | Version string `json:"version,omitempty"` 7 | TTL int64 `json:"ttl,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /models/mis.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type MisData struct { 4 | Count int `json:"count,omitempty"` 5 | Rows interface{} `json:"rows,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /models/module.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Module struct { 8 | Name string `json:"name,omitempty"` 9 | Version string `json:"version,omitempty"` 10 | Image string `json:"image,omitempty"` 11 | Programs map[string]string `json:"programs,omitempty"` 12 | Type string `json:"type,omitempty"` 13 | Flag int `json:"flag"` 14 | IsLatest bool `json:"isLatest,omitempty"` 15 | Description string `json:"description,omitempty"` 16 | CreationTimestamp time.Time `json:"createTime,omitempty"` 17 | UpdateTimestamp time.Time `json:"updateTime,omitempty"` 18 | } 19 | 20 | type InitCMD struct { 21 | CMD string `json:"cmd,omitempty"` 22 | APK string `json:"apk,omitempty"` 23 | APKSys string `json:"apk_sys,omitempty"` 24 | } 25 | 26 | type ModuleList struct { 27 | Total int `json:"total"` 28 | PageNo int `json:"pageNo,omitempty"` 29 | PageSize int `json:"pageSize,omitempty"` 30 | Items interface{} `json:"items"` 31 | } 32 | -------------------------------------------------------------------------------- /models/monitor.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type NodeHostStats struct { 5 | Name string 6 | Status map[string]float64 7 | CPUStats map[string]float64 8 | MemoryStats map[string]float64 9 | GPUStats map[string]float64 10 | DiskStats map[string]float64 11 | NetIOStats map[string]float64 12 | } 13 | 14 | type NodeSysAppStats struct { 15 | Name string 16 | Status map[string]float64 17 | CPUStats map[string]float64 18 | MemoryStats map[string]float64 19 | } 20 | 21 | type QPSStats struct { 22 | Name string 23 | QPS map[string]float64 24 | Success map[string]float64 25 | Fail map[string]float64 26 | } 27 | 28 | type NodeUserAppStats struct { 29 | Name string 30 | Status map[string]float64 31 | CPUStats map[string]float64 32 | MemoryStats map[string]float64 33 | QPSStats map[string]QPSStats 34 | } 35 | 36 | type NodePromStats struct { 37 | Name string 38 | Namespace string 39 | SysAppStats []NodeSysAppStats 40 | UserAppStats []NodeUserAppStats 41 | HostStats []NodeHostStats 42 | } 43 | -------------------------------------------------------------------------------- /models/namespace.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | // Namespace Namespace 4 | type Namespace struct { 5 | Name string `json:"name,omitempty" binding:"namespace"` 6 | } 7 | 8 | // NamespaceList namespace list 9 | type NamespaceList struct { 10 | Total int `json:"total"` 11 | *ListOptions `json:",inline"` 12 | Items []Namespace `json:"items"` 13 | } 14 | -------------------------------------------------------------------------------- /models/node_configuration.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "time" 4 | 5 | type NodeConfiguration struct { 6 | NodeName string `json:"nodeName" db:"node_name"` 7 | Namespace string `json:"namespace" db:"namespace"` 8 | Data string `json:"data" db:"data"` 9 | ConfigurationType string `json:"configurationType" db:"type"` 10 | CreateTime time.Time `json:"createTime" db:"create_time"` 11 | UpdateTime time.Time `json:"updateTime" db:"update_time"` 12 | } 13 | -------------------------------------------------------------------------------- /models/object_deprecated.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type ObjectStorageSourceView struct { 4 | Sources []ObjectStorageSource `json:"sources"` 5 | } 6 | 7 | type ObjectStorageSource struct { 8 | Name string `json:"name,omitempty"` 9 | } 10 | -------------------------------------------------------------------------------- /models/property.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "time" 4 | 5 | type Property struct { 6 | Name string `yaml:"name,omitempty" json:"name,omitempty" db:"name"` 7 | Value string `yaml:"value,omitempty" json:"value,omitempty" db:"value"` 8 | CreateTime time.Time `yaml:"createTime,omitempty" json:"createTime,omitempty" db:"create_time"` 9 | UpdateTime time.Time `yaml:"updateTime,omitempty" json:"updateTime,omitempty" db:"update_time"` 10 | } 11 | -------------------------------------------------------------------------------- /models/quota.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | // Quota 4 | type Quota struct { 5 | Namespace string `json:"namespace" binding:"required"` 6 | QuotaName string `json:"quotaName,omitempty"` 7 | Quota int `json:"quota" default:"0"` 8 | UsedNum int `json:"usedNum" default:"0"` 9 | } 10 | -------------------------------------------------------------------------------- /models/record.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | import ( 5 | "time" 6 | ) 7 | 8 | type Record struct { 9 | Name string `json:"name,omitempty" db:"name"` 10 | Namespace string `json:"namespace,omitempty" db:"namespace"` 11 | BatchName string `json:"batchName,omitempty" db:"batch_name"` 12 | FingerprintValue string `json:"fingerprintValue,omitempty" db:"fingerprint_value" binding:"omitempty,fingerprint"` 13 | Active int `json:"active,omitempty" db:"active"` 14 | NodeName string `json:"nodeName,omitempty" db:"node_name" binding:"omitempty,res_name"` 15 | ActiveIP string `json:"activeIP,omitempty" db:"active_ip"` 16 | ActiveTime time.Time `json:"activeTime,omitempty" db:"active_time"` 17 | CreateTime time.Time `json:"createTime,omitempty" db:"create_time"` 18 | UpdateTime time.Time `json:"updateTime,omitempty" db:"update_time"` 19 | } 20 | 21 | type RecordList struct { 22 | Total int `json:"total"` 23 | *Filter `json:",inline"` 24 | Items []Record `json:"items"` 25 | } 26 | -------------------------------------------------------------------------------- /models/registry.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "time" 7 | 8 | specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 9 | "github.com/jinzhu/copier" 10 | ) 11 | 12 | // Registry Registry 13 | type Registry struct { 14 | Name string `json:"name,omitempty" binding:"omitempty,res_name"` 15 | Namespace string `json:"namespace,omitempty"` 16 | Address string `json:"address"` 17 | Username string `json:"username"` 18 | Password string `json:"password,omitempty"` 19 | CreationTimestamp time.Time `json:"createTime,omitempty"` 20 | UpdateTimestamp time.Time `json:"updateTime,omitempty"` 21 | Description string `json:"description"` 22 | Version string `json:"version,omitempty"` 23 | } 24 | 25 | type RegistryView struct { 26 | Name string `json:"name,omitempty"` 27 | Address string `json:"address,omitempty"` 28 | Username string `json:"username,omitempty"` 29 | } 30 | 31 | // RegistryList Registry List 32 | type RegistryList struct { 33 | Total int `json:"total"` 34 | *ListOptions `json:",inline"` 35 | Items []Registry `json:"items"` 36 | } 37 | 38 | func (r *Registry) Equal(target *Registry) bool { 39 | return reflect.DeepEqual(r.Address, target.Address) && 40 | reflect.DeepEqual(r.Username, target.Username) && 41 | reflect.DeepEqual(r.Password, target.Password) && 42 | reflect.DeepEqual(r.Description, target.Description) 43 | } 44 | 45 | func (r *Registry) ToSecret() *specV1.Secret { 46 | res := &specV1.Secret{ 47 | Labels: map[string]string{ 48 | specV1.SecretLabel: specV1.SecretRegistry, 49 | }, 50 | } 51 | err := copier.Copy(res, r) 52 | if err != nil { 53 | panic(fmt.Sprintf("copier exception: %s", err.Error())) 54 | } 55 | res.Data = map[string][]byte{ 56 | "password": []byte(r.Password), 57 | "username": []byte(r.Username), 58 | "address": []byte(r.Address), 59 | } 60 | return res 61 | } 62 | -------------------------------------------------------------------------------- /models/remote.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type Remote struct { 5 | System bool `json:"system"` 6 | Instance string `json:"instance"` 7 | Container string `json:"container"` 8 | Mode string `json:"mode"` 9 | } 10 | 11 | type RemoteDescribe struct { 12 | System bool `json:"system"` 13 | Instance string `json:"instance"` 14 | Mode string `json:"mode"` 15 | ResourceType string `json:"resourceType"` 16 | } 17 | -------------------------------------------------------------------------------- /models/resource.go: -------------------------------------------------------------------------------- 1 | // Package models 模型定义 2 | package models 3 | 4 | type ResourceList struct { 5 | Total int `json:"total"` 6 | *ListOptions `json:",inline"` 7 | Items []string `json:"items"` 8 | SysItems []string `json:"sysItems"` 9 | } 10 | -------------------------------------------------------------------------------- /models/sync.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type DesireRequest struct { 4 | Resources []*Resource `yaml:"resources,omitempty" json:"resources,omitempty"` 5 | } 6 | 7 | type DesireResponse struct { 8 | Resources []*Resource `yaml:"resources,omitempty" json:"resources,omitempty"` 9 | } 10 | 11 | type ResponseInfo struct { 12 | Delta interface{} `yaml:"delta,omitempty" json:"delta,omitempty"` 13 | Metadata map[string]interface{} `yaml:"metadata,omitempty" json:"metadata,omitempty" default:"{}"` 14 | } 15 | 16 | type Resource struct { 17 | Type string `yaml:"type,omitempty" json:"type,omitempty"` 18 | Name string `yaml:"name,omitempty" json:"name,omitempty"` 19 | Version string `yaml:"version,omitempty" json:"version,omitempty"` 20 | Value interface{} `yaml:"value,omitempty" json:"value,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /models/sys_config.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "time" 4 | 5 | type SysConfig struct { 6 | Type string `yaml:"type,omitempty" json:"type,omitempty" db:"type"` 7 | Key string `yaml:"key,omitempty" json:"key,omitempty" db:"name"` 8 | Value string `yaml:"value,omitempty" json:"value,omitempty" db:"value"` 9 | CreateTime time.Time `yaml:"createTime,omitempty" json:"createTime,omitempty" db:"create_time"` 10 | UpdateTime time.Time `yaml:"updateTime,omitempty" json:"updateTime,omitempty" db:"update_time"` 11 | } 12 | 13 | type SysConfigView struct { 14 | SysConfigs []SysConfig `json:"sysconfigs"` 15 | } 16 | -------------------------------------------------------------------------------- /models/task.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type TaskStatus int 4 | 5 | const ( 6 | TaskNew TaskStatus = iota 7 | TaskProcessing 8 | TaskNeedRetry 9 | TaskFinished 10 | TaskFailed 11 | ) 12 | 13 | type Task struct { 14 | Id int64 `json:"id,omitempty"` 15 | Name string `json:"name,omitempty"` 16 | RegistrationName string `json:"registrationName,omitempty"` 17 | Namespace string `json:"namespace,omitempty"` 18 | ResourceName string `json:"resourceName,omitempty"` 19 | ResourceType string `json:"resourceType,omitempty"` 20 | Version int64 `json:"version,omitempty"` 21 | ExpireTime int64 `json:"expireTime,omitempty"` 22 | Status TaskStatus `json:"status,omitempty"` 23 | ProcessorsStatus map[string]TaskStatus `json:"processorsStatus,omitempty"` 24 | } 25 | -------------------------------------------------------------------------------- /models/yaml.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type YamlResourceList struct { 4 | Total int `json:"total"` 5 | Items []interface{} `json:"items"` 6 | } 7 | -------------------------------------------------------------------------------- /plugin/application.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/application.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Application 10 | 11 | type Application interface { 12 | GetApplication(tx interface{}, namespace, name, version string) (*v1.Application, error) 13 | CreateApplication(tx interface{}, namespace string, application *v1.Application) (*v1.Application, error) 14 | UpdateApplication(tx interface{}, namespace string, application *v1.Application) (*v1.Application, error) 15 | DeleteApplication(tx interface{}, namespace, name string) error 16 | ListApplication(tx interface{}, namespace string, listOptions *models.ListOptions) (*models.ApplicationList, error) 17 | ListApplicationsByNames(tx interface{}, ns string, names []string) ([]models.AppItem, int, error) 18 | } 19 | -------------------------------------------------------------------------------- /plugin/auth.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/common" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/plugin/auth.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Auth 11 | 12 | // Auth interfaces of auth 13 | type Auth interface { 14 | Authenticate(c *common.Context) error 15 | AuthAndVerify(c *common.Context, pr *PermissionRequest) error 16 | Verify(c *common.Context, pr *PermissionRequest) error 17 | io.Closer 18 | } 19 | 20 | const ( 21 | PermissionRead = "READ" 22 | PermissionFull = "FULL_CONTROL" 23 | 24 | PermissionResourceConfig = "config" 25 | PermissionResourceSecret = "secret" 26 | PermissionResourceApp = "app" 27 | PermissionResourceNode = "node" 28 | PermissionResourceBatch = "batch" 29 | PermissionResourceDevice = "device" 30 | PermissionResourceDeviceModel = "devicemodel" 31 | PermissionResourceDriver = "driver" 32 | ) 33 | 34 | var ( 35 | ErrGetAuthorizedUserInfo = errors.New("failed to get authorized user info") 36 | ) 37 | 38 | type PermissionRequest struct { 39 | Region string `json:"region"` 40 | Resource string `json:"resource"` 41 | Permission []string `json:"permission"` 42 | RequestContext RequestContext `json:"request_context"` 43 | } 44 | 45 | type RequestContext struct { 46 | IpAddress string `json:"ip_address"` 47 | Referer string `json:"referer"` 48 | Conditions map[string]interface{} `json:"conditions"` 49 | } 50 | -------------------------------------------------------------------------------- /plugin/awss3/awss3_config.go: -------------------------------------------------------------------------------- 1 | package awss3 2 | 3 | import "time" 4 | 5 | // CloudConfig baetyl-cloud config 6 | type CloudConfig struct { 7 | AWSS3 *S3Config `yaml:"awss3" json:"awss3"` 8 | } 9 | 10 | type S3Config struct { 11 | Endpoint string `yaml:"endpoint" json:"endpoint"` 12 | Ak string `yaml:"ak" json:"ak" binding:"nonzero"` 13 | Sk string `yaml:"sk" json:"sk" binding:"nonzero"` 14 | Region string `yaml:"region" json:"region" default:"us-east-1"` 15 | AddressFormat string `yaml:"addressFormat" json:"addressFormat" default:"pathStyle"` 16 | Expiration time.Duration `yaml:"expiration" json:"expiration" default:"1h"` 17 | } 18 | -------------------------------------------------------------------------------- /plugin/cache.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | //go:generate mockgen -destination=../mock/plugin/cache.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin DataCache 8 | 9 | type DataCache interface { 10 | SetByte(key string, value []byte) error 11 | GetByte(key string) ([]byte, error) 12 | SetString(key string, value string) error 13 | GetString(key string) (string, error) 14 | Delete(key string) error 15 | Exist(key string) (bool, error) 16 | io.Closer 17 | } 18 | -------------------------------------------------------------------------------- /plugin/cache/localcache/cache.go: -------------------------------------------------------------------------------- 1 | // Package localcache freecache implements a local cache for files 2 | package localcache 3 | 4 | import ( 5 | "github.com/baetyl/baetyl-go/v2/errors" 6 | "github.com/baetyl/baetyl-go/v2/log" 7 | "github.com/coocood/freecache" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/common" 10 | "github.com/baetyl/baetyl-cloud/v2/plugin" 11 | ) 12 | 13 | type localFreeCache struct { 14 | c *freecache.Cache 15 | } 16 | 17 | func init() { 18 | plugin.RegisterFactory("freecache", New) 19 | } 20 | 21 | func New() (plugin.Plugin, error) { 22 | var cfg CloudConfig 23 | if err := common.LoadConfig(&cfg); err != nil { 24 | return nil, errors.Trace(err) 25 | } 26 | cache := freecache.NewCache(cfg.FreeCacheConfig.MaxBytes) 27 | log.L().Info("cache set maxBytesSize", log.Any("size", cfg.FreeCacheConfig.MaxBytes)) 28 | return &localFreeCache{ 29 | c: cache, 30 | }, nil 31 | } 32 | 33 | func (f localFreeCache) SetString(key string, value string) error { 34 | return f.c.Set([]byte(key), []byte(value), 0) 35 | } 36 | 37 | func (f localFreeCache) Exist(key string) (bool, error) { 38 | _, err := f.c.Get([]byte(key)) 39 | if err != nil { 40 | if err == freecache.ErrNotFound { 41 | return false, nil 42 | } 43 | return false, err 44 | } 45 | return true, nil 46 | } 47 | 48 | func (f localFreeCache) GetString(key string) (string, error) { 49 | getData, err := f.c.Get([]byte(key)) 50 | if err != nil { 51 | return "", err 52 | } 53 | return string(getData), err 54 | } 55 | 56 | func (f localFreeCache) SetByte(key string, value []byte) error { 57 | return f.c.Set([]byte(key), value, 0) 58 | } 59 | 60 | func (f localFreeCache) GetByte(key string) ([]byte, error) { 61 | return f.c.Get([]byte(key)) 62 | } 63 | 64 | func (f localFreeCache) Delete(key string) error { 65 | f.c.Del([]byte(key)) 66 | return nil 67 | } 68 | 69 | func (f localFreeCache) Close() error { 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /plugin/cache/localcache/cache_config.go: -------------------------------------------------------------------------------- 1 | package localcache 2 | 3 | type CloudConfig struct { 4 | FreeCacheConfig struct { 5 | MaxBytes int `json:"maxBytes" default:"10485760" yaml:"maxBytes"` //default 10 * 1024 * 1024 10m 6 | } `yaml:"freeCacheConfig" json:"freeCacheConfig" default:"{}"` 7 | } 8 | -------------------------------------------------------------------------------- /plugin/cache/localcache/cache_test.go: -------------------------------------------------------------------------------- 1 | package localcache 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | "github.com/baetyl/baetyl-cloud/v2/plugin" 12 | ) 13 | 14 | func TestCache(t *testing.T) { 15 | conf := ` 16 | freeCacheConfig: 17 | maxBytes: 104857600 18 | 19 | ` 20 | filename := "cloud.yml" 21 | err := ioutil.WriteFile(filename, []byte(conf), 0644) 22 | assert.NoError(t, err) 23 | defer os.Remove(filename) 24 | common.SetConfFile(filename) 25 | 26 | p, err := New() 27 | assert.NoError(t, err) 28 | assert.NotNil(t, p) 29 | 30 | cache := p.(plugin.DataCache) 31 | 32 | err = cache.SetString("a", "abc") 33 | assert.NoError(t, err) 34 | 35 | data, err := cache.GetString("a") 36 | assert.NoError(t, err) 37 | assert.Equal(t, "abc", data) 38 | 39 | check, err := cache.Exist("a") 40 | assert.NoError(t, err) 41 | assert.Equal(t, true, check) 42 | 43 | err = cache.Delete("a") 44 | assert.NoError(t, err) 45 | check, err = cache.Exist("a") 46 | assert.NoError(t, err) 47 | assert.Equal(t, false, check) 48 | str := "" 49 | for { 50 | str += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 51 | if len(str) > 65535 { 52 | break 53 | } 54 | } 55 | 56 | err = cache.SetByte("c", []byte(str)) 57 | assert.NoError(t, err) 58 | 59 | dataByte, err := cache.GetByte("c") 60 | assert.NoError(t, err) 61 | assert.Equal(t, []byte(str), dataByte) 62 | 63 | err = cache.SetString("b", str) 64 | assert.NoError(t, err) 65 | 66 | data, err = cache.GetString("b") 67 | assert.NoError(t, err) 68 | assert.Equal(t, str, data) 69 | 70 | check, err = cache.Exist("b") 71 | assert.NoError(t, err) 72 | assert.Equal(t, true, check) 73 | 74 | err = cache.Delete("b") 75 | assert.NoError(t, err) 76 | check, err = cache.Exist("b") 77 | assert.NoError(t, err) 78 | assert.Equal(t, false, check) 79 | } 80 | -------------------------------------------------------------------------------- /plugin/configuration.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/configuration.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Configuration 10 | 11 | type Configuration interface { 12 | GetConfig(tx interface{}, namespace, name, version string) (*v1.Configuration, error) 13 | CreateConfig(tx interface{}, namespace string, configModel *v1.Configuration) (*v1.Configuration, error) 14 | UpdateConfig(tx interface{}, namespace string, configurationModel *v1.Configuration) (*v1.Configuration, error) 15 | DeleteConfig(tx interface{}, namespace, name string) error 16 | ListConfig(namespace string, listOptions *models.ListOptions) (*models.ConfigurationList, error) 17 | } 18 | -------------------------------------------------------------------------------- /plugin/cron.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/cron.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Cron 10 | 11 | type Cron interface { 12 | GetCron(name, namespace string) (*models.Cron, error) 13 | CreateCron(*models.Cron) error 14 | UpdateCron(*models.Cron) error 15 | DeleteCron(name, namespace string) error 16 | ListExpiredApps() ([]models.Cron, error) 17 | DeleteExpiredApps([]uint64) error 18 | io.Closer 19 | } 20 | -------------------------------------------------------------------------------- /plugin/csrf.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/common" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/csrf.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin CsrfValidator 10 | 11 | type CsrfValidator interface { 12 | Verify(c *common.Context) error 13 | io.Closer 14 | } 15 | -------------------------------------------------------------------------------- /plugin/database/cron_test.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | "github.com/baetyl/baetyl-cloud/v2/models" 12 | ) 13 | 14 | var ( 15 | cronAppTables = []string{ 16 | ` 17 | CREATE TABLE baetyl_cron_app( 18 | id INTEGER PRIMARY KEY AUTOINCREMENT, 19 | name VARCHAR(128) NOT NULL DEFAULT '', 20 | namespace VARCHAR(64) NOT NULL DEFAULT '', 21 | selector VARCHAR(2048) NOT NULL DEFAULT '', 22 | cron_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 23 | create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 24 | update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 25 | ); 26 | `, 27 | } 28 | ) 29 | 30 | func (d *DB) MockCreateCronAppTable() { 31 | for _, sql := range cronAppTables { 32 | _, err := d.Exec(nil, sql) 33 | if err != nil { 34 | panic(fmt.Sprintf("create table exception: %s", err.Error())) 35 | } 36 | } 37 | } 38 | 39 | func TestCronApp(t *testing.T) { 40 | db, err := MockNewDB() 41 | if err != nil { 42 | fmt.Printf("get mock sqlite3 error = %s", err.Error()) 43 | t.Fail() 44 | return 45 | } 46 | db.MockCreateCronAppTable() 47 | 48 | name, ns, selector := "baetyl", "cloud", "baetyl-node-name=node1" 49 | cronApp := &models.Cron{ 50 | Name: name, 51 | Namespace: ns, 52 | Selector: selector, 53 | CronTime: time.Now(), 54 | } 55 | 56 | err = db.CreateCron(cronApp) 57 | assert.NoError(t, err) 58 | 59 | _, err = db.GetCron(name, ns) 60 | assert.NoError(t, err) 61 | 62 | cronApp.Selector = "baetyl-node-name=node2" 63 | err = db.UpdateCron(cronApp) 64 | assert.NoError(t, err) 65 | 66 | _, err = db.ListExpiredApps() 67 | assert.NotEqual(t, err, nil) 68 | 69 | err = db.DeleteExpiredApps([]uint64{1}) 70 | assert.NoError(t, err) 71 | 72 | err = db.DeleteCron(name, ns) 73 | assert.NoError(t, err) 74 | 75 | _, err = db.GetCron(name, ns) 76 | assert.Error(t, err, common.ErrResourceNotFound) 77 | } 78 | -------------------------------------------------------------------------------- /plugin/database/db_config.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | // CloudConfig baetyl-cloud config 4 | type CloudConfig struct { 5 | Database struct { 6 | Decryption bool `yaml:"decryption" json:"decryption"` 7 | Type string `yaml:"type" json:"type" binding:"nonzero"` 8 | URL string `yaml:"url" json:"url" binding:"nonzero"` 9 | MaxConns int `yaml:"maxConns" json:"maxConns" default:"20"` 10 | MaxIdleConns int `yaml:"maxIdleConns" json:"maxIdleConns" default:"5"` 11 | ConnMaxLifetime int `yaml:"connMaxLifetime" json:"connMaxLifetime" default:"150"` 12 | } `yaml:"database" json:"database" default:"{}"` 13 | } 14 | -------------------------------------------------------------------------------- /plugin/database/db_test.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/log" 5 | _ "github.com/mattn/go-sqlite3" 6 | ) 7 | 8 | func MockNewDB() (*BaetylCloudDB, error) { 9 | var cfg CloudConfig 10 | cfg.Database.Type = "sqlite3" 11 | cfg.Database.URL = ":memory:" 12 | cfg.Database.ConnMaxLifetime = 150 13 | cfg.Database.MaxConns = 20 14 | cfg.Database.MaxIdleConns = 5 15 | db, err := NewDB(cfg) 16 | if err != nil { 17 | return nil, err 18 | } 19 | return &BaetylCloudDB{ 20 | DB: *db, 21 | log: log.L().With(log.Any("plugin", "test")), 22 | }, nil 23 | } 24 | -------------------------------------------------------------------------------- /plugin/database/entities/access_template_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "testing" 6 | 7 | "github.com/baetyl/baetyl-go/v2/dmcontext" 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/models" 11 | ) 12 | 13 | func TestTransAccessTemplate(t *testing.T) { 14 | at := &models.AccessTemplate{ 15 | Name: "dm-1", 16 | Namespace: "default", 17 | Description: "desc", 18 | Protocol: "pro-1", 19 | DeviceModel: "dm-1", 20 | Labels: map[string]string{"a": "b"}, 21 | Mappings: []dmcontext.ModelMapping{{ 22 | Attribute: "attr-1", 23 | Expression: "equal(x1)", 24 | }}, 25 | Properties: []dmcontext.DeviceProperty{{ 26 | Name: "prop-1", 27 | ID: "1", 28 | Type: "float32", 29 | Mode: "rw", 30 | Visitor: dmcontext.PropertyVisitor{ 31 | Modbus: &dmcontext.ModbusVisitor{ 32 | Function: 3, 33 | Address: "0x3", 34 | }, 35 | }, 36 | }}, 37 | } 38 | dbAT, err := FromAccessTemplate(at) 39 | assert.NoError(t, err) 40 | 41 | _, err = ToAccessTemplate(dbAT) 42 | assert.NoError(t, err) 43 | 44 | dbAT.Properties = "test" 45 | _, err = ToAccessTemplate(dbAT) 46 | assert.NotNil(t, err) 47 | 48 | dbAT.Mappings = "test" 49 | _, err = ToAccessTemplate(dbAT) 50 | assert.NotNil(t, err) 51 | 52 | dbAT.Labels = "test" 53 | _, err = ToAccessTemplate(dbAT) 54 | assert.NotNil(t, err) 55 | } 56 | -------------------------------------------------------------------------------- /plugin/database/entities/batch_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "path" 6 | "testing" 7 | "time" 8 | 9 | "github.com/stretchr/testify/assert" 10 | 11 | "github.com/baetyl/baetyl-cloud/v2/common" 12 | "github.com/baetyl/baetyl-cloud/v2/models" 13 | ) 14 | 15 | func genBatch() *models.Batch { 16 | return &models.Batch{ 17 | Name: "zx", 18 | Namespace: "default", 19 | Description: "desc", 20 | QuotaNum: "20", 21 | EnableWhitelist: 0, 22 | SecurityType: common.None, 23 | SecurityKey: "", 24 | CallbackName: "test", 25 | CreateTime: time.Unix(1000, 10), 26 | UpdateTime: time.Unix(1000, 10), 27 | Labels: map[string]string{"a": "a"}, 28 | Accelerator: "nvidia", 29 | SysApps: []string{"a", "b"}, 30 | Fingerprint: models.Fingerprint{ 31 | Type: common.FingerprintSN, 32 | SnPath: path.Join(common.DefaultSNPath, common.DefaultSNFile), 33 | }, 34 | } 35 | } 36 | 37 | func genBatchDB() *Batch { 38 | return &Batch{ 39 | Name: "zx", 40 | Namespace: "default", 41 | Description: "desc", 42 | QuotaNum: "20", 43 | EnableWhitelist: 0, 44 | SecurityType: common.None, 45 | SecurityKey: "", 46 | CallbackName: "test", 47 | CreateTime: time.Unix(1000, 10), 48 | UpdateTime: time.Unix(1000, 10), 49 | Labels: "{\"a\":\"a\"}", 50 | Accelerator: "nvidia", 51 | SysApps: "[\"a\",\"b\"]", 52 | Fingerprint: "{\"type\":1,\"snPath\":\"/var/lib/baetyl/sn/fingerprint.txt\"}", 53 | } 54 | } 55 | 56 | func TestConvertBatch(t *testing.T) { 57 | batch := genBatch() 58 | batchDB := genBatchDB() 59 | resBatch := ToBatchModel(batchDB) 60 | assert.EqualValues(t, batch, resBatch) 61 | resBatchDB := FromBatchModel(batch) 62 | assert.EqualValues(t, batchDB, resBatchDB) 63 | } 64 | -------------------------------------------------------------------------------- /plugin/database/entities/cron_app.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import "time" 4 | 5 | type CronApp struct { 6 | Id uint64 `db:"id"` 7 | Namespace string `db:"namespace"` 8 | Name string `db:"name"` 9 | Selector string `db:"selector"` 10 | CronTime time.Time `db:"cron_time"` 11 | CreateTime time.Time `db:"create_time"` 12 | UpdateTime time.Time `db:"update_time"` 13 | } 14 | -------------------------------------------------------------------------------- /plugin/database/entities/device_driver_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "testing" 6 | 7 | dm "github.com/baetyl/baetyl-go/v2/dmcontext" 8 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 9 | "github.com/stretchr/testify/assert" 10 | 11 | "github.com/baetyl/baetyl-cloud/v2/models" 12 | ) 13 | 14 | func TestTransDeviceDriver(t *testing.T) { 15 | device := &models.DeviceDriver{ 16 | NodeName: "node-1", 17 | DriverName: "driver-1", 18 | Namespace: "default", 19 | Protocol: "pro-1", 20 | Application: &v1.ObjectReference{ 21 | Name: "app1", 22 | Version: "v1", 23 | }, 24 | Configuration: &v1.ObjectReference{ 25 | Name: "cfg1", 26 | Version: "c1", 27 | }, 28 | DriverConfig: &models.DriverConfig{ 29 | Channels: []models.ChannelConfig{ 30 | { 31 | ChannelID: "1", 32 | Modbus: &models.ModbusChannel{ 33 | TCP: &dm.TCPConfig{ 34 | Address: "local", 35 | Port: 50200, 36 | }, 37 | }, 38 | }, 39 | }, 40 | }, 41 | } 42 | dbDevice, err := FromModelDeviceDriver(device) 43 | assert.NoError(t, err) 44 | 45 | _, err = ToModelDeviceDriver(dbDevice) 46 | assert.NoError(t, err) 47 | 48 | dbDevice.DriverConfig = "test" 49 | _, err = ToModelDeviceDriver(dbDevice) 50 | assert.NotNil(t, err) 51 | 52 | dbDevice.Configuration = "test" 53 | _, err = ToModelDeviceDriver(dbDevice) 54 | assert.NotNil(t, err) 55 | 56 | dbDevice.Application = "test" 57 | _, err = ToModelDeviceDriver(dbDevice) 58 | assert.NotNil(t, err) 59 | } 60 | -------------------------------------------------------------------------------- /plugin/database/entities/device_model_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | ejson "encoding/json" 6 | "strconv" 7 | "testing" 8 | 9 | dm "github.com/baetyl/baetyl-go/v2/dmcontext" 10 | "github.com/stretchr/testify/assert" 11 | 12 | "github.com/baetyl/baetyl-cloud/v2/models" 13 | ) 14 | 15 | func TestTransDeviceModel(t *testing.T) { 16 | dmm := &models.DeviceModel{ 17 | Name: "dm-1", 18 | Namespace: "default", 19 | Description: "desc", 20 | Protocol: "pro-1", 21 | Labels: map[string]string{"a": "b"}, 22 | Attributes: []models.DeviceModelAttribute{{ 23 | Name: "attr-1", 24 | ID: "attr-1", 25 | Type: "float64", 26 | DefaultValue: ejson.Number(strconv.FormatFloat(12.3, 'f', -1, 64)), 27 | Required: true, 28 | }}, 29 | Properties: []models.DeviceModelProperty{{ 30 | Name: "prop-1", 31 | ID: "prop-1", 32 | Type: "float32", 33 | Mode: "rw", 34 | Visitor: dm.PropertyVisitor{ 35 | Modbus: &dm.ModbusVisitor{ 36 | Function: 3, 37 | Address: "0x3", 38 | }, 39 | }, 40 | }}, 41 | } 42 | dbDM, err := FromModelDeviceModel(dmm) 43 | assert.NoError(t, err) 44 | 45 | _, err = ToModelDeviceModel(dbDM) 46 | assert.NoError(t, err) 47 | 48 | dbDM.Properties = "test" 49 | _, err = ToModelDeviceModel(dbDM) 50 | assert.NotNil(t, err) 51 | 52 | dbDM.Attributes = "test" 53 | _, err = ToModelDeviceModel(dbDM) 54 | assert.NotNil(t, err) 55 | 56 | dbDM.Labels = "test" 57 | _, err = ToModelDeviceModel(dbDM) 58 | assert.NotNil(t, err) 59 | } 60 | -------------------------------------------------------------------------------- /plugin/database/entities/device_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | ejson "encoding/json" 6 | "strconv" 7 | "testing" 8 | 9 | dm "github.com/baetyl/baetyl-go/v2/dmcontext" 10 | "github.com/stretchr/testify/assert" 11 | 12 | "github.com/baetyl/baetyl-cloud/v2/models" 13 | ) 14 | 15 | func TestTransDevice(t *testing.T) { 16 | device := &models.Device{ 17 | Name: "dm-1", 18 | Alias: "dm-1", 19 | Namespace: "default", 20 | Description: "desc", 21 | Protocol: "pro-1", 22 | Labels: map[string]string{"a": "b"}, 23 | Shadow: "shad", 24 | DeviceModel: "model-1", 25 | NodeName: "node-1", 26 | DriverName: "driver-1", 27 | Attributes: []models.DeviceAttribute{{ 28 | Name: "attr-1", 29 | ID: "attr-1", 30 | Type: "float64", 31 | Required: true, 32 | Value: ejson.Number(strconv.FormatFloat(12.23, 'f', -1, 64)), 33 | }}, 34 | Properties: []dm.DeviceProperty{{ 35 | Name: "prop-1", 36 | ID: "prop-1", 37 | Type: "float32", 38 | Mode: "rw", 39 | Expect: ejson.Number(strconv.FormatFloat(1.23, 'f', -1, 64)), 40 | Current: ejson.Number(strconv.FormatFloat(2.45, 'f', -1, 64)), 41 | }}, 42 | Config: &models.DeviceConfig{}, 43 | } 44 | dbDevcie, err := FromModelDevice(device) 45 | assert.NoError(t, err) 46 | 47 | _, err = ToModelDevice(dbDevcie) 48 | assert.NoError(t, err) 49 | 50 | dbDevcie.Config = "test" 51 | _, err = ToModelDevice(dbDevcie) 52 | assert.NotNil(t, err) 53 | 54 | dbDevcie.Properties = "test" 55 | _, err = ToModelDevice(dbDevcie) 56 | assert.NotNil(t, err) 57 | 58 | dbDevcie.Attributes = "test" 59 | _, err = ToModelDevice(dbDevcie) 60 | assert.NotNil(t, err) 61 | 62 | dbDevcie.Labels = "test" 63 | _, err = ToModelDevice(dbDevcie) 64 | assert.NotNil(t, err) 65 | } 66 | -------------------------------------------------------------------------------- /plugin/database/entities/device_uplink.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "time" 6 | ) 7 | 8 | const ( 9 | // 北向协议目前支持协议 10 | UplinkProtocolMQTT = "mqtt" 11 | UplinkProtocolHTTP = "http" 12 | UplinkProtocolWebsocket = "websocket" 13 | 14 | DestinationBaetylBroker = "baetyl-broker" 15 | DestinationBaetylDmp = "baetyl-dmp" 16 | DestinationCustom = "custom" 17 | ) 18 | 19 | type DeviceUplink struct { 20 | ID int64 `db:"id"` 21 | NodeName string `db:"node_name"` 22 | Namespace string `db:"namespace"` 23 | Protocol string `db:"protocol"` 24 | Destination string `db:"destination"` 25 | DestinationName string `db:"destination_name"` 26 | Address string `db:"address"` 27 | MQTTUser string `db:"mqtt_user"` 28 | MQTTPassword string `db:"mqtt_password"` 29 | HTTPMethod string `db:"http_method"` 30 | HTTPPath string `db:"http_path"` 31 | CA string `db:"ca"` 32 | Cert string `db:"cert"` 33 | PrivateKey string `db:"private_key"` 34 | Passphrase string `db:"passphrase"` 35 | CreateTime time.Time `db:"create_time"` 36 | UpdateTime time.Time `db:"update_time"` 37 | } 38 | -------------------------------------------------------------------------------- /plugin/database/entities/lock.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | type Lock struct { 5 | ID int64 `db:"id"` 6 | Name string `db:"name"` 7 | Version string `db:"version"` 8 | Expire int64 `db:"expire"` 9 | } 10 | -------------------------------------------------------------------------------- /plugin/database/entities/namesapce.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "github.com/baetyl/baetyl-cloud/v2/models" 6 | ) 7 | 8 | type Namespace struct { 9 | ID int64 `db:"id"` 10 | Name string `db:"name"` 11 | } 12 | 13 | func FromNamespaceModel(namespace *models.Namespace) (*Namespace, error) { 14 | return &Namespace{ 15 | Name: namespace.Name, 16 | }, nil 17 | } 18 | 19 | func ToNamespaceModel(namespace *Namespace) (*models.Namespace, error) { 20 | return &models.Namespace{ 21 | Name: namespace.Name, 22 | }, nil 23 | } 24 | -------------------------------------------------------------------------------- /plugin/database/entities/namespace_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "testing" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/models" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestFromNamespaceModel(t *testing.T) { 13 | ns := &Namespace{ 14 | Name: "testNs", 15 | } 16 | 17 | mNs := &models.Namespace{ 18 | Name: "testNs", 19 | } 20 | res, err := FromNamespaceModel(mNs) 21 | 22 | assert.NoError(t, err) 23 | assert.Equal(t, ns.Name, res.Name) 24 | } 25 | 26 | func TestToNamespaceModel(t *testing.T) { 27 | ns := &Namespace{ 28 | ID: 123, 29 | Name: "testNs", 30 | } 31 | 32 | mNs := &models.Namespace{ 33 | Name: "testNs", 34 | } 35 | 36 | res, err := ToNamespaceModel(ns) 37 | assert.NoError(t, err) 38 | assert.Equal(t, mNs.Name, res.Name) 39 | } 40 | -------------------------------------------------------------------------------- /plugin/database/entities/node_configuration.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import "time" 4 | 5 | type NodeConfiguration struct { 6 | ID int64 `json:"ID" db:"id"` 7 | NodeName string `json:"nodeName" db:"node_name"` 8 | Namespace string `json:"namespace" db:"namespace"` 9 | Data string `json:"data" db:"data"` 10 | ConfigurationType string `json:"configurationType" db:"type"` 11 | CreateTime time.Time `json:"createTime" db:"create_time"` 12 | UpdateTime time.Time `json:"updateTime" db:"update_time"` 13 | } 14 | -------------------------------------------------------------------------------- /plugin/database/entities/node_device.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "time" 6 | 7 | "github.com/baetyl/baetyl-go/v2/json" 8 | "github.com/jinzhu/copier" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/models" 11 | ) 12 | 13 | type NodeDevice struct { 14 | ID int64 `db:"id"` 15 | Name string `db:"name"` 16 | Namespace string `db:"namespace"` 17 | Version string `db:"version"` 18 | NodeName string `db:"node_name"` 19 | DeviceModel string `db:"device_model"` 20 | AccessTemplate string `db:"access_template"` 21 | DriverName string `db:"driver_name"` 22 | DriverInstName string `db:"driver_inst_name"` 23 | Config string `db:"config"` 24 | CreateTime time.Time `db:"create_time"` 25 | UpdateTime time.Time `db:"update_time"` 26 | } 27 | 28 | func FromNodeDevice(dev *models.NodeDevice) (*NodeDevice, error) { 29 | if dev.Config == nil { 30 | dev.Config = new(models.DeviceConfig) 31 | } 32 | cfg, err := json.Marshal(dev.Config) 33 | if err != nil { 34 | return nil, err 35 | } 36 | dev.Version = GenResourceVersion() 37 | device := &NodeDevice{ 38 | Config: string(cfg), 39 | } 40 | if err = copier.Copy(device, dev); err != nil { 41 | return nil, err 42 | } 43 | return device, nil 44 | } 45 | 46 | func ToNodeDevice(dev *NodeDevice) (*models.NodeDevice, error) { 47 | var cfg models.DeviceConfig 48 | if err := json.Unmarshal([]byte(dev.Config), &cfg); err != nil { 49 | return nil, err 50 | } 51 | device := &models.NodeDevice{ 52 | Config: &cfg, 53 | } 54 | if err := copier.Copy(device, dev); err != nil { 55 | return nil, err 56 | } 57 | return device, nil 58 | } 59 | -------------------------------------------------------------------------------- /plugin/database/entities/node_device_test.go: -------------------------------------------------------------------------------- 1 | // Package entities 数据库存储基本结构与方法 2 | package entities 3 | 4 | import ( 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | func TestTransNodeDevice(t *testing.T) { 13 | d := &models.NodeDevice{ 14 | Name: "dm-1", 15 | Namespace: "default", 16 | DeviceModel: "model-1", 17 | NodeName: "node-1", 18 | DriverName: "driver-1", 19 | Config: &models.DeviceConfig{}, 20 | } 21 | dbNodeDevice, err := FromNodeDevice(d) 22 | assert.NoError(t, err) 23 | 24 | _, err = ToNodeDevice(dbNodeDevice) 25 | assert.NoError(t, err) 26 | 27 | dbNodeDevice.Config = "test" 28 | _, err = ToNodeDevice(dbNodeDevice) 29 | assert.NotNil(t, err) 30 | } 31 | -------------------------------------------------------------------------------- /plugin/database/entities/shadow_test.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/baetyl/baetyl-go/v2/json" 7 | "github.com/baetyl/baetyl-go/v2/spec/v1" 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | "github.com/baetyl/baetyl-cloud/v2/models" 12 | ) 13 | 14 | func TestNewShadowFromShadowModel(t *testing.T) { 15 | shadow := models.NewShadow("default", "node01") 16 | shadow.Desire[common.DesiredApplications] = []v1.AppInfo{ 17 | { 18 | "app01", 19 | "v1", 20 | }, 21 | } 22 | shadow.Report[common.DesiredSysApplications] = []v1.AppInfo{ 23 | { 24 | "sysapp01", 25 | "v1", 26 | }, 27 | } 28 | 29 | shd, err := NewShadowFromShadowModel(shadow) 30 | assert.NoError(t, err) 31 | desire, _ := json.Marshal(&shadow.Desire) 32 | report, _ := json.Marshal(&shadow.Report) 33 | assert.Equal(t, string(report), shd.Report) 34 | assert.Equal(t, string(desire), shd.Desire) 35 | 36 | } 37 | 38 | func TestShadow_ToShadowModel(t *testing.T) { 39 | shadow := &Shadow{ 40 | Namespace: "default", 41 | Name: "node01", 42 | Desire: `{"apps":[],"sysapps":[{"name":"baetyl-core-node-test-2-qcfpywxuh","version":"211430"},{"name":"baetyl-function-node-test-2-hb8ibamcv","version":"211434"}]}`, 43 | Report: `{"apps":[],"sysapps":[{"name":"baetyl-core-node-test-2-qcfpywxuh","version":"211430"},{"name":"baetyl-function-node-test-2-hb8ibamcv","version":"211434"}]}`, 44 | DesireMeta: `{}`, 45 | ReportMeta: `{}`, 46 | } 47 | 48 | shd, err := shadow.ToShadowModel() 49 | assert.NoError(t, err) 50 | assert.Equal(t, 0, len(shd.Desire.AppInfos(false))) 51 | assert.Equal(t, 0, len(shd.Report.AppInfos(false))) 52 | assert.Equal(t, 2, len(shd.Desire.AppInfos(true))) 53 | assert.Equal(t, 2, len(shd.Report.AppInfos(true))) 54 | } 55 | -------------------------------------------------------------------------------- /plugin/database/entities/task.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/baetyl/baetyl-go/v2/json" 7 | "github.com/jinzhu/copier" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | type Task struct { 13 | Id int64 `json:"id,omitempty" db:"id"` 14 | Name string `json:"name,omitempty" db:"name"` 15 | RegistrationName string `json:"registrationName" db:"registration_name"` 16 | Namespace string `json:"namespace,omitempty" db:"namespace"` 17 | ResourceName string `json:"resourceName,omitempty" db:"resource_name"` 18 | ResourceType string `json:"resourceType,omitempty" db:"resource_type"` 19 | Version int64 `json:"version,omitempty" db:"version"` 20 | ExpireTime int64 `json:"expireTime,omitempty" db:"expire_time"` 21 | Status int `json:"status,omitempty" db:"status"` 22 | Content string `json:"content,omitempty" db:"content"` 23 | CreateTime time.Time `json:"createTime" db:"create_time"` 24 | UpdateTime time.Time `json:"updateTime" db:"update_time"` 25 | } 26 | 27 | func FromTaskModel(task *models.Task) (*Task, error) { 28 | t := new(Task) 29 | err := copier.Copy(t, task) 30 | 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | content, err := json.Marshal(task.ProcessorsStatus) 36 | if err != nil { 37 | return nil, err 38 | } 39 | t.Content = string(content) 40 | 41 | return t, nil 42 | } 43 | 44 | func ToTaskModel(task *Task) (*models.Task, error) { 45 | t := new(models.Task) 46 | err := copier.Copy(t, task) 47 | 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | processorsStatus := map[string]models.TaskStatus{} 53 | if task.Content != "" { 54 | err := json.Unmarshal([]byte(task.Content), &processorsStatus) 55 | 56 | if err != nil { 57 | return nil, err 58 | } 59 | } 60 | t.ProcessorsStatus = processorsStatus 61 | 62 | return t, nil 63 | } 64 | -------------------------------------------------------------------------------- /plugin/database/entities/task_test.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/baetyl/baetyl-go/v2/json" 7 | "github.com/stretchr/testify/assert" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | func TestFromTaskModel(t *testing.T) { 13 | mTask := &models.Task{ 14 | Id: 1, 15 | Name: "task_test", 16 | Namespace: "default", 17 | RegistrationName: "test_delete", 18 | ProcessorsStatus: map[string]models.TaskStatus{ 19 | "app_delete": models.TaskFinished, 20 | }, 21 | } 22 | 23 | task, err := FromTaskModel(mTask) 24 | assert.NoError(t, err) 25 | processorStatus, _ := json.Marshal(&mTask.ProcessorsStatus) 26 | 27 | assert.Equal(t, string(processorStatus), task.Content) 28 | assert.Equal(t, mTask.Id, task.Id) 29 | assert.Equal(t, mTask.Name, task.Name) 30 | assert.Equal(t, mTask.Namespace, task.Namespace) 31 | assert.Equal(t, mTask.RegistrationName, task.RegistrationName) 32 | } 33 | 34 | func TestToTaskModel(t *testing.T) { 35 | task := &Task{ 36 | Id: 1, 37 | Name: "task_test", 38 | Namespace: "default", 39 | RegistrationName: "test_delete", 40 | Content: "{\"app_delete\":3}", 41 | } 42 | 43 | mTask, err := ToTaskModel(task) 44 | assert.NoError(t, err) 45 | 46 | processorStatus := map[string]models.TaskStatus{ 47 | "app_delete": models.TaskFinished, 48 | } 49 | 50 | assert.Equal(t, processorStatus, mTask.ProcessorsStatus) 51 | assert.Equal(t, mTask.Id, task.Id) 52 | assert.Equal(t, mTask.Name, task.Name) 53 | assert.Equal(t, mTask.Namespace, task.Namespace) 54 | assert.Equal(t, mTask.RegistrationName, task.RegistrationName) 55 | } 56 | -------------------------------------------------------------------------------- /plugin/database/lock.go: -------------------------------------------------------------------------------- 1 | // Package database 数据库存储实现 2 | package database 3 | 4 | import ( 5 | "database/sql" 6 | 7 | "github.com/jmoiron/sqlx" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/common" 10 | "github.com/baetyl/baetyl-cloud/v2/models" 11 | ) 12 | 13 | func (d *BaetylCloudDB) InsertLock(lock *models.Lock) error { 14 | _, err := d.InsertLockTx(nil, lock) 15 | return err 16 | } 17 | 18 | func (d *BaetylCloudDB) DeleteLock(lock *models.Lock) error { 19 | res, err := d.DeleteLockTx(nil, lock) 20 | if res == nil || err != nil { 21 | return err 22 | } 23 | rows, err := res.RowsAffected() 24 | if err == nil && rows == 1 { 25 | return nil 26 | } 27 | return common.Error(common.ErrResourceNotFound, common.Field("type", "lock"), common.Field("name", lock.Name)) 28 | } 29 | 30 | func (d *BaetylCloudDB) DeleteExpiredLock(lock *models.Lock) error { 31 | res, err := d.DeleteExpiredLockTx(nil, lock) 32 | if res == nil || err != nil { 33 | return err 34 | } 35 | rows, err := res.RowsAffected() 36 | if err == nil && rows == 1 { 37 | return nil 38 | } 39 | return common.Error(common.ErrResourceNotFound, common.Field("type", "lock"), common.Field("name", lock.Name)) 40 | } 41 | 42 | func (d *BaetylCloudDB) InsertLockTx(tx *sqlx.Tx, lock *models.Lock) (sql.Result, error) { 43 | insertSQL := `INSERT INTO baetyl_lock (name, version, expire) VALUES (?, ?, ?)` 44 | return d.Exec(tx, insertSQL, lock.Name, lock.Version, lock.TTL) 45 | } 46 | 47 | func (d *BaetylCloudDB) DeleteLockTx(tx *sqlx.Tx, lock *models.Lock) (sql.Result, error) { 48 | deleteSQL := `DELETE FROM baetyl_lock WHERE name=? AND version=?` 49 | return d.Exec(tx, deleteSQL, lock.Name, lock.Version) 50 | } 51 | 52 | func (d *BaetylCloudDB) DeleteExpiredLockTx(tx *sqlx.Tx, lock *models.Lock) (sql.Result, error) { 53 | deleteSQL := `DELETE FROM baetyl_lock WHERE name=? AND NOW() > DATE_ADD(create_time, INTERVAL expire SECOND)` 54 | return d.Exec(tx, deleteSQL, lock.Name) 55 | } 56 | -------------------------------------------------------------------------------- /plugin/database/lock_test.go: -------------------------------------------------------------------------------- 1 | // Package database 数据库存储实现 2 | package database 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | "github.com/baetyl/baetyl-cloud/v2/models" 12 | ) 13 | 14 | var ( 15 | lockTable = []string{ 16 | ` 17 | CREATE TABLE baetyl_lock 18 | ( 19 | id integer PRIMARY KEY AUTOINCREMENT, 20 | name varchar(128) NOT NULL DEFAULT '', 21 | version varchar(128) NOT NULL DEFAULT '', 22 | expire Integer NOT NULL DEFAULT 0, 23 | create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 24 | update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 25 | ); 26 | `, 27 | } 28 | ) 29 | 30 | func (d *BaetylCloudDB) MockCreateLockTable() { 31 | for _, sql := range lockTable { 32 | _, err := d.Exec(nil, sql) 33 | if err != nil { 34 | panic(fmt.Sprintf("create lock exception: %s", err.Error())) 35 | } 36 | } 37 | } 38 | 39 | func TestLock(t *testing.T) { 40 | locker1 := &models.Lock{Name: "1", Version: "1", TTL: 0} 41 | 42 | db, err := MockNewDB() 43 | if err != nil { 44 | fmt.Printf("get mock sqlite3 error = %s", err.Error()) 45 | t.Fail() 46 | return 47 | } 48 | db.MockCreateLockTable() 49 | 50 | err = db.InsertLock(locker1) 51 | assert.NoError(t, err) 52 | 53 | err = db.DeleteLock(locker1) 54 | assert.NoError(t, err) 55 | 56 | err = db.DeleteLock(locker1) 57 | assert.Error(t, err, common.ErrResourceNotFound) 58 | } 59 | -------------------------------------------------------------------------------- /plugin/database/node_configuration_test.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | var ( 13 | nodeConfiguration = ` 14 | 15 | CREATE TABLE baetyl_node_configuration 16 | ( 17 | id integer PRIMARY KEY AUTOINCREMENT, 18 | node_name varchar(250) default '' NOT NULL , 19 | namespace varchar(256) default '' NOT NULL , 20 | data varchar(256) default '{"enable":0}' NOT NULL , 21 | type varchar(10) default '' NOT NULL , 22 | create_time timestamp default CURRENT_TIMESTAMP not null , 23 | update_time timestamp default CURRENT_TIMESTAMP not null 24 | ) ;` 25 | ) 26 | 27 | func (d *BaetylCloudDB) MockCreateNodeConfigurationTable() { 28 | _, err := d.Exec(nil, nodeConfiguration) 29 | if err != nil { 30 | panic(fmt.Sprintf("create baetyl node configuration exception: %s", err.Error())) 31 | } 32 | } 33 | 34 | func genNodeConfiguration() *models.NodeConfiguration { 35 | return &models.NodeConfiguration{ 36 | ConfigurationType: "cache", 37 | NodeName: "test", 38 | Data: "{\"enable\":false}", 39 | Namespace: "baetyl_cloud", 40 | } 41 | } 42 | 43 | func TestGetNodeConfig(t *testing.T) { 44 | db, err := MockNewDB() 45 | if err != nil { 46 | fmt.Printf("get mock sqlite3 error = %s", err.Error()) 47 | t.Fail() 48 | return 49 | } 50 | db.MockCreateNodeConfigurationTable() 51 | nc, err := db.CreateNodeConfig(nil, genNodeConfiguration()) 52 | assert.NoError(t, err) 53 | assert.NotNil(t, nc) 54 | nc, err = db.GetNodeConfig(nil, "baetyl_cloud", "test", "cache") 55 | assert.NoError(t, err) 56 | assert.NotNil(t, nc) 57 | nc, err = db.UpdateNodeConfig(nil, genNodeConfiguration()) 58 | assert.NoError(t, err) 59 | assert.NotNil(t, nc) 60 | } 61 | -------------------------------------------------------------------------------- /plugin/database/pki.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/plugin" 7 | ) 8 | 9 | func (d DB) CreateCert(cert plugin.Cert) error { 10 | insertSQL := ` 11 | INSERT INTO baetyl_certificate ( 12 | cert_id, parent_id, type, common_name, 13 | description, csr, content, private_key, not_before, not_after) 14 | VALUES (?,?,?,?,?,?,?,?,?,?) 15 | ` 16 | _, err := d.db.Exec(insertSQL, 17 | cert.CertId, cert.ParentId, cert.Type, 18 | cert.CommonName, cert.Description, cert.Csr, 19 | cert.Content, cert.PrivateKey, cert.NotBefore, cert.NotAfter) 20 | return err 21 | } 22 | 23 | func (d DB) DeleteCert(certId string) error { 24 | deleteSQL := ` 25 | DELETE FROM baetyl_certificate where cert_id=? 26 | ` 27 | _, err := d.db.Exec(deleteSQL, certId) 28 | return err 29 | } 30 | 31 | func (d DB) UpdateCert(cert plugin.Cert) error { 32 | updateSQL := ` 33 | UPDATE baetyl_certificate SET parent_id=?,type=?, 34 | common_name=?,description=?,csr=?,content=?,private_key=?, 35 | not_before=?, not_after=? 36 | WHERE cert_id=? 37 | ` 38 | _, err := d.db.Exec(updateSQL, 39 | cert.ParentId, cert.Type, cert.CommonName, cert.Description, cert.Csr, 40 | cert.Content, cert.PrivateKey, cert.NotBefore, cert.NotAfter, cert.CertId) 41 | return err 42 | } 43 | 44 | func (d DB) GetCert(certId string) (*plugin.Cert, error) { 45 | selectSQL := ` 46 | SELECT cert_id, parent_id, type, common_name, 47 | description, csr, content, private_key, not_before, not_after 48 | FROM baetyl_certificate 49 | WHERE cert_id=? LIMIT 0,1 50 | ` 51 | var cert []plugin.Cert 52 | if err := d.db.Select(&cert, selectSQL, certId); err != nil { 53 | return nil, err 54 | } 55 | if len(cert) > 0 { 56 | return &cert[0], nil 57 | } 58 | return nil, os.ErrNotExist 59 | } 60 | 61 | func (d DB) CountCertByParentId(parentId string) (int, error) { 62 | selectSQL := ` 63 | SELECT count(cert_id) AS count 64 | FROM baetyl_certificate 65 | WHERE parent_id=? 66 | ` 67 | var res []struct { 68 | Count int `db:"count"` 69 | } 70 | if err := d.db.Select(&res, selectSQL, parentId); err != nil { 71 | return 0, err 72 | } 73 | return res[0].Count, nil 74 | } 75 | -------------------------------------------------------------------------------- /plugin/decryption.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import "io" 4 | 5 | //go:generate mockgen -destination=../mock/plugin/decryption.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Decrypt 6 | 7 | type Decrypt interface { 8 | Decrypt(cipherText string) (string, error) 9 | 10 | io.Closer 11 | } 12 | -------------------------------------------------------------------------------- /plugin/decryption/config.go: -------------------------------------------------------------------------------- 1 | package decryption 2 | 3 | type CloudConfig struct { 4 | // CipherText 密码密文 IV sm4 cbc解密iv分量 Sm4ProtectKey sm4解密密钥保护密钥分量 Sm4EncKey sm4解密密钥加密分量 5 | Decryption struct { 6 | Type string `yaml:"type" json:"type"` 7 | CipherText string `yaml:"cipherText" json:"cipherText"` 8 | IV string `yaml:"iv" json:"iv"` 9 | Sm4ProtectKey []string `yaml:"sm4ProtectKey" json:"sm4ProtectKey"` 10 | Sm4EncKey string `yaml:"sm4EncKey" json:"sm4EncKey"` 11 | } `yaml:"decryption" json:"decryption" default:"{}"` 12 | } 13 | -------------------------------------------------------------------------------- /plugin/decryption/decryption_test.go: -------------------------------------------------------------------------------- 1 | package decryption 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func MockNewDP() (*Decryption, error) { 10 | var cfg CloudConfig 11 | cfg.Decryption.Type = "sm4" 12 | cfg.Decryption.Sm4EncKey = "AEF55CE747A502A9C571A1AC6DACE2EA" 13 | cfg.Decryption.IV = "00000000000000000000000000000000" 14 | cfg.Decryption.Sm4ProtectKey = make([]string, 3) 15 | cfg.Decryption.Sm4ProtectKey[0] = "e6af2c278c595cc8a00d4be45fdb0c40" 16 | cfg.Decryption.Sm4ProtectKey[1] = "927eafc3e53dc9898b2da46a6d6be336" 17 | cfg.Decryption.Sm4ProtectKey[2] = "e909ee2ddb3b31a12ab4b04557e0494d" 18 | 19 | return &Decryption{cfg: cfg}, nil 20 | } 21 | 22 | func TestDecryp(t *testing.T) { 23 | dp, err := MockNewDP() 24 | assert.NoError(t, err) 25 | 26 | decode, err := dp.Decrypt("c43b88c3b5ae15eee7b99dd9188c5ebd45be72bb74a22091eafc3beca75a47a5") 27 | assert.NoError(t, err) 28 | assert.Equal(t, decode, "SymmetricCipher Test data222") 29 | 30 | decode2, err := dp.Decrypt("ecc28664636fa967c8e87a9b4ba0581f") 31 | assert.NoError(t, err) 32 | assert.Equal(t, decode2, "secretpassword") 33 | } 34 | -------------------------------------------------------------------------------- /plugin/default/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/common" 5 | "github.com/baetyl/baetyl-cloud/v2/plugin" 6 | ) 7 | 8 | type defaultAuth struct { 9 | cfg CloudConfig 10 | } 11 | 12 | func init() { 13 | plugin.RegisterFactory("defaultauth", New) 14 | } 15 | 16 | // New New 17 | func New() (plugin.Plugin, error) { 18 | var cfg CloudConfig 19 | if err := common.LoadConfig(&cfg); err != nil { 20 | return nil, err 21 | } 22 | return &defaultAuth{ 23 | cfg: cfg, 24 | }, nil 25 | } 26 | 27 | func (d *defaultAuth) Authenticate(c *common.Context) error { 28 | c.SetNamespace(d.cfg.DefaultAuth.Namespace) 29 | c.SetUserInfo(common.UserInfo{ 30 | User: common.User{ID: d.cfg.DefaultAuth.Namespace, Name: d.cfg.DefaultAuth.Namespace}, 31 | Domain: common.Domain{ID: d.cfg.DefaultAuth.Namespace, Name: d.cfg.DefaultAuth.Namespace}, 32 | }) 33 | return nil 34 | } 35 | 36 | func (d *defaultAuth) AuthAndVerify(c *common.Context, pr *plugin.PermissionRequest) error { 37 | return d.Authenticate(c) 38 | } 39 | 40 | func (d *defaultAuth) Verify(c *common.Context, pr *plugin.PermissionRequest) error { 41 | return nil 42 | } 43 | 44 | // Close Close 45 | func (d *defaultAuth) Close() error { 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /plugin/default/auth/auth_test.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | 11 | "github.com/baetyl/baetyl-cloud/v2/common" 12 | "github.com/baetyl/baetyl-cloud/v2/config" 13 | "github.com/baetyl/baetyl-cloud/v2/plugin" 14 | ) 15 | 16 | const ( 17 | confData = ` 18 | defaultauth: 19 | namespace: testns 20 | ` 21 | ) 22 | 23 | func setUp() *config.CloudConfig { 24 | conf := &config.CloudConfig{} 25 | conf.Plugin.Auth = "defaultauth" 26 | return conf 27 | } 28 | 29 | func genConfig(workspace string) error { 30 | if err := os.MkdirAll(workspace, 0755); err != nil { 31 | return err 32 | } 33 | if err := ioutil.WriteFile(path.Join(workspace, "cloud.yml"), []byte(confData), 0755); err != nil { 34 | return err 35 | } 36 | return nil 37 | } 38 | 39 | func TestDefaultAuth_Authenticate(t *testing.T) { 40 | err := genConfig("etc/baetyl") 41 | assert.NoError(t, err) 42 | defer os.RemoveAll(path.Dir("etc/baetyl")) 43 | 44 | iam, err := plugin.GetPlugin("defaultauth") 45 | assert.NoError(t, err) 46 | auth := iam.(plugin.Auth) 47 | 48 | ctx := common.NewContextEmpty() 49 | err = auth.Authenticate(ctx) 50 | 51 | assert.NoError(t, err) 52 | assert.Equal(t, "testns", ctx.GetNamespace()) 53 | } 54 | -------------------------------------------------------------------------------- /plugin/default/auth/config.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | type CloudConfig struct { 4 | DefaultAuth struct { 5 | Namespace string `yaml:"namespace" json:"namespace" default:"baetyl-cloud"` 6 | } `yaml:"defaultauth" json:"defaultauth"` 7 | } 8 | -------------------------------------------------------------------------------- /plugin/default/csrf/config.go: -------------------------------------------------------------------------------- 1 | package csrf 2 | 3 | type CloudConfig struct { 4 | CsrfConfig struct { 5 | CookieName string `yaml:"cookieName" json:"cookieName" default:"csrftoken"` 6 | HeaderName string `yaml:"headerName" json:"headerName" default:"csrftoken"` 7 | Whitelist []string `yaml:"whitelist" json:"whitelist"` 8 | } `yaml:"defaultcsrf" json:"defaultcsrf"` 9 | } 10 | -------------------------------------------------------------------------------- /plugin/default/license/license.go: -------------------------------------------------------------------------------- 1 | package license 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/plugin" 5 | ) 6 | 7 | type license struct { 8 | } 9 | 10 | func init() { 11 | plugin.RegisterFactory("defaultlicense", New) 12 | } 13 | 14 | func New() (plugin.Plugin, error) { 15 | return &license{}, nil 16 | } 17 | 18 | var _ plugin.License = &license{} 19 | 20 | func (l *license) ProtectCode() error { 21 | return nil 22 | } 23 | 24 | func (l *license) CheckLicense() error { 25 | return nil 26 | } 27 | 28 | func (l *license) Close() error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /plugin/default/license/license_test.go: -------------------------------------------------------------------------------- 1 | package license 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestLicense_CheckLicense(t *testing.T) { 10 | l, err := New() 11 | assert.NoError(t, err) 12 | err = l.(*license).CheckLicense() 13 | assert.NoError(t, err) 14 | } 15 | 16 | func TestLicense_ProtectCode(t *testing.T) { 17 | l, err := New() 18 | assert.NoError(t, err) 19 | err = l.(*license).ProtectCode() 20 | assert.NoError(t, err) 21 | } 22 | 23 | func TestLicense_Close(t *testing.T) { 24 | l, err := New() 25 | assert.NoError(t, err) 26 | err = l.(*license).Close() 27 | assert.NoError(t, err) 28 | } 29 | -------------------------------------------------------------------------------- /plugin/default/lock/config.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | type CloudConfig struct { 4 | DefaultLocker struct { 5 | Storage string `yaml:"storage" json:"storage" default:"database"` 6 | } `yaml:"defaultlocker" json:"defaultlocker"` 7 | } 8 | -------------------------------------------------------------------------------- /plugin/default/lock/empty_lock.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/plugin" 7 | ) 8 | 9 | func init() { 10 | plugin.RegisterFactory("defaultlocker", New) 11 | } 12 | 13 | type emptyLocker struct{} 14 | 15 | func New() (plugin.Plugin, error) { 16 | return &emptyLocker{}, nil 17 | } 18 | 19 | func (l *emptyLocker) Lock(ctx context.Context, name string, ttl int64) (string, error) { 20 | return "", nil 21 | } 22 | 23 | func (l *emptyLocker) Unlock(ctx context.Context, name, version string) { 24 | return 25 | } 26 | 27 | func (l *emptyLocker) Close() error { 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /plugin/default/lock/empty_lock_test.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestEmptyLocker(t *testing.T) { 11 | locker := &emptyLocker{} 12 | 13 | res, err := locker.Lock(context.Background(), "", 0) 14 | assert.NoError(t, err) 15 | assert.Equal(t, res, "") 16 | 17 | locker.Unlock(context.Background(), "", "") 18 | 19 | err = locker.Close() 20 | assert.NoError(t, err) 21 | } 22 | -------------------------------------------------------------------------------- /plugin/default/pki/config.go: -------------------------------------------------------------------------------- 1 | package pki 2 | 3 | import "time" 4 | 5 | // CloudConfig baetyl-cloud config 6 | type CloudConfig struct { 7 | PKI struct { 8 | RootCAFile string `yaml:"rootCAFile" json:"rootCAFile" binding:"nonzero"` 9 | RootCAKeyFile string `yaml:"rootCAKeyFile" json:"rootCAKeyFile" binding:"nonzero"` 10 | SubDuration time.Duration `yaml:"subDuration" json:"subDuration" default:"175200h"` // 20*365*24 11 | RootDuration time.Duration `yaml:"rootDuration" json:"rootDuration" default:"438000h"` // 50*365*24 12 | Persistent string `yaml:"persistent" json:"persistent" default:"database"` 13 | } `yaml:"defaultpki" json:"defaultpki"` 14 | } 15 | -------------------------------------------------------------------------------- /plugin/default/pki/config_test.go: -------------------------------------------------------------------------------- 1 | package pki 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/baetyl/baetyl-go/v2/utils" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestPKI_Config(t *testing.T) { 12 | exp := CloudConfig{} 13 | exp.PKI.RootCAFile = "etc/config/cloud/ca.pem" 14 | exp.PKI.RootCAKeyFile = "etc/config/cloud/ca.key" 15 | exp.PKI.SubDuration = 20 * 365 * 24 * time.Hour 16 | exp.PKI.RootDuration = 50 * 365 * 24 * time.Hour 17 | exp.PKI.Persistent = "database" 18 | 19 | in := ` 20 | defaultpki: 21 | rootCAFile: "etc/config/cloud/ca.pem" 22 | rootCAKeyFile: "etc/config/cloud/ca.key" 23 | persistent: "database" 24 | ` 25 | cfg := CloudConfig{} 26 | err := utils.UnmarshalYAML([]byte(in), &cfg) 27 | assert.NoError(t, err) 28 | assert.EqualValues(t, exp, cfg) 29 | } 30 | -------------------------------------------------------------------------------- /plugin/default/quota/quota.go: -------------------------------------------------------------------------------- 1 | package quota 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/plugin" 5 | ) 6 | 7 | type quota struct { 8 | } 9 | 10 | func init() { 11 | plugin.RegisterFactory("defaultquota", New) 12 | } 13 | 14 | func New() (plugin.Plugin, error) { 15 | return "a{}, nil 16 | } 17 | 18 | var _ plugin.Quota = "a{} 19 | 20 | func (l *quota) GetQuota(namespace string) (map[string]int, error) { 21 | return map[string]int{}, nil 22 | } 23 | 24 | func (l *quota) GetDefaultQuotas(namespace string) (map[string]int, error) { 25 | return map[string]int{}, nil 26 | } 27 | 28 | func (l *quota) CreateQuota(namespace string, quotas map[string]int) error { 29 | return nil 30 | } 31 | 32 | func (l *quota) UpdateQuota(namespace, quotaName string, quota int) error { 33 | return nil 34 | } 35 | 36 | func (l *quota) AcquireQuota(namespace, quotaName string, number int) error { 37 | return nil 38 | } 39 | 40 | func (l *quota) ReleaseQuota(namespace, quotaName string, number int) error { 41 | return nil 42 | } 43 | 44 | func (l *quota) DeleteQuota(namespace, quotaName string) error { 45 | return nil 46 | } 47 | 48 | func (l *quota) DeleteQuotaByNamespace(namespace string) error { 49 | return nil 50 | } 51 | 52 | func (l *quota) Close() error { 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /plugin/default/sign/config.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | type CloudConfig struct { 4 | DefaultSign struct { 5 | } `yaml:"defaultsign" json:"defaultsign"` 6 | } 7 | -------------------------------------------------------------------------------- /plugin/default/sign/sign.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | import ( 4 | "bytes" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/common" 7 | "github.com/baetyl/baetyl-cloud/v2/plugin" 8 | ) 9 | 10 | type defaultSign struct { 11 | cfg CloudConfig 12 | } 13 | 14 | func init() { 15 | plugin.RegisterFactory("defaultsign", New) 16 | } 17 | 18 | // New New 19 | func New() (plugin.Plugin, error) { 20 | var cfg CloudConfig 21 | if err := common.LoadConfig(&cfg); err != nil { 22 | return nil, err 23 | } 24 | return &defaultSign{ 25 | cfg: cfg, 26 | }, nil 27 | } 28 | 29 | func (d *defaultSign) Signature(meta []byte) ([]byte, error) { 30 | return meta, nil 31 | } 32 | 33 | func (d *defaultSign) Verify(meta, sign []byte) bool { 34 | return bytes.Equal(meta, sign) 35 | } 36 | 37 | // Close Close 38 | func (d *defaultSign) Close() error { 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /plugin/default/sign/sign_test.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | import ( 4 | "encoding/base64" 5 | "io/ioutil" 6 | "os" 7 | "path" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | 12 | "github.com/baetyl/baetyl-cloud/v2/config" 13 | "github.com/baetyl/baetyl-cloud/v2/plugin" 14 | ) 15 | 16 | const ( 17 | confData = ` 18 | defaultsign: 19 | ` 20 | ) 21 | 22 | func setUp() *config.CloudConfig { 23 | conf := &config.CloudConfig{} 24 | conf.Plugin.Sign = "defaultsign" 25 | return conf 26 | } 27 | 28 | func genConfig(workspace string) error { 29 | if err := os.MkdirAll(workspace, 0755); err != nil { 30 | return err 31 | } 32 | if err := ioutil.WriteFile(path.Join(workspace, "cloud.yml"), []byte(confData), 0755); err != nil { 33 | return err 34 | } 35 | return nil 36 | } 37 | 38 | func TestDefaultSign_Sign_Verify(t *testing.T) { 39 | err := genConfig("etc/baetyl") 40 | assert.NoError(t, err) 41 | defer os.RemoveAll(path.Dir("etc/baetyl")) 42 | 43 | cfg := setUp() 44 | iam, err := plugin.GetPlugin(cfg.Plugin.Sign) 45 | assert.NoError(t, err) 46 | auth := iam.(plugin.Sign) 47 | 48 | meta := []byte("test") 49 | sign, err := auth.Signature(meta) 50 | assert.Nil(t, err) 51 | res := "dGVzdA==" 52 | assert.Equal(t, res, base64.StdEncoding.EncodeToString(sign)) 53 | 54 | inc := auth.Verify(meta, sign) 55 | assert.Equal(t, true, inc) 56 | } 57 | -------------------------------------------------------------------------------- /plugin/default/task/default_task.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/task" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/plugin" 7 | ) 8 | 9 | func init() { 10 | plugin.RegisterFactory("defaulttask", New) 11 | } 12 | 13 | type defaultTask struct { 14 | task.TaskProducer 15 | task.TaskWorker 16 | broker task.TaskBroker 17 | backend task.TaskBackend 18 | } 19 | 20 | func New() (plugin.Plugin, error) { 21 | broker := task.NewChannelBroker(10) 22 | backend := task.NewMapBackend() 23 | 24 | return &defaultTask{ 25 | task.NewTaskProducer(broker, backend), 26 | task.NewTaskWorker(broker, backend), 27 | broker, 28 | backend, 29 | }, nil 30 | } 31 | 32 | func (dt *defaultTask) Close() error { 33 | return dt.broker.Close() 34 | } 35 | -------------------------------------------------------------------------------- /plugin/default/transaction/default_tx_factory.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/plugin" 5 | ) 6 | 7 | func init() { 8 | plugin.RegisterFactory("defaulttx", New) 9 | } 10 | 11 | type defaultTxFactory struct{} 12 | 13 | func New() (plugin.Plugin, error) { 14 | return &defaultTxFactory{}, nil 15 | } 16 | 17 | func (t *defaultTxFactory) BeginTx() (interface{}, error) { 18 | return nil, nil 19 | } 20 | 21 | func (t *defaultTxFactory) Commit(tx interface{}) {} 22 | 23 | func (t *defaultTxFactory) Rollback(tx interface{}) {} 24 | 25 | func (t *defaultTxFactory) Close() error { 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /plugin/function.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/function.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Function 10 | 11 | // Function interface of Function 12 | type Function interface { 13 | List(userID string) ([]models.Function, error) 14 | ListFunctionVersions(userID, name string) ([]models.Function, error) 15 | Get(userID, name, version string) (*models.Function, error) 16 | io.Closer 17 | } 18 | -------------------------------------------------------------------------------- /plugin/index.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "database/sql" 5 | "io" 6 | 7 | "github.com/jmoiron/sqlx" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/common" 10 | ) 11 | 12 | //go:generate mockgen -destination=../mock/plugin/index.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Index 13 | 14 | // Index interface of Index 15 | type Index interface { 16 | // index 17 | CreateIndex(namespace string, keyA, keyB common.Resource, valueA, valueB string) (sql.Result, error) 18 | ListIndex(namespace string, keyA, byKeyB common.Resource, valueB string) ([]string, error) 19 | DeleteIndex(namespace string, keyA, byKeyB common.Resource, valueB string) (sql.Result, error) 20 | CreateIndexTx(tx *sqlx.Tx, namespace string, keyA, keyB common.Resource, valueA, valueB string) (sql.Result, error) 21 | ListIndexTx(tx *sqlx.Tx, namespace string, keyA, byKeyB common.Resource, valueB string) ([]string, error) 22 | DeleteIndexTx(tx *sqlx.Tx, namespace string, keyA, byKeyB common.Resource, valueB string) (sql.Result, error) 23 | RefreshIndex(tx interface{}, namespace string, keyA, keyB common.Resource, valueA string, valueBs []string) error 24 | io.Closer 25 | } 26 | -------------------------------------------------------------------------------- /plugin/jwt.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | "time" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/common" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/plugin/jwt.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin JWT 11 | 12 | type JWT interface { 13 | GetJWT(c *common.Context) (string, error) 14 | GenerateJWT(c *common.Context) (*JWTInfo, error) 15 | RefreshJWT(c *common.Context) (*JWTInfo, error) 16 | CheckAndParseJWT(c *common.Context) (map[string]interface{}, error) 17 | io.Closer 18 | } 19 | 20 | type JWTInfo struct { 21 | Token string `json:"token"` 22 | Expire time.Time `json:"expire"` 23 | MaxRefresh time.Time `json:"maxRefresh"` 24 | } 25 | -------------------------------------------------------------------------------- /plugin/kube/apis/cloud/register.go: -------------------------------------------------------------------------------- 1 | package cloud 2 | 3 | const ( 4 | GroupName = "cloud.baetyl.io" 5 | ) 6 | -------------------------------------------------------------------------------- /plugin/kube/apis/cloud/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // +k8s:deepcopy-gen=package 2 | // +groupName=cloud.baetyl.io 3 | 4 | package v1alpha1 5 | -------------------------------------------------------------------------------- /plugin/kube/apis/cloud/v1alpha1/register.go: -------------------------------------------------------------------------------- 1 | // +k8s:openapi-gen=true 2 | // +k8s:deepcopy-gen=package,register 3 | // +k8s:conversion-gen=baetyl-cloud/plugin/kube/apis/cloud 4 | // +k8s:defaulter-gen=TypeMeta 5 | // +groupName=cloud.baetyl.io 6 | 7 | package v1alpha1 8 | 9 | import ( 10 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/apimachinery/pkg/runtime" 12 | "k8s.io/apimachinery/pkg/runtime/schema" 13 | 14 | "github.com/baetyl/baetyl-cloud/v2/plugin/kube/apis/cloud" 15 | ) 16 | 17 | // SchemeGroupVersion is group version used to register these objects 18 | var SchemeGroupVersion = schema.GroupVersion{Group: cloud.GroupName, Version: "v1alpha1"} 19 | 20 | // Kind takes an unqualified kind and returns back a Group qualified GroupKind 21 | func Kind(kind string) schema.GroupKind { 22 | return SchemeGroupVersion.WithKind(kind).GroupKind() 23 | } 24 | 25 | // Resource takes an unqualified resource and returns a Group qualified GroupResource 26 | func Resource(resource string) schema.GroupResource { 27 | return SchemeGroupVersion.WithResource(resource).GroupResource() 28 | } 29 | 30 | var ( 31 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. 32 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 33 | AddToScheme = SchemeBuilder.AddToScheme 34 | ) 35 | 36 | // Adds the list of known types to api.Scheme. 37 | func addKnownTypes(scheme *runtime.Scheme) error { 38 | scheme.AddKnownTypes(SchemeGroupVersion, 39 | &Application{}, 40 | &ApplicationList{}, 41 | &Configuration{}, 42 | &ConfigurationList{}, 43 | &Node{}, 44 | &NodeList{}, 45 | &NodeReport{}, 46 | &NodeReportList{}, 47 | &NodeDesire{}, 48 | &NodeDesireList{}, 49 | &Secret{}, 50 | &SecretList{}, 51 | ) 52 | v1.AddToGroupVersion(scheme, SchemeGroupVersion) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /plugin/kube/client.go: -------------------------------------------------------------------------------- 1 | package kube 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/baetyl/baetyl-go/v2/log" 7 | "k8s.io/client-go/kubernetes" 8 | corev1 "k8s.io/client-go/kubernetes/typed/core/v1" 9 | "k8s.io/client-go/rest" 10 | "k8s.io/client-go/tools/clientcmd" 11 | 12 | "github.com/baetyl/baetyl-cloud/v2/common" 13 | "github.com/baetyl/baetyl-cloud/v2/plugin" 14 | clientset "github.com/baetyl/baetyl-cloud/v2/plugin/kube/client/clientset/versioned" 15 | ) 16 | 17 | type client struct { 18 | coreV1 corev1.CoreV1Interface 19 | customClient clientset.Interface 20 | cfg CloudConfig 21 | aesKey []byte 22 | ctx context.Context 23 | cancel context.CancelFunc 24 | log *log.Logger 25 | } 26 | 27 | func (c *client) Close() error { 28 | c.cancel() 29 | return nil 30 | } 31 | 32 | func init() { 33 | plugin.RegisterFactory("kube", New) 34 | plugin.RegisterFactory("kubernetes", New) 35 | } 36 | 37 | // New New 38 | func New() (plugin.Plugin, error) { 39 | var cfg CloudConfig 40 | if err := common.LoadConfig(&cfg); err != nil { 41 | return nil, err 42 | } 43 | 44 | kubeConfig, err := func() (*rest.Config, error) { 45 | if !cfg.Kube.OutCluster { 46 | return rest.InClusterConfig() 47 | } 48 | return clientcmd.BuildConfigFromFlags( 49 | "", cfg.Kube.ConfigPath) 50 | }() 51 | if err != nil { 52 | return nil, err 53 | } 54 | kubeClient, err := kubernetes.NewForConfig(kubeConfig) 55 | if err != nil { 56 | return nil, err 57 | } 58 | kubeClient.CoreV1() 59 | customClient, err := clientset.NewForConfig(kubeConfig) 60 | if err != nil { 61 | return nil, err 62 | } 63 | ctx, cancel := context.WithCancel(context.Background()) 64 | return &client{ 65 | coreV1: kubeClient.CoreV1(), 66 | customClient: customClient, 67 | cfg: cfg, 68 | ctx: ctx, 69 | cancel: cancel, 70 | aesKey: []byte(cfg.Kube.AES.Key), 71 | log: log.With(log.Any("plugin", "kube")), 72 | }, nil 73 | } 74 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package has the automatically generated clientset. 4 | package versioned 5 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package has the automatically generated fake clientset. 4 | package fake 5 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package fake 4 | 5 | import ( 6 | cloudv1alpha1 "github.com/baetyl/baetyl-cloud/v2/plugin/kube/apis/cloud/v1alpha1" 7 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | runtime "k8s.io/apimachinery/pkg/runtime" 9 | schema "k8s.io/apimachinery/pkg/runtime/schema" 10 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 11 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 12 | ) 13 | 14 | var scheme = runtime.NewScheme() 15 | var codecs = serializer.NewCodecFactory(scheme) 16 | 17 | var localSchemeBuilder = runtime.SchemeBuilder{ 18 | cloudv1alpha1.AddToScheme, 19 | } 20 | 21 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 22 | // of clientsets, like in: 23 | // 24 | // import ( 25 | // "k8s.io/client-go/kubernetes" 26 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 27 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 28 | // ) 29 | // 30 | // kclientset, _ := kubernetes.NewForConfig(c) 31 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 32 | // 33 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 34 | // correctly. 35 | var AddToScheme = localSchemeBuilder.AddToScheme 36 | 37 | func init() { 38 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 39 | utilruntime.Must(AddToScheme(scheme)) 40 | } 41 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package contains the scheme of the automatically generated clientset. 4 | package scheme 5 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package scheme 4 | 5 | import ( 6 | cloudv1alpha1 "github.com/baetyl/baetyl-cloud/v2/plugin/kube/apis/cloud/v1alpha1" 7 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | runtime "k8s.io/apimachinery/pkg/runtime" 9 | schema "k8s.io/apimachinery/pkg/runtime/schema" 10 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 11 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 12 | ) 13 | 14 | var Scheme = runtime.NewScheme() 15 | var Codecs = serializer.NewCodecFactory(Scheme) 16 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 17 | var localSchemeBuilder = runtime.SchemeBuilder{ 18 | cloudv1alpha1.AddToScheme, 19 | } 20 | 21 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 22 | // of clientsets, like in: 23 | // 24 | // import ( 25 | // "k8s.io/client-go/kubernetes" 26 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 27 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 28 | // ) 29 | // 30 | // kclientset, _ := kubernetes.NewForConfig(c) 31 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 32 | // 33 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 34 | // correctly. 35 | var AddToScheme = localSchemeBuilder.AddToScheme 36 | 37 | func init() { 38 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 39 | utilruntime.Must(AddToScheme(Scheme)) 40 | } 41 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/typed/cloud/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // This package has the automatically generated typed clients. 4 | package v1alpha1 5 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/typed/cloud/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | // Package fake has the automatically generated clients. 4 | package fake 5 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/typed/cloud/v1alpha1/fake/fake_cloud_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package fake 4 | 5 | import ( 6 | v1alpha1 "github.com/baetyl/baetyl-cloud/v2/plugin/kube/client/clientset/versioned/typed/cloud/v1alpha1" 7 | rest "k8s.io/client-go/rest" 8 | testing "k8s.io/client-go/testing" 9 | ) 10 | 11 | type FakeCloudV1alpha1 struct { 12 | *testing.Fake 13 | } 14 | 15 | func (c *FakeCloudV1alpha1) Applications(namespace string) v1alpha1.ApplicationInterface { 16 | return &FakeApplications{c, namespace} 17 | } 18 | 19 | func (c *FakeCloudV1alpha1) Configurations(namespace string) v1alpha1.ConfigurationInterface { 20 | return &FakeConfigurations{c, namespace} 21 | } 22 | 23 | func (c *FakeCloudV1alpha1) Nodes(namespace string) v1alpha1.NodeInterface { 24 | return &FakeNodes{c, namespace} 25 | } 26 | 27 | func (c *FakeCloudV1alpha1) NodeDesires(namespace string) v1alpha1.NodeDesireInterface { 28 | return &FakeNodeDesires{c, namespace} 29 | } 30 | 31 | func (c *FakeCloudV1alpha1) NodeReports(namespace string) v1alpha1.NodeReportInterface { 32 | return &FakeNodeReports{c, namespace} 33 | } 34 | 35 | func (c *FakeCloudV1alpha1) Secrets(namespace string) v1alpha1.SecretInterface { 36 | return &FakeSecrets{c, namespace} 37 | } 38 | 39 | // RESTClient returns a RESTClient that is used to communicate 40 | // with API server by this client implementation. 41 | func (c *FakeCloudV1alpha1) RESTClient() rest.Interface { 42 | var ret *rest.RESTClient 43 | return ret 44 | } 45 | -------------------------------------------------------------------------------- /plugin/kube/client/clientset/versioned/typed/cloud/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | // Code generated by client-gen. DO NOT EDIT. 2 | 3 | package v1alpha1 4 | 5 | type ApplicationExpansion interface{} 6 | 7 | type ConfigurationExpansion interface{} 8 | 9 | type NodeExpansion interface{} 10 | 11 | type NodeDesireExpansion interface{} 12 | 13 | type NodeReportExpansion interface{} 14 | 15 | type SecretExpansion interface{} 16 | -------------------------------------------------------------------------------- /plugin/kube/client_test.go: -------------------------------------------------------------------------------- 1 | package kube 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestNew(t *testing.T) { 10 | p, err := New() 11 | assert.Error(t, err) 12 | assert.Nil(t, p) 13 | assert.EqualError(t, err, "open etc/baetyl/cloud.yml: no such file or directory") 14 | } 15 | -------------------------------------------------------------------------------- /plugin/kube/config.go: -------------------------------------------------------------------------------- 1 | package kube 2 | 3 | // CloudConfig baetyl-cloud config 4 | type CloudConfig struct { 5 | Kube struct { 6 | OutCluster bool `yaml:"outCluster" json:"outCluster"` 7 | ConfigPath string `yaml:"configPath" json:"configPath" default:"etc/baetyl/kubeconfig.yml"` 8 | // TODO Remove from plugin 9 | AES struct { 10 | Key string `yaml:"key" json:"key" default:"baetyl2020202020"` 11 | } `yaml:"aes" json:"aes" default:"{}"` 12 | } `yaml:"kube" json:"kube"` 13 | } 14 | -------------------------------------------------------------------------------- /plugin/license.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import "io" 4 | 5 | //go:generate mockgen -destination=../mock/plugin/license.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin License 6 | 7 | type License interface { 8 | ProtectCode() error 9 | CheckLicense() error 10 | io.Closer 11 | } 12 | -------------------------------------------------------------------------------- /plugin/link/httplink/config.go: -------------------------------------------------------------------------------- 1 | package httplink 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/config" 5 | ) 6 | 7 | type CloudConfig struct { 8 | HTTPLink HTTPLinkConfig `yaml:"httplink" json:"httpLink" default:"{\"port\":\":9005\",\"readTimeout\":30000000000,\"writeTimeout\":30000000000,\"shutdownTime\":3000000000,\"commonName\":\"common-name\"}"` 9 | } 10 | 11 | type HTTPLinkConfig struct { 12 | config.Server `yaml:",inline" json:",inline"` 13 | CommonName string `yaml:"commonName" json:"commonName" default:"common-name"` 14 | } 15 | -------------------------------------------------------------------------------- /plugin/lock.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "context" 5 | "io" 6 | ) 7 | 8 | //go:generate mockgen -destination=../mock/plugin/lock.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Locker 9 | 10 | // Locker - the lock manager for baetyl cloud 11 | type Locker interface { 12 | 13 | // Lock lock the resource, Lock should be paired with Unlock. 14 | // PARAMS: 15 | // - name: the lock's name 16 | // - ttl: expire time of lock, if 0, use default time. 17 | // RETURNS: 18 | // error: if has error else nil 19 | Lock(ctx context.Context, name string, ttl int64) (string, error) 20 | 21 | // Unlock release the lock by name 22 | // PARAMS: 23 | // - name: the lock's name 24 | // RETURNS: 25 | // error: if has error else nil 26 | Unlock(ctx context.Context, name, version string) 27 | io.Closer 28 | } 29 | -------------------------------------------------------------------------------- /plugin/module.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/jmoiron/sqlx" 7 | 8 | "github.com/baetyl/baetyl-cloud/v2/common" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/models" 11 | ) 12 | 13 | //go:generate mockgen -destination=../mock/plugin/module.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Module 14 | 15 | type Module interface { 16 | GetModules(name string) ([]models.Module, error) 17 | GetModuleByVersion(name, version string) (*models.Module, error) 18 | GetModuleByImage(name, image string) (*models.Module, error) 19 | GetLatestModule(name string) (*models.Module, error) 20 | CreateModule(module *models.Module) (*models.Module, error) 21 | UpdateModuleByVersion(module *models.Module) (*models.Module, error) 22 | DeleteModules(name string) error 23 | DeleteModuleByVersion(name, version string) error 24 | ListModules(filter *models.Filter, tp common.ModuleType) ([]models.Module, error) 25 | GetLatestModuleImage(name string) (string, error) 26 | GetLatestModuleProgram(name, platform string) (string, error) 27 | 28 | GetModuleTx(tx *sqlx.Tx, name string) ([]models.Module, error) 29 | GetModuleByVersionTx(tx *sqlx.Tx, name, version string) (*models.Module, error) 30 | GetModuleByImageTx(tx *sqlx.Tx, name, image string) (*models.Module, error) 31 | GetLatestModuleTx(tx *sqlx.Tx, name string) (*models.Module, error) 32 | CreateModuleTx(tx *sqlx.Tx, module *models.Module) error 33 | UpdateModuleByVersionTx(tx *sqlx.Tx, module *models.Module) error 34 | DeleteModulesTx(tx *sqlx.Tx, name string) error 35 | DeleteModuleByVersionTx(tx *sqlx.Tx, name, version string) error 36 | ListModulesTx(tx *sqlx.Tx, filter *models.Filter) ([]models.Module, error) 37 | GetLatestModuleImageTx(tx *sqlx.Tx, name string) (string, error) 38 | GetLatestModuleProgramTx(tx *sqlx.Tx, name, platform string) (string, error) 39 | 40 | // close 41 | io.Closer 42 | } 43 | -------------------------------------------------------------------------------- /plugin/namespace.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/models" 5 | ) 6 | 7 | //go:generate mockgen -destination=../mock/plugin/namespace.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Namespace 8 | 9 | type Namespace interface { 10 | GetNamespace(namespace string) (*models.Namespace, error) 11 | CreateNamespace(namespace *models.Namespace) (*models.Namespace, error) 12 | ListNamespace(listOptions *models.ListOptions) (*models.NamespaceList, error) 13 | DeleteNamespace(namespace *models.Namespace) error 14 | } 15 | -------------------------------------------------------------------------------- /plugin/node.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/node.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Node 10 | 11 | type Node interface { 12 | GetNode(tx interface{}, namespace, name string) (*v1.Node, error) 13 | CreateNode(tx interface{}, namespace string, node *v1.Node) (*v1.Node, error) 14 | UpdateNode(tx interface{}, namespace string, node []*v1.Node) ([]*v1.Node, error) 15 | DeleteNode(tx interface{}, namespace, name string) error 16 | ListNode(tx interface{}, namespace string, listOptions *models.ListOptions) (*models.NodeList, error) 17 | CountAllNode(tx interface{}) (int, error) 18 | GetNodeByNames(tx interface{}, namespace string, names []string) ([]v1.Node, error) 19 | } 20 | -------------------------------------------------------------------------------- /plugin/pki.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "crypto/x509" 5 | "io" 6 | "time" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/pki.go -package=plugin -source=pki.go 10 | 11 | type Cert struct { 12 | CertId string `db:"cert_id"` 13 | ParentId string `db:"parent_id"` 14 | Type string `db:"type"` 15 | CommonName string `db:"common_name"` 16 | Csr string `db:"csr"` // base64 17 | Content string `db:"content"` // base64 18 | PrivateKey string `db:"private_key"` // base64 19 | Description string `db:"description"` 20 | NotBefore time.Time `db:"not_before"` 21 | NotAfter time.Time `db:"not_after"` 22 | } 23 | 24 | type PKI interface { 25 | // root cert 26 | GetRootCertID() string 27 | // info : 生成根证书的相关信息 parentId : 上一级根证书id,可为空 28 | CreateRootCert(info *x509.CertificateRequest, parentId string) (string, error) 29 | GetRootCert(rootId string) ([]byte, error) 30 | DeleteRootCert(rootId string) error 31 | 32 | // server cert 33 | CreateServerCert(csr []byte, rootId string) (string, error) 34 | GetServerCert(certId string) ([]byte, error) 35 | DeleteServerCert(certId string) error 36 | 37 | // client cert 38 | CreateClientCert(csr []byte, rootId string) (string, error) 39 | GetClientCert(certId string) ([]byte, error) 40 | DeleteClientCert(certId string) error 41 | 42 | // close 43 | io.Closer 44 | } 45 | 46 | type PKIStorage interface { 47 | CreateCert(cert Cert) error 48 | DeleteCert(certId string) error 49 | UpdateCert(cert Cert) error 50 | GetCert(certId string) (*Cert, error) 51 | CountCertByParentId(parentId string) (int, error) 52 | io.Closer 53 | } 54 | -------------------------------------------------------------------------------- /plugin/property.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/property.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Property 10 | 11 | type Property interface { 12 | GetProperty(name string) (*models.Property, error) 13 | CreateProperty(property *models.Property) error 14 | DeleteProperty(name string) error 15 | ListProperty(page *models.Filter) ([]models.Property, error) //Pagination 16 | CountProperty(name string) (int, error) 17 | UpdateProperty(property *models.Property) error 18 | 19 | GetPropertyValue(name string) (string, error) 20 | 21 | io.Closer 22 | } 23 | -------------------------------------------------------------------------------- /plugin/pubsub.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/pubsub" 5 | ) 6 | 7 | //go:generate mockgen -destination=../mock/plugin/pubsub.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Pubsub 8 | 9 | type Pubsub interface { 10 | pubsub.Pubsub 11 | } 12 | -------------------------------------------------------------------------------- /plugin/quota.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import "io" 4 | 5 | //go:generate mockgen -destination=../mock/plugin/quota.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Quota 6 | 7 | const ( 8 | QuotaNode = "maxNodeCount" 9 | QuotaBatch = "maxBatchCount" 10 | MenuEnable = "menuEnable" 11 | ) 12 | 13 | type QuotaCollector func(namespace string) (map[string]int, error) 14 | 15 | type Quota interface { 16 | GetQuota(namespace string) (map[string]int, error) 17 | GetDefaultQuotas(namespace string) (map[string]int, error) 18 | CreateQuota(namespace string, quotas map[string]int) error 19 | UpdateQuota(namespace, quotaName string, quota int) error 20 | AcquireQuota(namespace, quotaName string, number int) error 21 | ReleaseQuota(namespace, quotaName string, number int) error 22 | DeleteQuota(namespace, quotaName string) error 23 | DeleteQuotaByNamespace(namespace string) error 24 | io.Closer 25 | } 26 | -------------------------------------------------------------------------------- /plugin/register.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | "strings" 6 | "sync" 7 | 8 | "github.com/baetyl/baetyl-go/v2/log" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | ) 12 | 13 | // Plugin interfaces 14 | type Plugin interface { 15 | io.Closer 16 | } 17 | 18 | // Factory create engine by given config 19 | type Factory func() (Plugin, error) 20 | 21 | // PluginFactory contains all supported plugin factory 22 | //var pluginFactory = make(map[string]Factory) 23 | //var plugins = map[string]Plugin{} 24 | 25 | var pluginFactory sync.Map 26 | var plugins sync.Map 27 | 28 | // RegisterFactory adds a supported plugin 29 | func RegisterFactory(name string, f Factory) { 30 | if _, ok := pluginFactory.Load(name); ok { 31 | log.L().Info("plugin already exists, skip", log.Any("plugin", name)) 32 | return 33 | } 34 | pluginFactory.Store(name, f) 35 | log.L().Info("plugin is registered", log.Any("plugin", name)) 36 | } 37 | 38 | // GetPlugin GetPlugin 39 | func GetPlugin(name string) (Plugin, error) { 40 | name = strings.ToLower(name) 41 | if p, ok := plugins.Load(name); ok { 42 | return p.(Plugin), nil 43 | } 44 | f, ok := pluginFactory.Load(name) 45 | if !ok { 46 | return nil, common.Error(common.ErrPluginNotFound, common.Field("name", name)) 47 | } 48 | p, err := f.(Factory)() 49 | if err != nil { 50 | log.L().Error("failed to create plugin", log.Error(err)) 51 | return nil, err 52 | } 53 | act, ok := plugins.LoadOrStore(name, p) 54 | if ok { 55 | err := p.Close() 56 | if err != nil { 57 | log.L().Warn("failed to close plugin", log.Error(err)) 58 | } 59 | return act.(Plugin), nil 60 | } 61 | return p, nil 62 | } 63 | 64 | // ClosePlugins ClosePlugins 65 | func ClosePlugins() { 66 | plugins.Range(func(key, value interface{}) bool { 67 | value.(Plugin).Close() 68 | return true 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /plugin/resource.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import "io" 4 | 5 | //go:generate mockgen -destination=../mock/plugin/resource.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Resource 6 | 7 | type Resource interface { 8 | Node 9 | Application 10 | Configuration 11 | Secret 12 | Namespace 13 | io.Closer 14 | } 15 | -------------------------------------------------------------------------------- /plugin/secret.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | v1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/secret.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Secret 10 | 11 | type Secret interface { 12 | GetSecret(tx interface{}, namespace, name, version string) (*v1.Secret, error) 13 | CreateSecret(tx interface{}, namespace string, secretModel *v1.Secret) (*v1.Secret, error) 14 | UpdateSecret(namespace string, secretMapModel *v1.Secret) (*v1.Secret, error) 15 | DeleteSecret(tx interface{}, namespace, name string) error 16 | ListSecret(namespace string, listOptions *models.ListOptions) (*models.SecretList, error) 17 | } 18 | -------------------------------------------------------------------------------- /plugin/shadow.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/shadow.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Shadow 10 | 11 | // Shadow 12 | type Shadow interface { 13 | Get(tx interface{}, namespace, name string) (*models.Shadow, error) 14 | ListShadowByNames(tx interface{}, namespace string, names []string) ([]*models.Shadow, error) 15 | Create(tx interface{}, shadow *models.Shadow) (*models.Shadow, error) 16 | BatchCreateShadow(shadows []*models.Shadow) ([]*models.Shadow, error) 17 | Delete(tx interface{}, namespace, name string) error 18 | UpdateDesire(tx interface{}, shadow *models.Shadow) error 19 | UpdateDesires(tx interface{}, shadows []*models.Shadow) error 20 | UpdateReport(shadow *models.Shadow) (*models.Shadow, error) 21 | List(namespace string, nodeList *models.NodeList) (*models.ShadowList, error) 22 | ListAll(namespace string) (*models.ShadowList, error) 23 | io.Closer 24 | } 25 | -------------------------------------------------------------------------------- /plugin/sign.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | //go:generate mockgen -destination=../mock/plugin/sign.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Sign 8 | 9 | // Sign interfaces of Sign 10 | type Sign interface { 11 | Signature(meta []byte) ([]byte, error) 12 | Verify(meta, sign []byte) bool 13 | io.Closer 14 | } 15 | -------------------------------------------------------------------------------- /plugin/sign/config.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | type CloudConfig struct { 4 | RSASign struct { 5 | KeyFile string `yaml:"keyFile" json:"keyFile" default:"etc/baetyl/token.key"` 6 | } `yaml:"rsasign" json:"rsasign"` 7 | } 8 | -------------------------------------------------------------------------------- /plugin/sign/sign.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | import ( 4 | "crypto/rsa" 5 | "io/ioutil" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/common" 8 | "github.com/baetyl/baetyl-cloud/v2/common/util" 9 | "github.com/baetyl/baetyl-cloud/v2/plugin" 10 | ) 11 | 12 | type rsaSign struct { 13 | cfg CloudConfig 14 | priv *rsa.PrivateKey 15 | } 16 | 17 | func init() { 18 | plugin.RegisterFactory("rsasign", New) 19 | } 20 | 21 | // New New 22 | func New() (plugin.Plugin, error) { 23 | var cfg CloudConfig 24 | if err := common.LoadConfig(&cfg); err != nil { 25 | return nil, err 26 | } 27 | key, err := ioutil.ReadFile(cfg.RSASign.KeyFile) 28 | if err != nil { 29 | return nil, err 30 | } 31 | priv, err := util.BytesToPrivateKey(key) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return &rsaSign{ 36 | cfg: cfg, 37 | priv: priv, 38 | }, nil 39 | } 40 | 41 | func (r *rsaSign) Signature(meta []byte) ([]byte, error) { 42 | return util.SignPKCS1v15(meta, r.priv) 43 | } 44 | 45 | func (r *rsaSign) Verify(meta, sign []byte) bool { 46 | return util.VerifyPKCS1v15(meta, sign, &r.priv.PublicKey) 47 | } 48 | 49 | // Close Close 50 | func (r *rsaSign) Close() error { 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /plugin/sync_link.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | type SyncLink interface { 8 | Start() 9 | AddMsgRouter(k string, v interface{}) 10 | io.Closer 11 | } 12 | -------------------------------------------------------------------------------- /plugin/task.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/baetyl/baetyl-go/v2/task" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/plugin/task.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin Task 10 | 11 | // Task interface of Task 12 | type Task interface { 13 | task.TaskProducer 14 | task.TaskWorker 15 | 16 | io.Closer 17 | } 18 | -------------------------------------------------------------------------------- /plugin/tx_factory.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import "io" 4 | 5 | //go:generate mockgen -destination=../mock/plugin/tx_factory.go -package=plugin github.com/baetyl/baetyl-cloud/v2/plugin TransactionFactory 6 | 7 | type TransactionFactory interface { 8 | BeginTx() (interface{}, error) 9 | Commit(interface{}) 10 | Rollback(interface{}) 11 | io.Closer 12 | } 13 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: baetyl-cloud 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.16.0 24 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/apply/rbac_v1beta1.yml: -------------------------------------------------------------------------------- 1 | # kubectl apply -f baetyl-cloud-rbac.yml 2 | # kubectl delete -f baetyl-cloud-rbac.yml 3 | 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1beta1 6 | metadata: 7 | name: baetyl-cloud-clusterrole 8 | rules: 9 | - apiGroups: [ "cloud.baetyl.io" ] 10 | resources: [ "secrets","applications","nodes","configurations","nodedesires","nodereports" ] 11 | verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ] 12 | 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1beta1 15 | kind: ClusterRoleBinding 16 | metadata: 17 | name: baetyl-cloud-rbac 18 | subjects: 19 | - kind: ServiceAccount 20 | # Reference to upper's `metadata.name` 21 | name: baetyl-cloud 22 | # Reference to upper's `metadata.namespace` 23 | namespace: default 24 | roleRef: 25 | kind: ClusterRole 26 | name: baetyl-cloud-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/apply_1.27.2/rbac.yml: -------------------------------------------------------------------------------- 1 | # kubectl apply -f baetyl-cloud-rbac.yml 2 | # kubectl delete -f baetyl-cloud-rbac.yml 3 | 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | metadata: 7 | name: baetyl-cloud-clusterrole 8 | rules: 9 | - apiGroups: [ "cloud.baetyl.io" ] 10 | resources: [ "secrets","applications","nodes","configurations","nodedesires","nodereports" ] 11 | verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ] 12 | 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1 15 | kind: ClusterRoleBinding 16 | metadata: 17 | name: baetyl-cloud-rbac 18 | subjects: 19 | - kind: ServiceAccount 20 | # Reference to upper's `metadata.name` 21 | name: baetyl-cloud 22 | # Reference to upper's `metadata.namespace` 23 | namespace: default 24 | roleRef: 25 | kind: ClusterRole 26 | name: baetyl-cloud-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/apply_v1beta1/rbac.yml: -------------------------------------------------------------------------------- 1 | # kubectl apply -f baetyl-cloud-rbac.yml 2 | # kubectl delete -f baetyl-cloud-rbac.yml 3 | 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1beta1 6 | metadata: 7 | name: baetyl-cloud-clusterrole 8 | rules: 9 | - apiGroups: [ "cloud.baetyl.io" ] 10 | resources: [ "secrets","applications","nodes","configurations","nodedesires","nodereports" ] 11 | verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ] 12 | 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1beta1 15 | kind: ClusterRoleBinding 16 | metadata: 17 | name: baetyl-cloud-rbac 18 | subjects: 19 | - kind: ServiceAccount 20 | # Reference to upper's `metadata.name` 21 | name: baetyl-cloud 22 | # Reference to upper's `metadata.namespace` 23 | namespace: default 24 | roleRef: 25 | kind: ClusterRole 26 | name: baetyl-cloud-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/certs/client_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICYjCCAgigAwIBAgIDAYaiMAoGCCqGSM49BAMCMIGlMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRAwDgYDVQQDEwdy 6 | b290LmNhMCAXDTIwMDMyNzA5NTc1NFoYDzIwNTAwMzI3MDk1NzU0WjCBpTELMAkG 7 | A1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxGTAXBgNVBAcTEEhhaWRpYW4gRGlz 8 | dHJpY3QxFTATBgNVBAkTDEJhaWR1IENhbXB1czEPMA0GA1UEERMGMTAwMDkzMR4w 9 | HAYDVQQKExVMaW51eCBGb3VuZGF0aW9uIEVkZ2UxDzANBgNVBAsTBkJBRVRZTDEQ 10 | MA4GA1UEAxMHcm9vdC5jYTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOuYHJY0 11 | 83AeXWAR45lbRRzICdJzoyl0zOFIK6WW7XuJWD/HhYxCedYPaumgwVI7RRsNb+61 12 | VpS95aFMCMDW4yqjIzAhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/ 13 | MAoGCCqGSM49BAMCA0gAMEUCIGhBsis/RIa4+mzBeDwrICAcYZhjqQRc8pP172gQ 14 | yVRvAiEAyRzj7kln/xXd1yPW6BE/cavCp6tmwpvADUlaXS5FE9M= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/certs/client_ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEII0qZCQMJ3QD6FmhD5PExE5qndQNh1tV5fQy7JGpHbCHoAoGCCqGSM49 3 | AwEHoUQDQgAE65gcljTzcB5dYBHjmVtFHMgJ0nOjKXTM4UgrpZbte4lYP8eFjEJ5 4 | 1g9q6aDBUjtFGw1v7rVWlL3loUwIwNbjKg== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICsDCCAlegAwIBAgIDAYahMAoGCCqGSM49BAMCMIGsMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRcwFQYDVQQDEw5j 6 | bGllbnQucm9vdC5jYTAgFw0yMDAzMjcwOTU1MzVaGA8yMDUwMDMyNzA5NTUzNVow 7 | gaoxCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlqaW5nMRkwFwYDVQQHExBIYWlk 8 | aWFuIERpc3RyaWN0MRUwEwYDVQQJEwxCYWlkdSBDYW1wdXMxDzANBgNVBBETBjEw 9 | MDA5MzEeMBwGA1UEChMVTGludXggRm91bmRhdGlvbiBFZGdlMQ8wDQYDVQQLEwZC 10 | QUVUWUwxFTATBgNVBAMTDGNsb3VkLnNlcnZlcjBZMBMGByqGSM49AgEGCCqGSM49 11 | AwEHA0IABKx0tiiKiXS1VcTTK+caqmvYeRVSvyJr3gpZ+oUhCUAmMOTR1Fm2uIfm 12 | P/fErAklhcZY1H8+J87EM5sG11qWcnqjZjBkMA4GA1UdDwEB/wQEAwIFoDATBgNV 13 | HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMC8GA1UdEQQoMCaCJGd6aHh5 14 | LXkzMi1zYW5kYm94MDMxLmd6aHh5LmJhaWR1LmNvbTAKBggqhkjOPQQDAgNHADBE 15 | AiAm5dm4oKY5WFN2eD4xBJIWG/I4IRBH7yVxH3U5SkxaGAIgJIr3gyQEZxySIwPQ 16 | fm56/vWqdMIBTOmtv8q+ixF3Ves= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIG/B4w19XHDyb78DLNKPD+sacQvIIjvoIihW6voRjNGQoAoGCCqGSM49 3 | AwEHoUQDQgAErHS2KIqJdLVVxNMr5xqqa9h5FVK/ImveCln6hSEJQCYw5NHUWba4 4 | h+Y/98SsCSWFxljUfz4nzsQzmwbXWpZyeg== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/certs/server_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICcDCCAhagAwIBAgIDAYagMAoGCCqGSM49BAMCMIGsMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRcwFQYDVQQDEw5j 6 | bGllbnQucm9vdC5jYTAgFw0yMDAzMjcwOTU1MzVaGA8yMDUwMDMyNzA5NTUzNVow 7 | gawxCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlqaW5nMRkwFwYDVQQHExBIYWlk 8 | aWFuIERpc3RyaWN0MRUwEwYDVQQJEwxCYWlkdSBDYW1wdXMxDzANBgNVBBETBjEw 9 | MDA5MzEeMBwGA1UEChMVTGludXggRm91bmRhdGlvbiBFZGdlMQ8wDQYDVQQLEwZC 10 | QUVUWUwxFzAVBgNVBAMTDmNsaWVudC5yb290LmNhMFkwEwYHKoZIzj0CAQYIKoZI 11 | zj0DAQcDQgAE6FKiZEEPgkBbQwqd8vHX7+NPEa3j33WbTz0/xMcoAZTbg9yMZR/9 12 | BfNjArw3rUHc4K9aMNnlFYXu1RCgdLiIxqMjMCEwDgYDVR0PAQH/BAQDAgGGMA8G 13 | A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhAKV27nEL++GfZoA8WGBw 14 | q2MjYpZ2G6tvqQIa9oBI7z/dAiA3z47euYsWN2/rPjRoHTDAa9aZ6bBOXr8t0fKX 15 | sgQJMw== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/conf/cloud.yml: -------------------------------------------------------------------------------- 1 | adminServer: 2 | port: ":9004" 3 | 4 | httplink: 5 | port: ":9005" 6 | ca: "/etc/certs/client_ca.crt" 7 | cert: "/etc/certs/server.crt" 8 | key: "/etc/certs/server.key" 9 | 10 | initServer: 11 | port: ":9003" 12 | ca: "/etc/certs/server_ca.crt" 13 | cert: "/etc/certs/server.crt" 14 | key: "/etc/certs/server.key" 15 | 16 | plugin: 17 | modelStorage: "kubernetes" 18 | databaseStorage: "database" 19 | 20 | template: 21 | path: "/etc/templates" 22 | 23 | database: 24 | type: "mysql" 25 | url: "root:secretpassword@(mariadb:3306)/baetyl_cloud?charset=utf8&parseTime=true" 26 | 27 | defaultpki: 28 | rootCAFile: "/etc/certs/client_ca.crt" 29 | rootCAKeyFile: "/etc/certs/client_ca.key" 30 | rootCertId : "98ec3bc552f0478298aa1c6702a95427" 31 | persistent: "database" 32 | 33 | defaultauth: 34 | keyFile: "/etc/baetyl/token.key" 35 | 36 | logger: 37 | level: debug -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/conf/token.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA41Ux2wPALzq5agrwhNOr0B+BYePAf5CrVPXtfFKmQDdOqBkB 3 | jM5M61cXyWkcET3d/nKyewvNvWjKjXbaWxxaHAbQsen/5vcte9drW5dVvAquYi45 4 | nQDI2gM00u0FAARydqMzYRFZZir7a3d/tsHiH9HWjkOBkXiBpvDWHXjIRBfCRdgX 5 | 3rSwnHDh1Tc0se7rX+0lo8mw7jFCUEH1l9vF/jFE3BGUHK7UHEPg2gDP7w2L8VOF 6 | vTk2rQRGhy2jE3P4xF5x64i8KzOpJw8rbxBezL/yYNcpjuFkkrCpWVLHEgarHPCx 7 | HLB8HkUGAnlM9Apx613icvtRf+sqW1J+F2qfSQIDAQABAoIBAFNrouTcpnxuTzXD 8 | l+kWB5lSxlaWjcAB5W1C5YfWiF1OLlXu/yudVIqTpg3pvTvyePDzQ911QmU7/AAX 9 | Wh9O8x4PvitbU+V8VLt6HFI64WIkhUNP9SJQ9GNUA+FWypvsBdjVIHiBNk4Qfbw8 10 | 2KfG0+SbSuFfkj9Aeks5W0jrVontgPSumKy8oI0Y4BsvqjJmwK+c5EHqQ0pZ5x4D 11 | pluqyArQrAbHLMpfpVtaQXiAFdKnLwVTjEl+kZGFgkoJeoNbHGNQabvvH6fjzvPt 12 | 8DM44Bs4IvUppIHI6sd42XhcyfYXG/HjynUYtND8I0wWIqabOJJHxE71fQ2i8BfU 13 | Y4qxe0UCgYEA7vUzrbr/a8q0iVrp0rG+98E6c3tuPBNB9cYX16dX20PBhxDznsFJ 14 | 6uWdef4x87texQDKYeDScsR9nMiTX7AQDQqMCLHbp65oZGZlXmHJ9LwC7Ppwo3Fc 15 | kt8JGheS+6i6/+SqKAVPyoKMdC5pHQR/APsYmmodq8hLPEQZZfYOuyMCgYEA84u/ 16 | aAc6y7m3WdmsNCxwV4eEkqParrmlYCYHtWRqdRL5M3qg6AYSBZJUCzgPz+YtSPON 17 | hO5/1Vq5WzNOMwdbtKT7M7AwCdI0OrInyEq3gKnfsJP3Dbzj54JUcc+JdZqR+m3E 18 | 5deBoVBuCp0x0/oVpHcgsEBe4yiUBXAB3UjEKKMCgYEAxdRImY8UATiLaJ/UrvMq 19 | x9C4RH0ukRvcYs5CVO6dBNE+ekSlfIxHVuoMCsBQuJkp5201H/1SHWPhHpjLsc+A 20 | KlvN/TDKSjNRB7XiPFY3LZ8tyOW5tQaX/pwZ2/kiXaieUFYOLR3gpiaYg2Mc8MIV 21 | J0m6X7R0phAngVhbspcYMQMCgYAuRv6u4LjOX1K0swTiwRLzvt91EceK7eG7vF44 22 | nIUSC/HoU0Ph8s1X2682loeCpKU0OHtKqBsISn3wE3angZ1uXO8Sqkbmhte/03x1 23 | taTawOytW+BU7vCLXBt5qMrg2uckI9mHJwUNxv+x6p6+PcYBA1Xlx8V/+oTt55Oj 24 | HaGQawKBgAFjOYIs9tZaTqeHFQkw1zs2Da4e54mMp153XGFcby+2N9XQfs8BQitG 25 | CjpiLI/QVvYXOShRZK/cnMJBmqBhec8534D5GxwTeg/xUNlTq+G/9goLMtWKlBZp 26 | rjBUmKcoSNjVQ8UgIBiSXG0XlCNv+rC23eE5gg0OLLBsPIEOuuSf 27 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "baetyl-cloud.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "baetyl-cloud.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "baetyl-cloud.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "baetyl-cloud.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "baetyl-cloud.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 7 | {{- end }} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "baetyl-cloud.fullname" -}} 15 | {{- if .Values.fullnameOverride }} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 17 | {{- else }} 18 | {{- $name := default .Chart.Name .Values.nameOverride }} 19 | {{- if contains $name .Release.Name }} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 21 | {{- else }} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 23 | {{- end }} 24 | {{- end }} 25 | {{- end }} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "baetyl-cloud.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 32 | {{- end }} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "baetyl-cloud.labels" -}} 38 | helm.sh/chart: {{ include "baetyl-cloud.chart" . }} 39 | {{ include "baetyl-cloud.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end }} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "baetyl-cloud.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "baetyl-cloud.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "baetyl-cloud.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include "baetyl-cloud.fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/configmap.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: baetyl-cloud-config-map 5 | labels: 6 | app: "baetyl-cloud-config-map" 7 | data: 8 | {{- (.Files.Glob "conf/*").AsConfig | nindent 2 }} -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "baetyl-cloud.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else -}} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | {{- include "baetyl-cloud.labels" . | nindent 4 }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{- range .Values.ingress.tls }} 22 | - hosts: 23 | {{- range .hosts }} 24 | - {{ . | quote }} 25 | {{- end }} 26 | secretName: {{ .secretName }} 27 | {{- end }} 28 | {{- end }} 29 | rules: 30 | {{- range .Values.ingress.hosts }} 31 | - host: {{ .host | quote }} 32 | http: 33 | paths: 34 | {{- range .paths }} 35 | - path: {{ . }} 36 | backend: 37 | serviceName: {{ $fullName }} 38 | servicePort: {{ $svcPort }} 39 | {{- end }} 40 | {{- end }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: baetyl-cloud-secret 5 | labels: 6 | app: "baetyl-cloud-secret" 7 | type: Opaque 8 | data: 9 | {{(.Files.Glob "certs/*").AsSecrets | nindent 2 }} -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "baetyl-cloud.fullname" . }} 5 | labels: 6 | {{- include "baetyl-cloud.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | {{- toYaml .Values.service.ports | nindent 4 }} 11 | selector: 12 | {{- include "baetyl-cloud.selectorLabels" . | nindent 4 }} 13 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "baetyl-cloud.serviceAccountName" . }} 6 | labels: 7 | {{- include "baetyl-cloud.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /scripts/charts/baetyl-cloud/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "baetyl-cloud.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "baetyl-cloud.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "baetyl-cloud.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /scripts/k8s/apply/baetyl-cloud-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: baetyl-cloud 5 | namespace: default 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: baetyl-cloud 11 | template: 12 | metadata: 13 | labels: 14 | app: baetyl-cloud 15 | spec: 16 | serviceAccountName: baetyl-cloud 17 | containers: 18 | # docker build -t baetyl-cloud:local-build -f Dockerfile-local . 19 | - image: baetyl-cloud:local-build 20 | imagePullPolicy: IfNotPresent 21 | name: baetyl-cloud 22 | ports: 23 | - containerPort: 9004 24 | name: admin-port 25 | protocol: TCP 26 | - containerPort: 9005 27 | name: sync-port 28 | protocol: TCP 29 | - containerPort: 9003 30 | name: init-port 31 | protocol: TCP 32 | volumeMounts: 33 | - mountPath: /etc/baetyl 34 | name: config 35 | volumes: 36 | - name: config 37 | configMap: 38 | name: baetyl-cloud-config 39 | defaultMode: 256 40 | 41 | -------------------------------------------------------------------------------- /scripts/k8s/apply/baetyl-cloud-rbac.yml: -------------------------------------------------------------------------------- 1 | # kubectl apply -f baetyl-cloud-rbac.yml 2 | # kubectl delete -f baetyl-cloud-rbac.yml 3 | 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1beta1 6 | metadata: 7 | name: baetyl-cloud-clusterrole 8 | rules: 9 | - apiGroups: [ "cloud.baetyl.io" ] 10 | resources: [ "secrets","applications","nodes","configurations","nodedesires","nodereports" ] 11 | verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ] 12 | 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1beta1 15 | kind: ClusterRoleBinding 16 | metadata: 17 | name: baetyl-cloud-rbac 18 | subjects: 19 | - kind: ServiceAccount 20 | # Reference to upper's `metadata.name` 21 | name: baetyl-cloud 22 | # Reference to upper's `metadata.namespace` 23 | namespace: default 24 | roleRef: 25 | kind: ClusterRole 26 | name: baetyl-cloud-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /scripts/k8s/apply/baetyl-cloud-service-account.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: baetyl-cloud 5 | namespace: default 6 | labels: 7 | apps: baetyl-cloud 8 | -------------------------------------------------------------------------------- /scripts/k8s/apply/baetyl-cloud-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: baetyl-cloud 5 | labels: 6 | app: baetyl-cloud 7 | spec: 8 | type: NodePort 9 | ports: 10 | - name: init-port 11 | nodePort: 30003 12 | port: 9003 13 | protocol: TCP 14 | targetPort: 9003 15 | - name: admin-port 16 | nodePort: 30004 17 | port: 9004 18 | protocol: TCP 19 | targetPort: 9004 20 | - name: sync-port 21 | nodePort: 30005 22 | port: 9005 23 | protocol: TCP 24 | targetPort: 9005 25 | selector: 26 | app: baetyl-cloud 27 | -------------------------------------------------------------------------------- /scripts/k8s/apply_v1beta1/baetyl-cloud-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: baetyl-cloud 5 | namespace: default 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: baetyl-cloud 11 | template: 12 | metadata: 13 | labels: 14 | app: baetyl-cloud 15 | spec: 16 | serviceAccountName: baetyl-cloud 17 | containers: 18 | # docker build -t baetyl-cloud:local-build -f Dockerfile-local . 19 | - image: baetyl-cloud:local-build 20 | imagePullPolicy: IfNotPresent 21 | name: baetyl-cloud 22 | ports: 23 | - containerPort: 9004 24 | name: admin-port 25 | protocol: TCP 26 | - containerPort: 9005 27 | name: sync-port 28 | protocol: TCP 29 | - containerPort: 9003 30 | name: init-port 31 | protocol: TCP 32 | volumeMounts: 33 | - mountPath: /etc/baetyl 34 | name: config 35 | - mountPath: /etc/baetyl/templates 36 | name: templates 37 | volumes: 38 | - name: config 39 | configMap: 40 | name: baetyl-cloud-config 41 | defaultMode: 256 42 | - name: templates 43 | configMap: 44 | name: baetyl-cloud-templates 45 | defaultMode: 256 46 | 47 | -------------------------------------------------------------------------------- /scripts/k8s/apply_v1beta1/baetyl-cloud-rbac.yml: -------------------------------------------------------------------------------- 1 | # kubectl apply -f baetyl-cloud-rbac.yml 2 | # kubectl delete -f baetyl-cloud-rbac.yml 3 | 4 | kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1beta1 6 | metadata: 7 | name: baetyl-cloud-clusterrole 8 | rules: 9 | - apiGroups: [ "cloud.baetyl.io" ] 10 | resources: [ "secrets","applications","nodes","configurations","nodedesires","nodereports" ] 11 | verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ] 12 | 13 | --- 14 | apiVersion: rbac.authorization.k8s.io/v1beta1 15 | kind: ClusterRoleBinding 16 | metadata: 17 | name: baetyl-cloud-rbac 18 | subjects: 19 | - kind: ServiceAccount 20 | # Reference to upper's `metadata.name` 21 | name: baetyl-cloud 22 | # Reference to upper's `metadata.namespace` 23 | namespace: default 24 | roleRef: 25 | kind: ClusterRole 26 | name: baetyl-cloud-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /scripts/k8s/apply_v1beta1/baetyl-cloud-service-account.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: baetyl-cloud 5 | namespace: default 6 | labels: 7 | apps: baetyl-cloud 8 | -------------------------------------------------------------------------------- /scripts/k8s/apply_v1beta1/baetyl-cloud-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: baetyl-cloud 5 | labels: 6 | app: baetyl-cloud 7 | spec: 8 | type: NodePort 9 | ports: 10 | - name: init-port 11 | nodePort: 30003 12 | port: 9003 13 | protocol: TCP 14 | targetPort: 9003 15 | - name: admin-port 16 | nodePort: 30004 17 | port: 9004 18 | protocol: TCP 19 | targetPort: 9004 20 | - name: sync-port 21 | nodePort: 30005 22 | port: 9005 23 | protocol: TCP 24 | targetPort: 9005 25 | selector: 26 | app: baetyl-cloud 27 | -------------------------------------------------------------------------------- /scripts/native/certs/client_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICYjCCAgigAwIBAgIDAYaiMAoGCCqGSM49BAMCMIGlMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRAwDgYDVQQDEwdy 6 | b290LmNhMCAXDTIwMDMyNzA5NTc1NFoYDzIwNTAwMzI3MDk1NzU0WjCBpTELMAkG 7 | A1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxGTAXBgNVBAcTEEhhaWRpYW4gRGlz 8 | dHJpY3QxFTATBgNVBAkTDEJhaWR1IENhbXB1czEPMA0GA1UEERMGMTAwMDkzMR4w 9 | HAYDVQQKExVMaW51eCBGb3VuZGF0aW9uIEVkZ2UxDzANBgNVBAsTBkJBRVRZTDEQ 10 | MA4GA1UEAxMHcm9vdC5jYTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOuYHJY0 11 | 83AeXWAR45lbRRzICdJzoyl0zOFIK6WW7XuJWD/HhYxCedYPaumgwVI7RRsNb+61 12 | VpS95aFMCMDW4yqjIzAhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/ 13 | MAoGCCqGSM49BAMCA0gAMEUCIGhBsis/RIa4+mzBeDwrICAcYZhjqQRc8pP172gQ 14 | yVRvAiEAyRzj7kln/xXd1yPW6BE/cavCp6tmwpvADUlaXS5FE9M= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /scripts/native/certs/client_ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEII0qZCQMJ3QD6FmhD5PExE5qndQNh1tV5fQy7JGpHbCHoAoGCCqGSM49 3 | AwEHoUQDQgAE65gcljTzcB5dYBHjmVtFHMgJ0nOjKXTM4UgrpZbte4lYP8eFjEJ5 4 | 1g9q6aDBUjtFGw1v7rVWlL3loUwIwNbjKg== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /scripts/native/certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICsDCCAlegAwIBAgIDAYahMAoGCCqGSM49BAMCMIGsMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRcwFQYDVQQDEw5j 6 | bGllbnQucm9vdC5jYTAgFw0yMDAzMjcwOTU1MzVaGA8yMDUwMDMyNzA5NTUzNVow 7 | gaoxCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlqaW5nMRkwFwYDVQQHExBIYWlk 8 | aWFuIERpc3RyaWN0MRUwEwYDVQQJEwxCYWlkdSBDYW1wdXMxDzANBgNVBBETBjEw 9 | MDA5MzEeMBwGA1UEChMVTGludXggRm91bmRhdGlvbiBFZGdlMQ8wDQYDVQQLEwZC 10 | QUVUWUwxFTATBgNVBAMTDGNsb3VkLnNlcnZlcjBZMBMGByqGSM49AgEGCCqGSM49 11 | AwEHA0IABKx0tiiKiXS1VcTTK+caqmvYeRVSvyJr3gpZ+oUhCUAmMOTR1Fm2uIfm 12 | P/fErAklhcZY1H8+J87EM5sG11qWcnqjZjBkMA4GA1UdDwEB/wQEAwIFoDATBgNV 13 | HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMC8GA1UdEQQoMCaCJGd6aHh5 14 | LXkzMi1zYW5kYm94MDMxLmd6aHh5LmJhaWR1LmNvbTAKBggqhkjOPQQDAgNHADBE 15 | AiAm5dm4oKY5WFN2eD4xBJIWG/I4IRBH7yVxH3U5SkxaGAIgJIr3gyQEZxySIwPQ 16 | fm56/vWqdMIBTOmtv8q+ixF3Ves= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /scripts/native/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIG/B4w19XHDyb78DLNKPD+sacQvIIjvoIihW6voRjNGQoAoGCCqGSM49 3 | AwEHoUQDQgAErHS2KIqJdLVVxNMr5xqqa9h5FVK/ImveCln6hSEJQCYw5NHUWba4 4 | h+Y/98SsCSWFxljUfz4nzsQzmwbXWpZyeg== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /scripts/native/certs/server_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICcDCCAhagAwIBAgIDAYagMAoGCCqGSM49BAMCMIGsMQswCQYDVQQGEwJDTjEQ 3 | MA4GA1UECBMHQmVpamluZzEZMBcGA1UEBxMQSGFpZGlhbiBEaXN0cmljdDEVMBMG 4 | A1UECRMMQmFpZHUgQ2FtcHVzMQ8wDQYDVQQREwYxMDAwOTMxHjAcBgNVBAoTFUxp 5 | bnV4IEZvdW5kYXRpb24gRWRnZTEPMA0GA1UECxMGQkFFVFlMMRcwFQYDVQQDEw5j 6 | bGllbnQucm9vdC5jYTAgFw0yMDAzMjcwOTU1MzVaGA8yMDUwMDMyNzA5NTUzNVow 7 | gawxCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlqaW5nMRkwFwYDVQQHExBIYWlk 8 | aWFuIERpc3RyaWN0MRUwEwYDVQQJEwxCYWlkdSBDYW1wdXMxDzANBgNVBBETBjEw 9 | MDA5MzEeMBwGA1UEChMVTGludXggRm91bmRhdGlvbiBFZGdlMQ8wDQYDVQQLEwZC 10 | QUVUWUwxFzAVBgNVBAMTDmNsaWVudC5yb290LmNhMFkwEwYHKoZIzj0CAQYIKoZI 11 | zj0DAQcDQgAE6FKiZEEPgkBbQwqd8vHX7+NPEa3j33WbTz0/xMcoAZTbg9yMZR/9 12 | BfNjArw3rUHc4K9aMNnlFYXu1RCgdLiIxqMjMCEwDgYDVR0PAQH/BAQDAgGGMA8G 13 | A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhAKV27nEL++GfZoA8WGBw 14 | q2MjYpZ2G6tvqQIa9oBI7z/dAiA3z47euYsWN2/rPjRoHTDAa9aZ6bBOXr8t0fKX 15 | sgQJMw== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /scripts/native/conf/conf.yml: -------------------------------------------------------------------------------- 1 | # Change database's url with real account and address. 2 | # Go into scripts/demo/native fold in this project, then start baetyl-cloud by ../../../output/baetyl-cloud -c ./conf/conf.yml 3 | 4 | adminServer: 5 | port: ":9004" 6 | 7 | httplink: 8 | port: ":9005" 9 | ca: "./certs/client_ca.crt" 10 | cert: "./certs/server.crt" 11 | key: "./certs/server.key" 12 | 13 | initServer: 14 | port: ":9003" 15 | ca: "./certs/server_ca.crt" 16 | cert: "./certs/server.crt" 17 | key: "./certs/server.key" 18 | 19 | template: 20 | path: "./templates" 21 | 22 | kube: 23 | outCluster: true 24 | configPath: ./conf/kubeconfig.yml 25 | 26 | database: 27 | type: "mysql" 28 | # kubectl port-forward --namespace default svc/mariadb 3306:3306 29 | url: "root:secretpassword@(localhost:3306)/baetyl_cloud?charset=utf8&parseTime=true" 30 | 31 | defaultpki: 32 | rootCAFile: "./certs/client_ca.crt" 33 | rootCAKeyFile: "./certs/client_ca.key" 34 | persistent: "database" 35 | 36 | defaultauth: 37 | keyFile: "./conf/token.key" 38 | 39 | logger: 40 | level: debug 41 | -------------------------------------------------------------------------------- /scripts/native/conf/token.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA41Ux2wPALzq5agrwhNOr0B+BYePAf5CrVPXtfFKmQDdOqBkB 3 | jM5M61cXyWkcET3d/nKyewvNvWjKjXbaWxxaHAbQsen/5vcte9drW5dVvAquYi45 4 | nQDI2gM00u0FAARydqMzYRFZZir7a3d/tsHiH9HWjkOBkXiBpvDWHXjIRBfCRdgX 5 | 3rSwnHDh1Tc0se7rX+0lo8mw7jFCUEH1l9vF/jFE3BGUHK7UHEPg2gDP7w2L8VOF 6 | vTk2rQRGhy2jE3P4xF5x64i8KzOpJw8rbxBezL/yYNcpjuFkkrCpWVLHEgarHPCx 7 | HLB8HkUGAnlM9Apx613icvtRf+sqW1J+F2qfSQIDAQABAoIBAFNrouTcpnxuTzXD 8 | l+kWB5lSxlaWjcAB5W1C5YfWiF1OLlXu/yudVIqTpg3pvTvyePDzQ911QmU7/AAX 9 | Wh9O8x4PvitbU+V8VLt6HFI64WIkhUNP9SJQ9GNUA+FWypvsBdjVIHiBNk4Qfbw8 10 | 2KfG0+SbSuFfkj9Aeks5W0jrVontgPSumKy8oI0Y4BsvqjJmwK+c5EHqQ0pZ5x4D 11 | pluqyArQrAbHLMpfpVtaQXiAFdKnLwVTjEl+kZGFgkoJeoNbHGNQabvvH6fjzvPt 12 | 8DM44Bs4IvUppIHI6sd42XhcyfYXG/HjynUYtND8I0wWIqabOJJHxE71fQ2i8BfU 13 | Y4qxe0UCgYEA7vUzrbr/a8q0iVrp0rG+98E6c3tuPBNB9cYX16dX20PBhxDznsFJ 14 | 6uWdef4x87texQDKYeDScsR9nMiTX7AQDQqMCLHbp65oZGZlXmHJ9LwC7Ppwo3Fc 15 | kt8JGheS+6i6/+SqKAVPyoKMdC5pHQR/APsYmmodq8hLPEQZZfYOuyMCgYEA84u/ 16 | aAc6y7m3WdmsNCxwV4eEkqParrmlYCYHtWRqdRL5M3qg6AYSBZJUCzgPz+YtSPON 17 | hO5/1Vq5WzNOMwdbtKT7M7AwCdI0OrInyEq3gKnfsJP3Dbzj54JUcc+JdZqR+m3E 18 | 5deBoVBuCp0x0/oVpHcgsEBe4yiUBXAB3UjEKKMCgYEAxdRImY8UATiLaJ/UrvMq 19 | x9C4RH0ukRvcYs5CVO6dBNE+ekSlfIxHVuoMCsBQuJkp5201H/1SHWPhHpjLsc+A 20 | KlvN/TDKSjNRB7XiPFY3LZ8tyOW5tQaX/pwZ2/kiXaieUFYOLR3gpiaYg2Mc8MIV 21 | J0m6X7R0phAngVhbspcYMQMCgYAuRv6u4LjOX1K0swTiwRLzvt91EceK7eG7vF44 22 | nIUSC/HoU0Ph8s1X2682loeCpKU0OHtKqBsISn3wE3angZ1uXO8Sqkbmhte/03x1 23 | taTawOytW+BU7vCLXBt5qMrg2uckI9mHJwUNxv+x6p6+PcYBA1Xlx8V/+oTt55Oj 24 | HaGQawKBgAFjOYIs9tZaTqeHFQkw1zs2Da4e54mMp153XGFcby+2N9XQfs8BQitG 25 | CjpiLI/QVvYXOShRZK/cnMJBmqBhec8534D5GxwTeg/xUNlTq+G/9goLMtWKlBZp 26 | rjBUmKcoSNjVQ8UgIBiSXG0XlCNv+rC23eE5gg0OLLBsPIEOuuSf 27 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-broker-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.BrokerAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | type: "container" 8 | mode: "{{.NodeMode}}" 9 | system: true 10 | replica: 1 11 | services: 12 | - name: "baetyl-broker" 13 | type: "deployment" 14 | image: {{GetModuleImage "baetyl-broker"}} 15 | replica: 1 16 | volumeMounts: 17 | - name: "broker-conf" 18 | mountPath: "/etc/baetyl" 19 | readOnly: true 20 | ports: 21 | - containerPort: 50010 22 | protocol: "TCP" 23 | volumes: 24 | - name: "broker-conf" 25 | config: 26 | name: "{{.BrokerConfName}}" 27 | version: "{{.BrokerConfVersion}}" 28 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-broker-conf.yml: -------------------------------------------------------------------------------- 1 | name: "{{.BrokerConfName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-app-name: "{{.BrokerAppName}}" 6 | baetyl-node-name: "{{.NodeName}}" 7 | baetyl-cloud-system: "true" 8 | data: 9 | conf.yml: |- 10 | session: 11 | sysTopics: ["$link", "$baetyl"] 12 | logger: 13 | level: debug 14 | encoding: console -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-core-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.CoreAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | resource-invisible: "true" 8 | type: "container" 9 | mode: "{{.NodeMode}}" 10 | system: true 11 | replica: 1 12 | services: 13 | - name: "baetyl-core" 14 | type: "deployment" 15 | image: {{GetModuleImage "baetyl"}} 16 | replica: 1 17 | args: 18 | - "core" 19 | volumeMounts: 20 | - name: "core-conf" 21 | mountPath: "/etc/baetyl" 22 | readOnly: true 23 | - name: "node-cert" 24 | mountPath: "/var/lib/baetyl/node" 25 | - name: "core-store-path" 26 | mountPath: "/var/lib/baetyl/store" 27 | - name: "object-download-path" 28 | mountPath: "/var/lib/baetyl/object" 29 | - name: "host-root-path" 30 | mountPath: "/var/lib/baetyl/host" 31 | ports: 32 | - containerPort: 80 33 | hostPort: {{.CoreAPIPort}} 34 | protocol: "TCP" 35 | security: 36 | privileged: true 37 | volumes: 38 | - name: "core-conf" 39 | config: 40 | name: "{{.CoreConfName}}" 41 | version: "{{.CoreConfVersion}}" 42 | - name: "node-cert" 43 | secret: 44 | name: "{{.NodeCertName}}" 45 | version: "{{.NodeCertVersion}}" 46 | - name: "core-store-path" 47 | hostPath: 48 | path: "{{.BAETYL_HOST_PATH_LIB}}/core/store" 49 | - name: "object-download-path" 50 | hostPath: 51 | path: "{{.BAETYL_HOST_PATH_LIB}}/object" 52 | - name: "host-root-path" 53 | hostPath: 54 | path: "{{.BAETYL_HOST_PATH_LIB}}/host" -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-core-conf.yml: -------------------------------------------------------------------------------- 1 | name: "{{.CoreConfName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-app-name: "{{.CoreAppName}}" 6 | baetyl-node-name: "{{.NodeName}}" 7 | baetyl-cloud-system: "true" 8 | data: 9 | conf.yml: |- 10 | node: 11 | ca: var/lib/baetyl/node/ca.pem 12 | key: var/lib/baetyl/node/client.key 13 | cert: var/lib/baetyl/node/client.pem 14 | server: 15 | key: var/lib/baetyl/system/certs/key.pem 16 | cert: var/lib/baetyl/system/certs/crt.pem 17 | sync: 18 | download: 19 | timeout: 30m 20 | report: 21 | interval: {{.CoreFrequency}} 22 | httplink: 23 | address: "{{GetProperty "sync-server-address"}}" 24 | insecureSkipVerify: true 25 | logger: 26 | level: debug 27 | encoding: console -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-ekuiper-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.EkuiperAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | type: "container" 8 | mode: "{{.NodeMode}}" 9 | system: true 10 | replica: 1 11 | services: 12 | - name: "baetyl-ekuiper" 13 | type: "deployment" 14 | image: {{GetModuleImage "baetyl-ekuiper"}} 15 | replica: 1 16 | volumeMounts: 17 | - name: "kuiper-data" 18 | mountPath: "/kuiper/data" 19 | ports: 20 | - containerPort: 9081 21 | protocol: "TCP" 22 | volumes: 23 | - name: "kuiper-data" 24 | hostPath: 25 | path: "/var/lib/baetyl/kuiper/data" 26 | type: "DirectoryOrCreate" 27 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-function-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.FunctionAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | resource-invisible: "true" 8 | type: "container" 9 | mode: "{{.NodeMode}}" 10 | system: true 11 | replica: 1 12 | services: 13 | - name: "baetyl-function" 14 | image: "{{GetModuleImage "baetyl-function"}}" 15 | type: "deployment" 16 | replica: 1 17 | volumeMounts: 18 | - name: "func-conf" 19 | mountPath: "/etc/baetyl" 20 | readOnly: true 21 | ports: 22 | - containerPort: 50011 23 | protocol: "TCP" 24 | volumes: 25 | - name: "func-conf" 26 | config: 27 | name: "{{.FunctionConfName}}" 28 | version: "{{.FunctionConfVersion}}" 29 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-function-conf.yml: -------------------------------------------------------------------------------- 1 | name: "{{.FunctionConfName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-app-name: "{{.FunctionAppName}}" 6 | baetyl-node-name: "{{.NodeName}}" 7 | baetyl-cloud-system: "true" 8 | resource-invisible: "true" 9 | data: 10 | conf.yml: |- 11 | logger: 12 | level: debug 13 | encoding: console -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-init-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.InitAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | resource-invisible: "true" 8 | type: "container" 9 | mode: "{{.NodeMode}}" 10 | system: true 11 | replica: 1 12 | services: 13 | - name: "baetyl-init" 14 | type: "deployment" 15 | image: {{GetModuleImage "baetyl"}} 16 | replica: 1 17 | args: 18 | - "init" 19 | volumeMounts: 20 | - name: "init-conf" 21 | mountPath: "/etc/baetyl" 22 | readOnly: true 23 | - name: "node-cert" 24 | mountPath: "/var/lib/baetyl/node" 25 | - name: "init-store-path" 26 | mountPath: "/var/lib/baetyl/store" 27 | - name: "object-download-path" 28 | mountPath: "/var/lib/baetyl/object" 29 | - name: "host-root-path" 30 | mountPath: "/var/lib/baetyl/host" 31 | security: 32 | privileged: true 33 | volumes: 34 | - name: "init-conf" 35 | config: 36 | name: "{{.InitConfName}}" 37 | version: "{{.InitConfVersion}}" 38 | - name: "node-cert" 39 | secret: 40 | name: "{{.NodeCertName}}" 41 | version: "{{.NodeCertVersion}}" 42 | - name: "init-store-path" 43 | hostPath: 44 | path: "{{.BAETYL_HOST_PATH_LIB}}/init/store" 45 | - name: "object-download-path" 46 | hostPath: 47 | path: "{{.BAETYL_HOST_PATH_LIB}}/object" 48 | - name: "host-root-path" 49 | hostPath: 50 | path: "{{.BAETYL_HOST_PATH_LIB}}/host" -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-init-conf.yml: -------------------------------------------------------------------------------- 1 | name: "{{.InitConfName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-app-name: "{{.InitAppName}}" 6 | baetyl-node-name: "{{.NodeName}}" 7 | baetyl-cloud-system: "true" 8 | data: 9 | conf.yml: |- 10 | node: 11 | ca: var/lib/baetyl/node/ca.pem 12 | key: var/lib/baetyl/node/client.key 13 | cert: var/lib/baetyl/node/client.pem 14 | sync: 15 | download: 16 | timeout: 30m 17 | httplink: 18 | address: "{{GetProperty "sync-server-address"}}" 19 | insecureSkipVerify: true 20 | logger: 21 | level: debug 22 | encoding: console -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-install.ps1: -------------------------------------------------------------------------------- 1 | $Addr="{{GetProperty "init-server-address"}}" 2 | $DeployYaml="{{.InitApplyYaml}}" 3 | $DbPath='{{.DBPath}}' 4 | $Token="{{.Token}}" 5 | $Mode='{{.Mode}}' 6 | 7 | function Check-User { 8 | $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) 9 | if (!$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { 10 | Write-Warning "baetyl installation should using administration principal" 11 | Break Script 12 | } 13 | } 14 | 15 | function Remove-DbFile { 16 | $CoreDbFile = Join-Path $DbPath 'store\core.db' 17 | $InitDbFile = Join-Path $DbPath 'init\store\core.db' 18 | if (Test-Path $InitDbFile) { 19 | Remove-Item $InitDbFile 20 | } 21 | if (Test-Path $CoreDbFile) { 22 | Remove-Item $CoreDbFile 23 | } 24 | } 25 | 26 | function Install-Baetyl { 27 | Remove-DbFile 28 | if ($Mode -eq "native") { 29 | Write-Host "baetyl install in native mode" 30 | if (Get-Command baetyl -ErrorAction SilentlyContinue) { 31 | baetyl delete 32 | baetyl apply -f "$Addr/v1/init/$($DeployYaml)?token=$Token" --skip-verify=true 33 | } else { 34 | Write-Warning "baetyl not installed yet, please install baetyl firstly" 35 | Break Script 36 | } 37 | } 38 | } 39 | 40 | Check-User 41 | Install-Baetyl 42 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ADDR="{{GetProperty "init-server-address"}}" 4 | DEPLOYYML="{{.InitApplyYaml}}" 5 | DB_PATH='{{.DBPath}}' 6 | TOKEN="{{.Token}}" 7 | MODE='{{.Mode}}' 8 | SUDO=sudo 9 | 10 | exec_cmd_nobail() { 11 | echo "+ $2 bash -c \"$1\"" 12 | $2 bash -c "$1" 13 | } 14 | 15 | print_status() { 16 | echo "## $1" 17 | } 18 | 19 | dbfile_clean() { 20 | INIT_DBFILE=$DB_PATH/store/core.db 21 | CORE_DBFILE=$DB_PATH/init/store/core.db 22 | if [ -f $INIT_DBFILE ]; then 23 | exec_cmd_nobail "rm -rf $INIT_DBFILE" $SUDO 24 | print_status "init db file deleted" 25 | fi 26 | if [ -f $CORE_DBFILE ]; then 27 | exec_cmd_nobail "rm -rf $CORE_DBFILE" $SUDO 28 | print_status "core db file deleted" 29 | fi 30 | } 31 | 32 | kube_clean() { 33 | exec_cmd_nobail "kubectl delete clusterrolebinding baetyl-edge-system-rbac --ignore-not-found=true" $SUDO 34 | exec_cmd_nobail "kubectl delete ns baetyl-edge-system --ignore-not-found=true" $SUDO 35 | } 36 | 37 | download_tool=curl 38 | check_download_tool() { 39 | if [ -x "$(command -v wget)" ]; then 40 | download_tool=wget 41 | fi 42 | } 43 | 44 | kube_apply() { 45 | TempFile=$(mktemp temp.XXXXXX) 46 | if [ "$download_tool" = "wget" ]; then 47 | exec_cmd_nobail "wget --no-check-certificate -O $TempFile \"$1\"" $SUDO 48 | else 49 | exec_cmd_nobail "curl -skfL \"$1\" >$TempFile" $SUDO 50 | fi 51 | exec_cmd_nobail "kubectl apply -f $TempFile" $SUDO 52 | exec_cmd_nobail "rm -f $TempFile 2>/dev/null" $SUDO 53 | } 54 | 55 | install_baetyl() { 56 | dbfile_clean 57 | if [ $MODE = "kube" ]; then 58 | print_status "baetyl install in k8s mode" 59 | kube_clean 60 | kube_apply "$ADDR/v1/init/$DEPLOYYML?token=$TOKEN" 61 | elif [ $MODE = "native" ]; then 62 | print_status "baetyl install in native mode" 63 | exec_cmd_nobail "baetyl delete" $SUDO 64 | exec_cmd_nobail "baetyl apply -f '$ADDR/v1/init/$DEPLOYYML?token=$TOKEN' --skip-verify=true" $SUDO 65 | else 66 | print_status "Not supported install mode $MODE" 67 | exit 0 68 | fi 69 | } 70 | 71 | install_baetyl 72 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-nodejs10-program.yml: -------------------------------------------------------------------------------- 1 | name: "{{.ConfigName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-config-type: "baetyl-program" 7 | data: 8 | _object_baetyl-nodejs10_darwin-amd64.zip: |- 9 | {"url":"{{GetModuleProgram "nodejs10" "darwin-amd64"}}","unpack":"zip"} 10 | _object_baetyl-nodejs10_linux-amd64.zip: |- 11 | {"url":"{{GetModuleProgram "nodejs10" "linux-amd64"}}","unpack":"zip"} 12 | _object_baetyl-nodejs10_linux-arm64-v8.zip: |- 13 | {"url":"{{GetModuleProgram "nodejs10" "linux-arm64-v8"}}","unpack":"zip"} 14 | _object_baetyl-nodejs10_linux-arm-v7.zip: |- 15 | {"url":"{{GetModuleProgram "nodejs10" "linux-arm-v7"}}","unpack":"zip"} -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-python3-opencv-program.yml: -------------------------------------------------------------------------------- 1 | name: "{{.ConfigName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-config-type: "baetyl-program" 7 | data: 8 | _object_baetyl-python3-opencv_darwin-amd64.zip: |- 9 | {"url":"{{GetModuleProgram "python3-opencv" "darwin-amd64"}}","unpack":"zip"} 10 | _object_baetyl-python3-opencv_linux-amd64.zip: |- 11 | {"url":"{{GetModuleProgram "python3-opencv" "linux-amd64"}}","unpack":"zip"} 12 | _object_baetyl-python3-opencv_linux-arm64-v8.zip: |- 13 | {"url":"{{GetModuleProgram "python3-opencv" "linux-arm64-v8"}}","unpack":"zip"} 14 | _object_baetyl-python3-opencv_linux-arm-v7.zip: |- 15 | {"url":"{{GetModuleProgram "python3-opencv" "linux-arm-v7"}}","unpack":"zip"} -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-python3-program.yml: -------------------------------------------------------------------------------- 1 | name: "{{.ConfigName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-config-type: "baetyl-program" 7 | data: 8 | _object_baetyl-python3_darwin-amd64.zip: |- 9 | {"url":"{{GetModuleProgram "python3" "darwin-amd64"}}","unpack":"zip"} 10 | _object_baetyl-python3_linux-amd64.zip: |- 11 | {"url":"{{GetModuleProgram "python3" "linux-amd64"}}","unpack":"zip"} 12 | _object_baetyl-python3_linux-arm64-v8.zip: |- 13 | {"url":"{{GetModuleProgram "python3" "linux-arm64-v8"}}","unpack":"zip"} 14 | _object_baetyl-python3_linux-arm-v7.zip: |- 15 | {"url":"{{GetModuleProgram "python3" "linux-arm-v7"}}","unpack":"zip"} -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-rule-app.yml: -------------------------------------------------------------------------------- 1 | name: "{{.RuleAppName}}" 2 | namespace: "{{.Namespace}}" 3 | selector: "baetyl-node-name={{.NodeName}}" 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-app-mode: "{{.AppMode}}" 7 | type: "container" 8 | mode: "{{.NodeMode}}" 9 | system: true 10 | replica: 1 11 | services: 12 | - name: "baetyl-rule" 13 | type: "deployment" 14 | image: {{GetModuleImage "baetyl-rule"}} 15 | replica: 1 16 | volumeMounts: 17 | - name: "rule-conf" 18 | mountPath: "/etc/baetyl" 19 | readOnly: true 20 | volumes: 21 | - name: "rule-conf" 22 | config: 23 | name: "{{.RuleConfName}}" 24 | version: "{{.RuleConfVersion}}" 25 | -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-rule-conf.yml: -------------------------------------------------------------------------------- 1 | name: "{{.RuleConfName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-app-name: "{{.RuleAppName}}" 6 | baetyl-node-name: "{{.NodeName}}" 7 | baetyl-cloud-system: "true" 8 | data: 9 | conf.yml: |- 10 | logger: 11 | level: debug 12 | encoding: console -------------------------------------------------------------------------------- /scripts/native/templates/baetyl-sql-program.yml: -------------------------------------------------------------------------------- 1 | name: "{{.ConfigName}}" 2 | namespace: "{{.Namespace}}" 3 | system: true 4 | labels: 5 | baetyl-cloud-system: "true" 6 | baetyl-config-type: "baetyl-program" 7 | data: 8 | _object_baetyl-sql_darwin-amd64.zip: |- 9 | {"url":"{{GetModuleProgram "sql" "darwin-amd64"}}","unpack":"zip"} 10 | _object_baetyl-sql_linux-amd64.zip: |- 11 | {"url":"{{GetModuleProgram "sql" "linux-amd64"}}","unpack":"zip"} 12 | _object_baetyl-sql_linux-arm64-v8.zip: |- 13 | {"url":"{{GetModuleProgram "sql" "linux-arm64-v8"}}","unpack":"zip"} 14 | _object_baetyl-sql_linux-arm-v7.zip: |- 15 | {"url":"{{GetModuleProgram "sql" "linux-arm-v7"}}","unpack":"zip"} -------------------------------------------------------------------------------- /server/sync_server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/log" 5 | specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 6 | 7 | "github.com/baetyl/baetyl-cloud/v2/api" 8 | "github.com/baetyl/baetyl-cloud/v2/config" 9 | "github.com/baetyl/baetyl-cloud/v2/plugin" 10 | ) 11 | 12 | type HandlerMessage func(msg specV1.Message) (*specV1.Message, error) 13 | 14 | type SyncServer struct { 15 | links map[string]plugin.SyncLink 16 | syncAPI api.SyncAPI 17 | } 18 | 19 | func NewSyncServer(cfg *config.CloudConfig) (*SyncServer, error) { 20 | sync := &SyncServer{ 21 | links: map[string]plugin.SyncLink{}, 22 | } 23 | for _, l := range cfg.Plugin.SyncLinks { 24 | link, err := plugin.GetPlugin(l) 25 | if err != nil { 26 | return nil, err 27 | } 28 | sync.links[l] = link.(plugin.SyncLink) 29 | } 30 | return sync, nil 31 | } 32 | 33 | func (s *SyncServer) SetSyncAPI(a api.SyncAPI) { 34 | s.syncAPI = a 35 | } 36 | 37 | func (s *SyncServer) InitMsgRouter() { 38 | for _, v := range s.links { 39 | v.AddMsgRouter(string(specV1.MessageReport), HandlerMessage(s.syncAPI.Report)) 40 | v.AddMsgRouter(string(specV1.MessageDesire), HandlerMessage(s.syncAPI.Desire)) 41 | } 42 | } 43 | 44 | func (s *SyncServer) AddMsgRouter(router string, handler HandlerMessage) { 45 | for _, v := range s.links { 46 | v.AddMsgRouter(router, handler) 47 | } 48 | } 49 | 50 | func (s *SyncServer) Run() { 51 | for k, v := range s.links { 52 | go v.Start() 53 | log.L().Info("sync server starting", log.Any("name", k)) 54 | } 55 | } 56 | 57 | func (s *SyncServer) Close() { 58 | for _, v := range s.links { 59 | v.Close() 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /service/auth.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/config" 5 | "github.com/baetyl/baetyl-cloud/v2/plugin" 6 | ) 7 | 8 | //go:generate mockgen -destination=../mock/service/auth.go -package=service github.com/baetyl/baetyl-cloud/v2/service AuthService 9 | 10 | type AuthService interface { 11 | plugin.Auth 12 | } 13 | 14 | type authService struct { 15 | plugin.Auth 16 | } 17 | 18 | func NewAuthService(config *config.CloudConfig) (AuthService, error) { 19 | auth, err := plugin.GetPlugin(config.Plugin.Auth) 20 | if err != nil { 21 | return nil, err 22 | } 23 | return &authService{auth.(plugin.Auth)}, nil 24 | } 25 | -------------------------------------------------------------------------------- /service/auth_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/baetyl/baetyl-cloud/v2/common" 9 | _ "github.com/baetyl/baetyl-cloud/v2/plugin/default/auth" 10 | ) 11 | 12 | func TestAuthService_Authenticate(t *testing.T) { 13 | mockObject := InitMockEnvironment(t) 14 | defer mockObject.Close() 15 | c := &common.Context{} 16 | mockObject.auth.EXPECT().Authenticate(c).Return(nil).Times(1) 17 | 18 | as, err := NewAuthService(mockObject.conf) 19 | assert.Nil(t, err) 20 | err = as.Authenticate(c) 21 | assert.Nil(t, err) 22 | } 23 | -------------------------------------------------------------------------------- /service/cache.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "io/ioutil" 5 | "time" 6 | 7 | "github.com/baetyl/baetyl-go/v2/errors" 8 | "github.com/gin-contrib/cache/persistence" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/config" 11 | ) 12 | 13 | //go:generate mockgen -destination=../mock/service/cache.go -package=service github.com/baetyl/baetyl-cloud/v2/service CacheService 14 | 15 | type CacheService interface { 16 | Get(key string, load func(string) (string, error)) (string, error) 17 | GetProperty(key string) (string, error) 18 | GetFileData(file string) (string, error) 19 | } 20 | 21 | type CacheServiceImpl struct { 22 | expireDuration time.Duration 23 | cache persistence.CacheStore 24 | 25 | prop PropertyService // default backend 26 | } 27 | 28 | func NewCacheService(cfg *config.CloudConfig) (CacheService, error) { 29 | propertyService, err := NewPropertyService(cfg) 30 | if err != nil { 31 | return nil, errors.Trace(err) 32 | } 33 | return &CacheServiceImpl{ 34 | expireDuration: cfg.Cache.ExpirationDuration, 35 | cache: persistence.NewInMemoryStore(cfg.Cache.ExpirationDuration), 36 | prop: propertyService, 37 | }, nil 38 | } 39 | 40 | func (s *CacheServiceImpl) Get(key string, load func(string) (string, error)) (string, error) { 41 | var value string 42 | if err := s.cache.Get(key, &value); err == nil { 43 | return value, nil 44 | } 45 | value, err := load(key) 46 | if err != nil { 47 | return "", errors.Trace(err) 48 | } 49 | return value, nil 50 | } 51 | 52 | func (s *CacheServiceImpl) GetProperty(key string) (string, error) { 53 | return s.Get(key, s.prop.GetPropertyValue) 54 | } 55 | 56 | func (s *CacheServiceImpl) GetFileData(file string) (string, error) { 57 | return s.Get(file, func(key string) (string, error) { 58 | data, err := ioutil.ReadFile(key) 59 | if err != nil { 60 | return "", errors.Trace(err) 61 | } 62 | return string(data), nil 63 | }) 64 | } 65 | -------------------------------------------------------------------------------- /service/cache_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/baetyl/baetyl-cloud/v2/common" 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | func TestCacheService(t *testing.T) { 13 | mockObject := InitMockEnvironment(t) 14 | defer mockObject.Close() 15 | 16 | // good case 17 | mConf := &models.Property{ 18 | Name: "baetyl_0.1.0", 19 | Value: "http://test.baetyl/0.1.0", 20 | } 21 | mockObject.property.EXPECT().GetPropertyValue(mConf.Name).Return(mConf.Value, nil).AnyTimes() 22 | 23 | cache, err := NewCacheService(mockObject.conf) 24 | assert.NoError(t, err) 25 | res, err := cache.Get(mConf.Name, mockObject.property.GetPropertyValue) 26 | assert.NoError(t, err) 27 | assert.Equal(t, res, mConf.Value) 28 | 29 | // bad case 30 | name := "bad name" 31 | mockObject.property.EXPECT().GetPropertyValue(name).Return("", common.Error( 32 | common.ErrResourceNotFound, 33 | common.Field("name", name))) 34 | assert.NoError(t, err) 35 | res, err = cache.Get(name, mockObject.property.GetPropertyValue) 36 | assert.Error(t, err) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /service/cron.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/errors" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/config" 7 | "github.com/baetyl/baetyl-cloud/v2/models" 8 | "github.com/baetyl/baetyl-cloud/v2/plugin" 9 | ) 10 | 11 | //go:generate mockgen -destination=../mock/service/cron.go -package=service github.com/baetyl/baetyl-cloud/v2/service CronService 12 | 13 | type CronService interface { 14 | GetCron(name, namespace string) (*models.Cron, error) 15 | CreateCron(*models.Cron) error 16 | UpdateCron(*models.Cron) error 17 | DeleteCron(name, namespace string) error 18 | ListExpiredApps() ([]models.Cron, error) 19 | DeleteExpiredApps([]uint64) error 20 | } 21 | 22 | type cronService struct { 23 | plugin.Cron 24 | } 25 | 26 | func NewCronService(config *config.CloudConfig) (CronService, error) { 27 | cron, err := plugin.GetPlugin(config.Plugin.Cron) 28 | if err != nil { 29 | return nil, errors.Trace(err) 30 | } 31 | 32 | return &cronService{ 33 | cron.(plugin.Cron), 34 | }, nil 35 | } 36 | -------------------------------------------------------------------------------- /service/cron_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/golang/mock/gomock" 8 | "github.com/stretchr/testify/assert" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/common" 11 | "github.com/baetyl/baetyl-cloud/v2/config" 12 | mockPlugin "github.com/baetyl/baetyl-cloud/v2/mock/plugin" 13 | "github.com/baetyl/baetyl-cloud/v2/models" 14 | "github.com/baetyl/baetyl-cloud/v2/plugin" 15 | ) 16 | 17 | func mockCron(mock plugin.Cron) plugin.Factory { 18 | factory := func() (plugin.Plugin, error) { 19 | return mock, nil 20 | } 21 | return factory 22 | } 23 | 24 | func TestCronService(t *testing.T) { 25 | conf := &config.CloudConfig{} 26 | conf.Plugin.Cron = common.RandString(9) 27 | mockCtl := gomock.NewController(t) 28 | defer mockCtl.Finish() 29 | 30 | mCron := mockPlugin.NewMockCron(mockCtl) 31 | plugin.RegisterFactory(conf.Plugin.Cron, mockCron(mCron)) 32 | 33 | cs, err := NewCronService(conf) 34 | assert.NoError(t, err) 35 | 36 | n, ns := "baetyl", "cloud" 37 | cronEntity := &models.Cron{ 38 | Name: n, 39 | Namespace: ns, 40 | Selector: "baetyl-node-name=node1", 41 | CronTime: time.Now(), 42 | } 43 | 44 | mCron.EXPECT().GetCron(n, ns).Return(cronEntity, nil) 45 | _, err = cs.GetCron(n, ns) 46 | assert.NoError(t, err) 47 | 48 | mCron.EXPECT().CreateCron(cronEntity).Return(nil) 49 | err = cs.CreateCron(cronEntity) 50 | assert.NoError(t, err) 51 | 52 | mCron.EXPECT().UpdateCron(cronEntity).Return(nil) 53 | err = cs.UpdateCron(cronEntity) 54 | assert.NoError(t, err) 55 | 56 | mCron.EXPECT().DeleteCron(n, ns).Return(nil) 57 | err = cs.DeleteCron(n, ns) 58 | assert.NoError(t, err) 59 | 60 | mCron.EXPECT().ListExpiredApps().Return(nil, nil) 61 | _, err = cs.ListExpiredApps() 62 | assert.NoError(t, err) 63 | 64 | mCron.EXPECT().DeleteExpiredApps(nil).Return(nil) 65 | err = cs.DeleteExpiredApps(nil) 66 | assert.NoError(t, err) 67 | } 68 | -------------------------------------------------------------------------------- /service/license.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/config" 5 | "github.com/baetyl/baetyl-cloud/v2/plugin" 6 | ) 7 | 8 | //go:generate mockgen -destination=../mock/service/license.go -package=service github.com/baetyl/baetyl-cloud/v2/service LicenseService 9 | type LicenseService interface { 10 | plugin.License 11 | } 12 | 13 | type LicenseServiceImpl struct { 14 | plugin.License 15 | } 16 | 17 | func NewLicenseService(config *config.CloudConfig) (LicenseService, error) { 18 | l, err := plugin.GetPlugin(config.Plugin.License) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | return &LicenseServiceImpl{ 24 | l.(plugin.License), 25 | }, nil 26 | } 27 | -------------------------------------------------------------------------------- /service/license_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestLicenseService_CheckLicense(t *testing.T) { 10 | services := InitMockEnvironment(t) 11 | ls, err := NewLicenseService(services.conf) 12 | assert.NoError(t, err) 13 | 14 | services.license.EXPECT().CheckLicense().Return(nil) 15 | err = ls.CheckLicense() 16 | assert.NoError(t, err) 17 | } 18 | -------------------------------------------------------------------------------- /service/locker.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/config" 7 | "github.com/baetyl/baetyl-cloud/v2/plugin" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/service/locker.go -package=service github.com/baetyl/baetyl-cloud/v2/service LockerService 11 | 12 | type LockerService interface { 13 | Lock(ctx context.Context, name string, ttl int64) (string, error) 14 | Unlock(ctx context.Context, name, value string) 15 | } 16 | 17 | // NewModuleService 18 | func NewLockerService(config *config.CloudConfig) (LockerService, error) { 19 | locker, err := plugin.GetPlugin(config.Plugin.Locker) 20 | if err != nil { 21 | return nil, err 22 | } 23 | return locker.(plugin.Locker), nil 24 | } 25 | -------------------------------------------------------------------------------- /service/module.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/common" 5 | "github.com/baetyl/baetyl-cloud/v2/config" 6 | "github.com/baetyl/baetyl-cloud/v2/models" 7 | "github.com/baetyl/baetyl-cloud/v2/plugin" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/service/module.go -package=service github.com/baetyl/baetyl-cloud/v2/service ModuleService 11 | 12 | type ModuleService interface { 13 | GetModules(name string) ([]models.Module, error) 14 | GetModuleByVersion(name, version string) (*models.Module, error) 15 | GetModuleByImage(name, image string) (*models.Module, error) 16 | GetLatestModule(name string) (*models.Module, error) 17 | CreateModule(module *models.Module) (*models.Module, error) 18 | UpdateModuleByVersion(module *models.Module) (*models.Module, error) 19 | DeleteModules(name string) error 20 | DeleteModuleByVersion(name, version string) error 21 | ListModules(filter *models.Filter, tp common.ModuleType) ([]models.Module, error) 22 | 23 | GetLatestModuleImage(name string) (string, error) 24 | GetLatestModuleProgram(name, platform string) (string, error) 25 | } 26 | 27 | // NewModuleService 28 | func NewModuleService(config *config.CloudConfig) (ModuleService, error) { 29 | ds, err := plugin.GetPlugin(config.Plugin.Module) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return ds.(plugin.Module), nil 34 | } 35 | -------------------------------------------------------------------------------- /service/property.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/config" 5 | "github.com/baetyl/baetyl-cloud/v2/models" 6 | "github.com/baetyl/baetyl-cloud/v2/plugin" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/service/property.go -package=service github.com/baetyl/baetyl-cloud/v2/service PropertyService 10 | 11 | type PropertyService interface { 12 | GetProperty(name string) (*models.Property, error) 13 | CreateProperty(property *models.Property) error 14 | DeleteProperty(name string) error 15 | ListProperty(page *models.Filter) ([]models.Property, error) //Pagination 16 | CountProperty(name string) (int, error) 17 | UpdateProperty(property *models.Property) error 18 | 19 | GetPropertyValue(name string) (string, error) 20 | } 21 | 22 | type propertyService struct { 23 | property plugin.Property 24 | } 25 | 26 | // NewPropertyService 27 | func NewPropertyService(config *config.CloudConfig) (PropertyService, error) { 28 | ds, err := plugin.GetPlugin(config.Plugin.Property) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | p := &propertyService{ 34 | property: ds.(plugin.Property), 35 | } 36 | 37 | return p, nil 38 | } 39 | 40 | func (p *propertyService) GetProperty(name string) (*models.Property, error) { 41 | return p.property.GetProperty(name) 42 | } 43 | 44 | func (p *propertyService) CreateProperty(property *models.Property) error { 45 | return p.property.CreateProperty(property) 46 | } 47 | 48 | func (p *propertyService) DeleteProperty(name string) error { 49 | return p.property.DeleteProperty(name) 50 | } 51 | 52 | func (p *propertyService) ListProperty(page *models.Filter) ([]models.Property, error) { 53 | return p.property.ListProperty(page) 54 | } 55 | 56 | func (p *propertyService) CountProperty(name string) (int, error) { 57 | return p.property.CountProperty(name) 58 | } 59 | 60 | func (p *propertyService) UpdateProperty(property *models.Property) error { 61 | return p.property.UpdateProperty(property) 62 | } 63 | 64 | func (p *propertyService) GetPropertyValue(name string) (string, error) { 65 | return p.property.GetPropertyValue(name) 66 | } 67 | -------------------------------------------------------------------------------- /service/property_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/golang/mock/gomock" 7 | "github.com/stretchr/testify/assert" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/models" 10 | ) 11 | 12 | func TestPropertyService_GetProperty(t *testing.T) { 13 | mock := gomock.NewController(t) 14 | defer mock.Finish() 15 | 16 | mockObject := InitMockEnvironment(t) 17 | defer mockObject.Close() 18 | 19 | property := mockObject.property 20 | is := propertyService{} 21 | is.property = mockObject.property 22 | 23 | name := "a" 24 | m := &models.Property{ 25 | Name: "a", 26 | Value: "a-value", 27 | } 28 | property.EXPECT().GetProperty(name).Return(m, nil).Times(1) 29 | res, err := is.GetProperty(name) 30 | assert.NoError(t, err) 31 | assert.Equal(t, res.Name, m.Name) 32 | assert.Equal(t, res.Value, m.Value) 33 | } 34 | -------------------------------------------------------------------------------- /service/quota.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/common" 5 | "github.com/baetyl/baetyl-cloud/v2/config" 6 | "github.com/baetyl/baetyl-cloud/v2/plugin" 7 | ) 8 | 9 | //go:generate mockgen -destination=../mock/service/quota.go -package=service github.com/baetyl/baetyl-cloud/v2/service QuotaService 10 | type QuotaService interface { 11 | plugin.Quota 12 | CheckQuota(namespace string, collector plugin.QuotaCollector) error 13 | } 14 | 15 | type QuotaServiceImpl struct { 16 | plugin.Quota 17 | } 18 | 19 | func NewQuotaService(config *config.CloudConfig) (QuotaService, error) { 20 | l, err := plugin.GetPlugin(config.Plugin.Quota) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | return &QuotaServiceImpl{ 26 | l.(plugin.Quota), 27 | }, nil 28 | } 29 | 30 | func (l *QuotaServiceImpl) CheckQuota(namespace string, collector plugin.QuotaCollector) error { 31 | limits, err := l.GetQuota(namespace) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | counts, err := collector(namespace) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | if counts == nil || limits == nil { 42 | return nil 43 | } 44 | 45 | for k, v := range counts { 46 | if limits[k] != 0 && v >= limits[k] { 47 | return common.Error( 48 | common.ErrLicenseQuota, 49 | common.Field("name", k), 50 | common.Field("limit", limits[k])) 51 | } 52 | } 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /service/quota_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | 9 | "github.com/baetyl/baetyl-cloud/v2/plugin" 10 | ) 11 | 12 | func TestLicenseService_CheckQuota(t *testing.T) { 13 | namespace := "default" 14 | services := InitMockEnvironment(t) 15 | ls, err := NewQuotaService(services.conf) 16 | assert.NoError(t, err) 17 | quotas := map[string]int{ 18 | plugin.QuotaNode: 10, 19 | } 20 | 21 | services.quota.EXPECT().GetQuota(namespace).Return(quotas, nil) 22 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 23 | return map[string]int{plugin.QuotaNode: 1}, nil 24 | }) 25 | assert.NoError(t, err) 26 | 27 | services.quota.EXPECT().GetQuota(namespace).Return(nil, nil) 28 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 29 | return map[string]int{plugin.QuotaNode: 1}, nil 30 | }) 31 | assert.NoError(t, err) 32 | 33 | services.quota.EXPECT().GetQuota(namespace).Return(quotas, nil) 34 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 35 | return nil, nil 36 | }) 37 | assert.NoError(t, err) 38 | 39 | errGetQuota := fmt.Errorf("get quota error") 40 | services.quota.EXPECT().GetQuota(namespace).Return(nil, errGetQuota) 41 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 42 | return map[string]int{plugin.QuotaNode: 1}, nil 43 | }) 44 | assert.Equal(t, err, errGetQuota) 45 | 46 | errGetNodeCount := fmt.Errorf("get node count error") 47 | services.quota.EXPECT().GetQuota(namespace).Return(quotas, nil) 48 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 49 | return nil, errGetNodeCount 50 | }) 51 | assert.Equal(t, err, errGetNodeCount) 52 | 53 | services.quota.EXPECT().GetQuota(namespace).Return(quotas, nil) 54 | err = ls.CheckQuota(namespace, func(namespace string) (map[string]int, error) { 55 | return map[string]int{plugin.QuotaNode: 11}, nil 56 | }) 57 | assert.Error(t, err) 58 | } 59 | -------------------------------------------------------------------------------- /service/resource.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-cloud/v2/config" 5 | ) 6 | 7 | // AppCombinedService is a combined service contains application, configuration and secret services. 8 | type AppCombinedService struct { 9 | App ApplicationService 10 | Config ConfigService 11 | Secret SecretService 12 | } 13 | 14 | func NewAppCombinedService(cfg *config.CloudConfig) (*AppCombinedService, error) { 15 | configService, err := NewConfigService(cfg) 16 | if err != nil { 17 | return nil, err 18 | } 19 | secretService, err := NewSecretService(cfg) 20 | if err != nil { 21 | return nil, err 22 | } 23 | appService, err := NewApplicationService(cfg) 24 | if err != nil { 25 | return nil, err 26 | } 27 | return &AppCombinedService{ 28 | App: appService, 29 | Config: configService, 30 | Secret: secretService, 31 | }, nil 32 | } 33 | -------------------------------------------------------------------------------- /service/sign.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "crypto/sha256" 5 | "encoding/hex" 6 | "fmt" 7 | 8 | "github.com/baetyl/baetyl-go/v2/json" 9 | 10 | "github.com/baetyl/baetyl-cloud/v2/config" 11 | "github.com/baetyl/baetyl-cloud/v2/plugin" 12 | ) 13 | 14 | //go:generate mockgen -destination=../mock/service/sign.go -package=service github.com/baetyl/baetyl-cloud/v2/service SignService 15 | 16 | type SignService interface { 17 | plugin.Sign 18 | GenToken(map[string]interface{}) (string, error) 19 | } 20 | 21 | type signService struct { 22 | plugin.Sign 23 | } 24 | 25 | func NewSignService(config *config.CloudConfig) (SignService, error) { 26 | s, err := plugin.GetPlugin(config.Plugin.Sign) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return &signService{s.(plugin.Sign)}, nil 31 | } 32 | 33 | func (s *signService) GenToken(data map[string]interface{}) (string, error) { 34 | signData, err := json.Marshal(data) 35 | if err != nil { 36 | return "", err 37 | } 38 | dataStr := hex.EncodeToString(signData) 39 | sign, err := s.Signature(signData) 40 | if err != nil { 41 | return "", err 42 | } 43 | hashed := sha256.Sum256(sign) 44 | signStr := hex.EncodeToString(hashed[:]) 45 | return fmt.Sprintf("%s%s", signStr[:10], dataStr), nil 46 | } 47 | -------------------------------------------------------------------------------- /service/task.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/baetyl/baetyl-go/v2/task" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/config" 7 | "github.com/baetyl/baetyl-cloud/v2/plugin" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/service/task.go -package=service github.com/baetyl/baetyl-cloud/v2/service TaskService 11 | 12 | type TaskService interface { 13 | task.TaskProducer 14 | task.TaskWorker 15 | } 16 | 17 | // NewTaskService NewTaskService 18 | func NewTaskService(config *config.CloudConfig) (TaskService, error) { 19 | taskService, err := plugin.GetPlugin(config.Plugin.Task) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | return taskService.(plugin.Task), nil 25 | } 26 | -------------------------------------------------------------------------------- /service/task_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestTaskService(t *testing.T) { 10 | mockObject := InitMockEnvironment(t) 11 | defer mockObject.Close() 12 | 13 | _, err := NewTaskService(mockObject.conf) 14 | assert.NoError(t, err) 15 | } 16 | -------------------------------------------------------------------------------- /service/wrapper.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 5 | 6 | "github.com/baetyl/baetyl-cloud/v2/config" 7 | "github.com/baetyl/baetyl-cloud/v2/plugin" 8 | ) 9 | 10 | //go:generate mockgen -destination=../mock/service/wrapper.go -package=service github.com/baetyl/baetyl-cloud/v2/service WrapperService 11 | 12 | type CreateNodeFunc func(tx interface{}, namespace string, node *specV1.Node) (*specV1.Node, error) 13 | 14 | type WrapperService interface { 15 | CreateNodeTx(CreateNodeFunc) CreateNodeFunc 16 | } 17 | 18 | type WrapperServiceImpl struct { 19 | plugin.TransactionFactory 20 | } 21 | 22 | func NewWrapperService(config *config.CloudConfig) (WrapperService, error) { 23 | tx, err := plugin.GetPlugin(config.Plugin.Tx) 24 | if err != nil { 25 | return nil, err 26 | } 27 | return &WrapperServiceImpl{ 28 | tx.(plugin.TransactionFactory), 29 | }, nil 30 | } 31 | 32 | func (w *WrapperServiceImpl) Close(tx interface{}) { 33 | if p := recover(); p != nil { 34 | w.Rollback(tx) 35 | panic(p) 36 | } 37 | } 38 | 39 | func (w *WrapperServiceImpl) FinishTx(err error, tx interface{}) { 40 | if err != nil { 41 | w.Rollback(tx) 42 | } else { 43 | w.Commit(tx) 44 | } 45 | } 46 | 47 | func (w *WrapperServiceImpl) CreateNodeTx(function CreateNodeFunc) CreateNodeFunc { 48 | return func(tx interface{}, namespace string, node *specV1.Node) (*specV1.Node, error) { 49 | transaction, err := w.BeginTx() 50 | if err != nil { 51 | return nil, err 52 | } 53 | defer w.Close(transaction) 54 | result, err := function(transaction, namespace, node) 55 | w.FinishTx(err, transaction) 56 | return result, err 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /service/wrapper_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/baetyl/baetyl-go/v2/errors" 7 | specV1 "github.com/baetyl/baetyl-go/v2/spec/v1" 8 | "github.com/golang/mock/gomock" 9 | "github.com/stretchr/testify/assert" 10 | 11 | "github.com/baetyl/baetyl-cloud/v2/common" 12 | "github.com/baetyl/baetyl-cloud/v2/config" 13 | mockPlugin "github.com/baetyl/baetyl-cloud/v2/mock/plugin" 14 | "github.com/baetyl/baetyl-cloud/v2/plugin" 15 | ) 16 | 17 | func mockTx(mock plugin.TransactionFactory) plugin.Factory { 18 | factory := func() (plugin.Plugin, error) { 19 | return mock, nil 20 | } 21 | return factory 22 | } 23 | 24 | func mockCreateNodeY(tx interface{}, namespace string, node *specV1.Node) (*specV1.Node, error) { 25 | return nil, nil 26 | } 27 | 28 | func mockCreateNodeN(tx interface{}, namespace string, node *specV1.Node) (*specV1.Node, error) { 29 | return nil, errors.New("error") 30 | } 31 | 32 | func TestCreateWrapper(t *testing.T) { 33 | cfg := &config.CloudConfig{} 34 | cfg.Plugin.Tx = common.RandString(9) 35 | mockCtl := gomock.NewController(t) 36 | 37 | mTx := mockPlugin.NewMockTransactionFactory(mockCtl) 38 | _, err := NewWrapperService(cfg) 39 | assert.Error(t, err) 40 | 41 | plugin.RegisterFactory(cfg.Plugin.Tx, mockTx(mTx)) 42 | wrapper, err := NewWrapperService(cfg) 43 | assert.NoError(t, err) 44 | 45 | mTx.EXPECT().BeginTx().Return(nil, errors.New("error")) 46 | _, err = wrapper.CreateNodeTx(mockCreateNodeY)(nil, "", nil) 47 | assert.Error(t, err) 48 | 49 | mTx.EXPECT().BeginTx().Return(nil, nil) 50 | mTx.EXPECT().Rollback(nil).Return() 51 | _, err = wrapper.CreateNodeTx(mockCreateNodeN)(nil, "", nil) 52 | assert.Error(t, err) 53 | 54 | mTx.EXPECT().BeginTx().Return(nil, nil) 55 | mTx.EXPECT().Commit(nil).Return() 56 | _, err = wrapper.CreateNodeTx(mockCreateNodeY)(nil, "", nil) 57 | assert.NoError(t, err) 58 | } 59 | --------------------------------------------------------------------------------