From 823011173161af719b06ed7b86eb6efb9ce49a5c Mon Sep 17 00:00:00 2001 From: yy Date: Thu, 12 Oct 2023 17:47:15 +0800 Subject: [PATCH 1/5] refactor license --- .github/workflows/controllers.yml | 4 +- .../{licenseissuer => license}/.dockerignore | 2 +- .../{licenseissuer => license}/.gitignore | 4 +- controllers/license/Dockerfile | 33 ++ .../{licenseissuer => license}/Makefile | 19 +- controllers/license/PROJECT | 20 + .../{licenseissuer => license}/README.md | 17 +- .../api/v1/groupversion_info.go | 6 +- .../api/v1/license_types.go | 21 +- .../api/v1/zz_generated.deepcopy.go | 89 --- controllers/license/cmd/launcher/main.go | 5 + .../cmd => license/cmd/manager}/main.go | 75 +-- controllers/license/cmd/preset/main.go | 5 + .../bases/license.sealos.io_licenses.yaml} | 21 +- .../config/crd/kustomization.yaml | 11 +- .../config/crd/kustomizeconfig.yaml | 0 .../crd/patches/cainjection_in_licenses.yaml | 2 +- .../crd/patches/webhook_in_licenses.yaml | 2 +- .../config/default/kustomization.yaml | 6 +- .../default/manager_auth_proxy_patch.yaml | 18 +- .../config/default/manager_config_patch.yaml | 0 .../license/config/manager/kustomization.yaml | 2 + .../config/manager/manager.yaml | 43 +- .../config/prometheus/kustomization.yaml | 0 .../config/prometheus/monitor.yaml | 4 +- .../rbac/auth_proxy_client_clusterrole.yaml | 4 +- .../config/rbac/auth_proxy_role.yaml | 4 +- .../config/rbac/auth_proxy_role_binding.yaml | 4 +- .../config/rbac/auth_proxy_service.yaml | 4 +- .../config/rbac/kustomization.yaml | 0 .../config/rbac/leader_election_role.yaml | 4 +- .../rbac/leader_election_role_binding.yaml | 4 +- .../config/rbac/license_editor_role.yaml | 8 +- .../config/rbac/license_viewer_role.yaml | 8 +- controllers/license/config/rbac/role.yaml | 32 + .../config/rbac/role_binding.yaml | 4 +- .../config/rbac/service_account.yaml | 4 +- .../config/samples/kustomization.yaml | 3 +- .../config/samples/license_v1_license.yaml} | 6 +- controllers/{licenseissuer => license}/go.mod | 62 +- controllers/{licenseissuer => license}/go.sum | 112 ++-- .../hack/boilerplate.go.txt | 0 .../internal/controller/license_controller.go | 83 +++ .../internal/controller/suite_test.go | 6 +- .../internal/controller/util/license.go | 3 + controllers/licenseissuer/.env | 5 - controllers/licenseissuer/Dockerfile | 11 - controllers/licenseissuer/PROJECT | 53 -- .../licenseissuer/api/v1/cloudclient_types.go | 61 -- .../config/certmanager/certificate.yaml | 39 -- .../config/certmanager/kustomization.yaml | 5 - .../config/certmanager/kustomizeconfig.yaml | 8 - .../bases/infostream.sealos.io_launchers.yaml | 56 -- .../patches/cainjection_in_cloudclients.yaml | 7 - .../crd/patches/webhook_in_cloudclients.yaml | 16 - .../config/default/manager_webhook_patch.yaml | 23 - .../default/webhookcainjection_patch.yaml | 15 - .../config/manager/kustomization.yaml | 8 - .../config/rbac/cloudclient_editor_role.yaml | 31 - .../config/rbac/cloudclient_viewer_role.yaml | 27 - .../licenseissuer/config/rbac/role.yaml | 113 ---- .../config/samples/cloud_v1_cloudclient.yaml | 12 - .../config/webhook/kustomization.yaml | 6 - .../config/webhook/kustomizeconfig.yaml | 14 - .../config/webhook/manifests.yaml | 27 - .../licenseissuer/config/webhook/service.yaml | 20 - controllers/licenseissuer/deploy/Kubefile | 24 - .../deploy/manifests/configmaps.yaml | 32 - .../deploy/manifests/customconfig.yaml.tmpl | 34 -- .../deploy/manifests/deploy.yaml | 551 ------------------ .../licenseissuer/deploy/manifests/setup.sh | 17 - .../internal/controller/license_controller.go | 198 ------- .../internal/controller/util/collect.go | 262 --------- .../internal/controller/util/const.go | 87 --- .../internal/controller/util/datasync.go | 98 ---- .../internal/controller/util/external.go | 160 ----- .../internal/controller/util/init.go | 140 ----- .../internal/controller/util/license.go | 372 ------------ .../internal/controller/util/notice.go | 266 --------- .../internal/controller/util/options.go | 226 ------- .../internal/controller/util/prob.go | 172 ------ .../internal/controller/util/reader.go | 47 -- .../internal/controller/util/runnable.go | 223 ------- .../internal/controller/util/util.go | 60 -- controllers/licenseissuer/launcher/main.go | 51 -- controllers/licenseissuer/preset/main.go | 180 ------ go.work | 2 +- 87 files changed, 370 insertions(+), 4153 deletions(-) rename controllers/{licenseissuer => license}/.dockerignore (92%) rename controllers/{licenseissuer => license}/.gitignore (96%) create mode 100644 controllers/license/Dockerfile rename controllers/{licenseissuer => license}/Makefile (93%) create mode 100644 controllers/license/PROJECT rename controllers/{licenseissuer => license}/README.md (79%) rename controllers/{licenseissuer => license}/api/v1/groupversion_info.go (83%) rename controllers/{licenseissuer => license}/api/v1/license_types.go (78%) rename controllers/{licenseissuer => license}/api/v1/zz_generated.deepcopy.go (56%) create mode 100644 controllers/license/cmd/launcher/main.go rename controllers/{licenseissuer/cmd => license/cmd/manager}/main.go (60%) create mode 100644 controllers/license/cmd/preset/main.go rename controllers/{licenseissuer/config/crd/bases/infostream.sealos.io_licenses.yaml => license/config/crd/bases/license.sealos.io_licenses.yaml} (85%) rename controllers/{licenseissuer => license}/config/crd/kustomization.yaml (74%) rename controllers/{licenseissuer => license}/config/crd/kustomizeconfig.yaml (100%) rename controllers/{licenseissuer => license}/config/crd/patches/cainjection_in_licenses.yaml (87%) rename controllers/{licenseissuer => license}/config/crd/patches/webhook_in_licenses.yaml (91%) rename controllers/{licenseissuer => license}/config/default/kustomization.yaml (98%) rename controllers/{licenseissuer => license}/config/default/manager_auth_proxy_patch.yaml (65%) rename controllers/{licenseissuer => license}/config/default/manager_config_patch.yaml (100%) create mode 100644 controllers/license/config/manager/kustomization.yaml rename controllers/{licenseissuer => license}/config/manager/manager.yaml (73%) rename controllers/{licenseissuer => license}/config/prometheus/kustomization.yaml (100%) rename controllers/{licenseissuer => license}/config/prometheus/monitor.yaml (85%) rename controllers/{licenseissuer => license}/config/rbac/auth_proxy_client_clusterrole.yaml (74%) rename controllers/{licenseissuer => license}/config/rbac/auth_proxy_role.yaml (80%) rename controllers/{licenseissuer => license}/config/rbac/auth_proxy_role_binding.yaml (80%) rename controllers/{licenseissuer => license}/config/rbac/auth_proxy_service.yaml (80%) rename controllers/{licenseissuer => license}/config/rbac/kustomization.yaml (100%) rename controllers/{licenseissuer => license}/config/rbac/leader_election_role.yaml (85%) rename controllers/{licenseissuer => license}/config/rbac/leader_election_role_binding.yaml (80%) rename controllers/{licenseissuer => license}/config/rbac/license_editor_role.yaml (76%) rename controllers/{licenseissuer => license}/config/rbac/license_viewer_role.yaml (75%) create mode 100644 controllers/license/config/rbac/role.yaml rename controllers/{licenseissuer => license}/config/rbac/role_binding.yaml (80%) rename controllers/{licenseissuer => license}/config/rbac/service_account.yaml (71%) rename controllers/{licenseissuer => license}/config/samples/kustomization.yaml (66%) rename controllers/{licenseissuer/config/samples/cloud_v1_license.yaml => license/config/samples/license_v1_license.yaml} (60%) rename controllers/{licenseissuer => license}/go.mod (65%) rename controllers/{licenseissuer => license}/go.sum (83%) rename controllers/{licenseissuer => license}/hack/boilerplate.go.txt (100%) create mode 100644 controllers/license/internal/controller/license_controller.go rename controllers/{licenseissuer => license}/internal/controller/suite_test.go (92%) create mode 100644 controllers/license/internal/controller/util/license.go delete mode 100644 controllers/licenseissuer/.env delete mode 100644 controllers/licenseissuer/Dockerfile delete mode 100644 controllers/licenseissuer/PROJECT delete mode 100644 controllers/licenseissuer/api/v1/cloudclient_types.go delete mode 100644 controllers/licenseissuer/config/certmanager/certificate.yaml delete mode 100644 controllers/licenseissuer/config/certmanager/kustomization.yaml delete mode 100644 controllers/licenseissuer/config/certmanager/kustomizeconfig.yaml delete mode 100644 controllers/licenseissuer/config/crd/bases/infostream.sealos.io_launchers.yaml delete mode 100644 controllers/licenseissuer/config/crd/patches/cainjection_in_cloudclients.yaml delete mode 100644 controllers/licenseissuer/config/crd/patches/webhook_in_cloudclients.yaml delete mode 100644 controllers/licenseissuer/config/default/manager_webhook_patch.yaml delete mode 100644 controllers/licenseissuer/config/default/webhookcainjection_patch.yaml delete mode 100644 controllers/licenseissuer/config/manager/kustomization.yaml delete mode 100644 controllers/licenseissuer/config/rbac/cloudclient_editor_role.yaml delete mode 100644 controllers/licenseissuer/config/rbac/cloudclient_viewer_role.yaml delete mode 100644 controllers/licenseissuer/config/rbac/role.yaml delete mode 100644 controllers/licenseissuer/config/samples/cloud_v1_cloudclient.yaml delete mode 100644 controllers/licenseissuer/config/webhook/kustomization.yaml delete mode 100644 controllers/licenseissuer/config/webhook/kustomizeconfig.yaml delete mode 100644 controllers/licenseissuer/config/webhook/manifests.yaml delete mode 100644 controllers/licenseissuer/config/webhook/service.yaml delete mode 100644 controllers/licenseissuer/deploy/Kubefile delete mode 100644 controllers/licenseissuer/deploy/manifests/configmaps.yaml delete mode 100644 controllers/licenseissuer/deploy/manifests/customconfig.yaml.tmpl delete mode 100644 controllers/licenseissuer/deploy/manifests/deploy.yaml delete mode 100644 controllers/licenseissuer/deploy/manifests/setup.sh delete mode 100644 controllers/licenseissuer/internal/controller/license_controller.go delete mode 100644 controllers/licenseissuer/internal/controller/util/collect.go delete mode 100644 controllers/licenseissuer/internal/controller/util/const.go delete mode 100644 controllers/licenseissuer/internal/controller/util/datasync.go delete mode 100644 controllers/licenseissuer/internal/controller/util/external.go delete mode 100644 controllers/licenseissuer/internal/controller/util/init.go delete mode 100644 controllers/licenseissuer/internal/controller/util/license.go delete mode 100644 controllers/licenseissuer/internal/controller/util/notice.go delete mode 100644 controllers/licenseissuer/internal/controller/util/options.go delete mode 100644 controllers/licenseissuer/internal/controller/util/prob.go delete mode 100644 controllers/licenseissuer/internal/controller/util/reader.go delete mode 100644 controllers/licenseissuer/internal/controller/util/runnable.go delete mode 100644 controllers/licenseissuer/internal/controller/util/util.go delete mode 100644 controllers/licenseissuer/launcher/main.go delete mode 100644 controllers/licenseissuer/preset/main.go diff --git a/.github/workflows/controllers.yml b/.github/workflows/controllers.yml index 8fa7d23f3a7..f9519c6c2bd 100644 --- a/.github/workflows/controllers.yml +++ b/.github/workflows/controllers.yml @@ -84,7 +84,7 @@ jobs: - { name: db-adminer, path: db/adminer } - { name: resources, path: resources } - { name: resources-metering, path: resources/metering } - - { name: licenseissuer, path: licenseissuer } + - { name: license, path: license } - { name: node, path: node } - { name: admission, path: admission } steps: @@ -186,7 +186,7 @@ jobs: - { name: db-adminer, path: db/adminer } - { name: resources, path: resources } - { name: resources-metering, path: resources/metering } - - { name: licenseissuer, path: licenseissuer } + - { name: license, path: license } - { name: node, path: node } - { name: admission, path: admission } steps: diff --git a/controllers/licenseissuer/.dockerignore b/controllers/license/.dockerignore similarity index 92% rename from controllers/licenseissuer/.dockerignore rename to controllers/license/.dockerignore index 8e6fac709b6..a3aab7af70c 100644 --- a/controllers/licenseissuer/.dockerignore +++ b/controllers/license/.dockerignore @@ -1,3 +1,3 @@ # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file # Ignore build and test binaries. -testbin/ +bin/ diff --git a/controllers/licenseissuer/.gitignore b/controllers/license/.gitignore similarity index 96% rename from controllers/licenseissuer/.gitignore rename to controllers/license/.gitignore index e917e5cefe5..7f02333db7a 100644 --- a/controllers/licenseissuer/.gitignore +++ b/controllers/license/.gitignore @@ -5,8 +5,7 @@ *.dll *.so *.dylib -bin -testbin/* +bin/* Dockerfile.cross # Test binary, build with `go test -c` @@ -21,6 +20,7 @@ Dockerfile.cross # editor and IDE paraphernalia .idea +.vscode *.swp *.swo *~ diff --git a/controllers/license/Dockerfile b/controllers/license/Dockerfile new file mode 100644 index 00000000000..c389c0981af --- /dev/null +++ b/controllers/license/Dockerfile @@ -0,0 +1,33 @@ +# Build the manager binary +FROM golang:1.20 as builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY cmd/main.go cmd/main.go +COPY api/ api/ +COPY internal/controller/ internal/controller/ + +# Build +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/manager . +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/controllers/licenseissuer/Makefile b/controllers/license/Makefile similarity index 93% rename from controllers/licenseissuer/Makefile rename to controllers/license/Makefile index 733389e433d..618344a37bf 100644 --- a/controllers/licenseissuer/Makefile +++ b/controllers/license/Makefile @@ -1,12 +1,9 @@ # Image URL to use all building/pushing image targets -IMG ?= ghcr.io/labring/sealos-licenseissuer-controller:latest +IMG ?= ghcr.io/labring/sealos-license-controller:latest # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.26.1 -include .env -export - # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -64,21 +61,21 @@ test: manifests generate fmt vet envtest ## Run tests. ##@ Build -.PHONY: build +.PHONY: build CONTROLLER_PKG=github.com/labring/sealos/controllers/pkg -CONTROLLER_LICENSEISSUER=github.com/labring/sealos/controllers/licenseissuer/internal/controller +CONTROLLER_LICENSE=github.com/labring/sealos/controllers/license/internal/controller build: manifests generate fmt vet ## Build manager binary. LD_FLAGS=""; \ [ -n "$(CRYPTOKEY)" ] && LD_FLAGS+="-X ${CONTROLLER_PKG}/crypto.encryptionKey=${CRYPTOKEY} -X ${CONTROLLER_PKG}/database.cryptoKey=${CRYPTOKEY}"; \ - [ -n "$(LICENSE_KEY)" ] && LD_FLAGS+=" -X ${CONTROLLER_LICENSEISSUER}/util.Key=${LICENSE_KEY}"; \ - CGO_ENABLED=0 GOOS=linux go build -ldflags "$${LD_FLAGS}" -o bin/manager cmd/main.go && \ - CGO_ENABLED=0 GOOS=linux go build -o bin/preset-${GOARCH} preset/main.go && chmod +x bin/preset-${GOARCH} && \ - CGO_ENABLED=0 GOOS=linux go build -o bin/launcher-${GOARCH} launcher/main.go && chmod +x bin/launcher-${GOARCH} + [ -n "$(LICENSE_KEY)" ] && LD_FLAGS+=" -X ${CONTROLLER_LICENSE}/util.Key=${LICENSE_KEY}"; \ + CGO_ENABLED=0 GOOS=linux go build -ldflags "$${LD_FLAGS}" -o bin/manager cmd/manager/main.go && \ + CGO_ENABLED=0 GOOS=linux go build -o bin/preset-${GOARCH} cmd/preset/main.go && chmod +x bin/preset-${GOARCH} && \ + CGO_ENABLED=0 GOOS=linux go build -o bin/launcher-${GOARCH} cmd/launcher/main.go && chmod +x bin/launcher-${GOARCH} .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go + go run ./cmd/manager/main.go # If you wish built the manager image targeting other platforms you can use the --platform flag. # (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. diff --git a/controllers/license/PROJECT b/controllers/license/PROJECT new file mode 100644 index 00000000000..1d476dd9e48 --- /dev/null +++ b/controllers/license/PROJECT @@ -0,0 +1,20 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html +domain: sealos.io +layout: +- go.kubebuilder.io/v4 +projectName: license +repo: github.com/labring/sealos/controllers/license +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: sealos.io + group: license + kind: License + path: github.com/labring/sealos/controllers/license/api/v1 + version: v1 +version: "3" diff --git a/controllers/licenseissuer/README.md b/controllers/license/README.md similarity index 79% rename from controllers/licenseissuer/README.md rename to controllers/license/README.md index a01619f619b..9e81c63e9d2 100644 --- a/controllers/licenseissuer/README.md +++ b/controllers/license/README.md @@ -1,14 +1,5 @@ -# licenseissuer-controller - -LicenseIssuer is a Operator that authorizes the use of a license for a given user. - -In this module, there are three binaries in total, which are launcher, preset, and manager. - -Launcher is a starter responsible for launching preset and manager. - -Preset is an idempotent binary program responsible for registering the root user in the database, and the root user has a certain amount of free quota. - -Manager is used to create license resources and activate the license injected into the cluster. +# license +// TODO(user): Add simple overview of use/purpose ## Description // TODO(user): An in-depth paragraph about your project and overview of use @@ -27,13 +18,13 @@ kubectl apply -f config/samples/ 2. Build and push your image to the location specified by `IMG`: ```sh -make docker-build docker-push IMG=/licenseissuer-controller:tag +make docker-build docker-push IMG=/license:tag ``` 3. Deploy the controller to the cluster with the image specified by `IMG`: ```sh -make deploy IMG=/licenseissuer-controller:tag +make deploy IMG=/license:tag ``` ### Uninstall CRDs diff --git a/controllers/licenseissuer/api/v1/groupversion_info.go b/controllers/license/api/v1/groupversion_info.go similarity index 83% rename from controllers/licenseissuer/api/v1/groupversion_info.go rename to controllers/license/api/v1/groupversion_info.go index f110a94d101..0aa6231881d 100644 --- a/controllers/licenseissuer/api/v1/groupversion_info.go +++ b/controllers/license/api/v1/groupversion_info.go @@ -14,9 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v1 contains API Schema definitions for the infostream v1 API group +// Package v1 contains API Schema definitions for the license v1 API group // +kubebuilder:object:generate=true -// +groupName=infostream.sealos.io +// +groupName=license.sealos.io package v1 import ( @@ -26,7 +26,7 @@ import ( var ( // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "infostream.sealos.io", Version: "v1"} + GroupVersion = schema.GroupVersion{Group: "license.sealos.io", Version: "v1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} diff --git a/controllers/licenseissuer/api/v1/license_types.go b/controllers/license/api/v1/license_types.go similarity index 78% rename from controllers/licenseissuer/api/v1/license_types.go rename to controllers/license/api/v1/license_types.go index 8e0a462872a..40396fa1e97 100644 --- a/controllers/licenseissuer/api/v1/license_types.go +++ b/controllers/license/api/v1/license_types.go @@ -20,20 +20,31 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +type Type string + +const ( + AccountLicenseType Type = "Account" + ClusterLicenseType Type = "Cluster" +) // LicenseSpec defines the desired state of License type LicenseSpec struct { - UID string `json:"uid,omitempty"` + //+kubebuilder:validation:Enum=Account;Cluster + Type Type `json:"type,omitempty"` Token string `json:"token,omitempty"` Key string `json:"key,omitempty"` } +type LicenseStatusPhase string + +const ( + LicenseStatusPhasePending LicenseStatusPhase = "Pending" + LicenseStatusPhaseSuccess LicenseStatusPhase = "Active" +) + // LicenseStatus defines the observed state of License type LicenseStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + Phase LicenseStatusPhase `json:"phase,omitempty"` } //+kubebuilder:object:root=true diff --git a/controllers/licenseissuer/api/v1/zz_generated.deepcopy.go b/controllers/license/api/v1/zz_generated.deepcopy.go similarity index 56% rename from controllers/licenseissuer/api/v1/zz_generated.deepcopy.go rename to controllers/license/api/v1/zz_generated.deepcopy.go index 2ff8f3e68b9..19ba1650ce0 100644 --- a/controllers/licenseissuer/api/v1/zz_generated.deepcopy.go +++ b/controllers/license/api/v1/zz_generated.deepcopy.go @@ -25,95 +25,6 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Launcher) DeepCopyInto(out *Launcher) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Launcher. -func (in *Launcher) DeepCopy() *Launcher { - if in == nil { - return nil - } - out := new(Launcher) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Launcher) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LauncherList) DeepCopyInto(out *LauncherList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Launcher, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LauncherList. -func (in *LauncherList) DeepCopy() *LauncherList { - if in == nil { - return nil - } - out := new(LauncherList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LauncherList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LauncherSpec) DeepCopyInto(out *LauncherSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LauncherSpec. -func (in *LauncherSpec) DeepCopy() *LauncherSpec { - if in == nil { - return nil - } - out := new(LauncherSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LauncherStatus) DeepCopyInto(out *LauncherStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LauncherStatus. -func (in *LauncherStatus) DeepCopy() *LauncherStatus { - if in == nil { - return nil - } - out := new(LauncherStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *License) DeepCopyInto(out *License) { *out = *in diff --git a/controllers/license/cmd/launcher/main.go b/controllers/license/cmd/launcher/main.go new file mode 100644 index 00000000000..211be58eac4 --- /dev/null +++ b/controllers/license/cmd/launcher/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + // TODO do something +} diff --git a/controllers/licenseissuer/cmd/main.go b/controllers/license/cmd/manager/main.go similarity index 60% rename from controllers/licenseissuer/cmd/main.go rename to controllers/license/cmd/manager/main.go index a048c2fbe6d..c75ba6301ce 100644 --- a/controllers/licenseissuer/cmd/main.go +++ b/controllers/license/cmd/manager/main.go @@ -17,17 +17,13 @@ limitations under the License. package main import ( - "context" "flag" "os" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - accountv1 "github.com/labring/sealos/controllers/account/api/v1" - ntf "github.com/labring/sealos/controllers/pkg/notification/api/v1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -35,9 +31,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" - issuerv1 "github.com/labring/sealos/controllers/licenseissuer/api/v1" - "github.com/labring/sealos/controllers/licenseissuer/internal/controller" - "github.com/labring/sealos/controllers/licenseissuer/internal/controller/util" + licensev1 "github.com/labring/sealos/controllers/license/api/v1" + "github.com/labring/sealos/controllers/license/internal/controller" //+kubebuilder:scaffold:imports ) @@ -48,9 +43,8 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(ntf.AddToScheme(scheme)) - utilruntime.Must(issuerv1.AddToScheme(scheme)) - utilruntime.Must(accountv1.AddToScheme(scheme)) + + utilruntime.Must(licensev1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } @@ -58,6 +52,9 @@ func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string + + // TODO add more flags here + flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, @@ -68,6 +65,7 @@ func main() { } opts.BindFlags(flag.CommandLine) flag.Parse() + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ @@ -76,7 +74,7 @@ func main() { Port: 9443, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, - LeaderElectionID: "ec74c1eb.sealos.io", + LeaderElectionID: "90cbb0a1.sealos.io", // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily // when the Manager ends. This requires the binary to immediately end when the // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly @@ -94,63 +92,10 @@ func main() { os.Exit(1) } - // get options for this Operator - options := util.GetOptions() - mongoURI := options.GetEnvOptions().MongoURI - dbCol, err := util.NewLicenseDB(mongoURI) - if err != nil { - setupLog.Error(err, "unable to create database") - os.Exit(1) - } - defer func() { - _ = dbCol.Disconnect() - }() - - if err = (&controller.LicenseReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - DBCol: dbCol, - Recorder: util.GetHashMap(), - }).SetupWithManager(mgr); err != nil { + if err = (&controller.LicenseReconciler{}).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "License") os.Exit(1) } - - // server := util.NewLicenseServer("0.0.0.0", options.GetEnvOptions().ServerPort, util.NewLicenseClient(dbCol)) - // server.Run() - // defer server.Stop() - - // if err = (&controller.LauncherReconciler{ - // Client: mgr.GetClient(), - // Scheme: mgr.GetScheme(), - // }).SetupWithManager(mgr); err != nil { - // setupLog.Error(err, "unable to create controller", "controller", "Launcher") - // os.Exit(1) - // } - - // start the runnable tasks - tasks := util.BuildForRunnable(context.Background(), mgr.GetClient(), options) - for _, task := range tasks { - if err = mgr.Add(task); err != nil { - setupLog.Error(err, "unable to set up task pool") - os.Exit(1) - } - } - - // if err = (&controller.ScaleMonitorReconciler{ - // Client: mgr.GetClient(), - // Scheme: mgr.GetScheme(), - // }).SetupWithManager(mgr); err != nil { - // setupLog.Error(err, "unable to create controller", "controller", "ScaleMonitor") - // os.Exit(1) - // } - // if err = mgr.Add(&issuer.ClusterScaleMonitor{Client: mgr.GetClient()}); err != nil { - // setupLog.Error(err, "unable to set up monitor for cluster scale") - // os.Exit(1) - // } - - //mgr.GetWebhookServer().Register("/validate-cloud-sealos-io-v1-license", &webhook.Admission{Handler: &controller.ScaleWebhook{Client: mgr.GetClient()}}) - //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/controllers/license/cmd/preset/main.go b/controllers/license/cmd/preset/main.go new file mode 100644 index 00000000000..211be58eac4 --- /dev/null +++ b/controllers/license/cmd/preset/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + // TODO do something +} diff --git a/controllers/licenseissuer/config/crd/bases/infostream.sealos.io_licenses.yaml b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml similarity index 85% rename from controllers/licenseissuer/config/crd/bases/infostream.sealos.io_licenses.yaml rename to controllers/license/config/crd/bases/license.sealos.io_licenses.yaml index 8b0243e86ab..bdb336e8569 100644 --- a/controllers/licenseissuer/config/crd/bases/infostream.sealos.io_licenses.yaml +++ b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml @@ -3,11 +3,10 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null - name: licenses.infostream.sealos.io + controller-gen.kubebuilder.io/version: v0.12.0 + name: licenses.license.sealos.io spec: - group: infostream.sealos.io + group: license.sealos.io names: kind: License listKind: LicenseList @@ -39,20 +38,20 @@ spec: type: string token: type: string - uid: + type: + enum: + - Account + - Cluster type: string type: object status: description: LicenseStatus defines the observed state of License + properties: + phase: + type: string type: object type: object served: true storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/controllers/licenseissuer/config/crd/kustomization.yaml b/controllers/license/config/crd/kustomization.yaml similarity index 74% rename from controllers/licenseissuer/config/crd/kustomization.yaml rename to controllers/license/config/crd/kustomization.yaml index 16571b9f56c..64681839462 100644 --- a/controllers/licenseissuer/config/crd/kustomization.yaml +++ b/controllers/license/config/crd/kustomization.yaml @@ -2,21 +2,18 @@ # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default resources: -- bases/infostream.sealos.io_licenses.yaml -- bases/infostream.sealos.io_launchers.yaml +- bases/license.sealos.io_licenses.yaml #+kubebuilder:scaffold:crdkustomizeresource -patchesStrategicMerge: +patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_licenses.yaml -#- patches/webhook_in_launchers.yaml +#- path: patches/webhook_in_licenses.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_licenses.yaml -#- patches/cainjection_in_launchers.yaml +#- path: patches/cainjection_in_licenses.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/controllers/licenseissuer/config/crd/kustomizeconfig.yaml b/controllers/license/config/crd/kustomizeconfig.yaml similarity index 100% rename from controllers/licenseissuer/config/crd/kustomizeconfig.yaml rename to controllers/license/config/crd/kustomizeconfig.yaml diff --git a/controllers/licenseissuer/config/crd/patches/cainjection_in_licenses.yaml b/controllers/license/config/crd/patches/cainjection_in_licenses.yaml similarity index 87% rename from controllers/licenseissuer/config/crd/patches/cainjection_in_licenses.yaml rename to controllers/license/config/crd/patches/cainjection_in_licenses.yaml index 1482355d6fc..1c3c4334431 100644 --- a/controllers/licenseissuer/config/crd/patches/cainjection_in_licenses.yaml +++ b/controllers/license/config/crd/patches/cainjection_in_licenses.yaml @@ -4,4 +4,4 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME - name: licenses.cloud.sealos.io + name: licenses.license.sealos.io diff --git a/controllers/licenseissuer/config/crd/patches/webhook_in_licenses.yaml b/controllers/license/config/crd/patches/webhook_in_licenses.yaml similarity index 91% rename from controllers/licenseissuer/config/crd/patches/webhook_in_licenses.yaml rename to controllers/license/config/crd/patches/webhook_in_licenses.yaml index 0f11ec514c1..2ab51b4e50a 100644 --- a/controllers/licenseissuer/config/crd/patches/webhook_in_licenses.yaml +++ b/controllers/license/config/crd/patches/webhook_in_licenses.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: licenses.cloud.sealos.io + name: licenses.license.sealos.io spec: conversion: strategy: Webhook diff --git a/controllers/licenseissuer/config/default/kustomization.yaml b/controllers/license/config/default/kustomization.yaml similarity index 98% rename from controllers/licenseissuer/config/default/kustomization.yaml rename to controllers/license/config/default/kustomization.yaml index 1d0e527e38c..4b18094da29 100644 --- a/controllers/licenseissuer/config/default/kustomization.yaml +++ b/controllers/license/config/default/kustomization.yaml @@ -1,12 +1,12 @@ # Adds namespace to all resources. -namespace: sealos-system +namespace: license-system # Value of this field is prepended to the # names of all resources, e.g. a deployment named # "wordpress" becomes "alices-wordpress". # Note that it should also match with the prefix (text before '-') of the namespace # field above. -namePrefix: licenseissuer- +namePrefix: license- # Labels to add to all resources and selectors. #labels: @@ -45,7 +45,7 @@ patchesStrategicMerge: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. # Uncomment the following replacements to add the cert-manager CA injection annotations -# replacements: +#replacements: # - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs # kind: Certificate # group: cert-manager.io diff --git a/controllers/licenseissuer/config/default/manager_auth_proxy_patch.yaml b/controllers/license/config/default/manager_auth_proxy_patch.yaml similarity index 65% rename from controllers/licenseissuer/config/default/manager_auth_proxy_patch.yaml rename to controllers/license/config/default/manager_auth_proxy_patch.yaml index b7512661674..73fad2a6754 100644 --- a/controllers/licenseissuer/config/default/manager_auth_proxy_patch.yaml +++ b/controllers/license/config/default/manager_auth_proxy_patch.yaml @@ -8,22 +8,6 @@ metadata: spec: template: spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux containers: - name: kube-rbac-proxy securityContext: @@ -31,7 +15,7 @@ spec: capabilities: drop: - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1 args: - "--secure-listen-address=0.0.0.0:8443" - "--upstream=http://127.0.0.1:8080/" diff --git a/controllers/licenseissuer/config/default/manager_config_patch.yaml b/controllers/license/config/default/manager_config_patch.yaml similarity index 100% rename from controllers/licenseissuer/config/default/manager_config_patch.yaml rename to controllers/license/config/default/manager_config_patch.yaml diff --git a/controllers/license/config/manager/kustomization.yaml b/controllers/license/config/manager/kustomization.yaml new file mode 100644 index 00000000000..5c5f0b84cba --- /dev/null +++ b/controllers/license/config/manager/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- manager.yaml diff --git a/controllers/licenseissuer/config/manager/manager.yaml b/controllers/license/config/manager/manager.yaml similarity index 73% rename from controllers/licenseissuer/config/manager/manager.yaml rename to controllers/license/config/manager/manager.yaml index e006b8d8018..b3292af80f1 100644 --- a/controllers/licenseissuer/config/manager/manager.yaml +++ b/controllers/license/config/manager/manager.yaml @@ -6,8 +6,8 @@ metadata: app.kubernetes.io/name: namespace app.kubernetes.io/instance: system app.kubernetes.io/component: manager - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: system --- @@ -21,8 +21,8 @@ metadata: app.kubernetes.io/name: deployment app.kubernetes.io/instance: controller-manager app.kubernetes.io/component: manager - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize spec: selector: @@ -67,38 +67,11 @@ spec: # type: RuntimeDefault containers: - command: - - /launcher + - /manager args: - --leader-elect - image: ghcr.io/labring/sealos-licenseissuer-controller:latest - imagePullPolicy: Always + image: controller:latest name: manager - env: - - name: MONGO_URI - valueFrom: - secretKeyRef: - key: MongoURI - name: licenseissuer-env - - name: PASSWORD_SALT - valueFrom: - secretKeyRef: - key: PasswordSalt - name: licenseissuer-env - - name: MONGO_USER_DB - valueFrom: - secretKeyRef: - key: MongoUserDB - name: licenseissuer-env - - name: MONGO_USER_COL - valueFrom: - secretKeyRef: - key: MongoUserCollection - name: licenseissuer-env - - name: NAMESPACE - valueFrom: - secretKeyRef: - key: Namespace - name: licenseissuer-env securityContext: allowPrivilegeEscalation: false capabilities: @@ -121,9 +94,9 @@ spec: resources: limits: cpu: 500m - memory: 1024Mi + memory: 128Mi requests: cpu: 10m - memory: 512Mi + memory: 64Mi serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/controllers/licenseissuer/config/prometheus/kustomization.yaml b/controllers/license/config/prometheus/kustomization.yaml similarity index 100% rename from controllers/licenseissuer/config/prometheus/kustomization.yaml rename to controllers/license/config/prometheus/kustomization.yaml diff --git a/controllers/licenseissuer/config/prometheus/monitor.yaml b/controllers/license/config/prometheus/monitor.yaml similarity index 85% rename from controllers/licenseissuer/config/prometheus/monitor.yaml rename to controllers/license/config/prometheus/monitor.yaml index 955438e5966..a638a2a358f 100644 --- a/controllers/licenseissuer/config/prometheus/monitor.yaml +++ b/controllers/license/config/prometheus/monitor.yaml @@ -8,8 +8,8 @@ metadata: app.kubernetes.io/name: servicemonitor app.kubernetes.io/instance: controller-manager-metrics-monitor app.kubernetes.io/component: metrics - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-monitor namespace: system diff --git a/controllers/licenseissuer/config/rbac/auth_proxy_client_clusterrole.yaml b/controllers/license/config/rbac/auth_proxy_client_clusterrole.yaml similarity index 74% rename from controllers/licenseissuer/config/rbac/auth_proxy_client_clusterrole.yaml rename to controllers/license/config/rbac/auth_proxy_client_clusterrole.yaml index 60981c802d7..61806ffc81e 100644 --- a/controllers/licenseissuer/config/rbac/auth_proxy_client_clusterrole.yaml +++ b/controllers/license/config/rbac/auth_proxy_client_clusterrole.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: clusterrole app.kubernetes.io/instance: metrics-reader app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: metrics-reader rules: diff --git a/controllers/licenseissuer/config/rbac/auth_proxy_role.yaml b/controllers/license/config/rbac/auth_proxy_role.yaml similarity index 80% rename from controllers/licenseissuer/config/rbac/auth_proxy_role.yaml rename to controllers/license/config/rbac/auth_proxy_role.yaml index 62f4adda440..132b5783dd5 100644 --- a/controllers/licenseissuer/config/rbac/auth_proxy_role.yaml +++ b/controllers/license/config/rbac/auth_proxy_role.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: clusterrole app.kubernetes.io/instance: proxy-role app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: proxy-role rules: diff --git a/controllers/licenseissuer/config/rbac/auth_proxy_role_binding.yaml b/controllers/license/config/rbac/auth_proxy_role_binding.yaml similarity index 80% rename from controllers/licenseissuer/config/rbac/auth_proxy_role_binding.yaml rename to controllers/license/config/rbac/auth_proxy_role_binding.yaml index a394d20f4b0..99be6d545fb 100644 --- a/controllers/licenseissuer/config/rbac/auth_proxy_role_binding.yaml +++ b/controllers/license/config/rbac/auth_proxy_role_binding.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: clusterrolebinding app.kubernetes.io/instance: proxy-rolebinding app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: proxy-rolebinding roleRef: diff --git a/controllers/licenseissuer/config/rbac/auth_proxy_service.yaml b/controllers/license/config/rbac/auth_proxy_service.yaml similarity index 80% rename from controllers/licenseissuer/config/rbac/auth_proxy_service.yaml rename to controllers/license/config/rbac/auth_proxy_service.yaml index 187bdf0760d..bb105642907 100644 --- a/controllers/licenseissuer/config/rbac/auth_proxy_service.yaml +++ b/controllers/license/config/rbac/auth_proxy_service.yaml @@ -6,8 +6,8 @@ metadata: app.kubernetes.io/name: service app.kubernetes.io/instance: controller-manager-metrics-service app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-service namespace: system diff --git a/controllers/licenseissuer/config/rbac/kustomization.yaml b/controllers/license/config/rbac/kustomization.yaml similarity index 100% rename from controllers/licenseissuer/config/rbac/kustomization.yaml rename to controllers/license/config/rbac/kustomization.yaml diff --git a/controllers/licenseissuer/config/rbac/leader_election_role.yaml b/controllers/license/config/rbac/leader_election_role.yaml similarity index 85% rename from controllers/licenseissuer/config/rbac/leader_election_role.yaml rename to controllers/license/config/rbac/leader_election_role.yaml index bd8f037158a..fdeee9f91e1 100644 --- a/controllers/licenseissuer/config/rbac/leader_election_role.yaml +++ b/controllers/license/config/rbac/leader_election_role.yaml @@ -6,8 +6,8 @@ metadata: app.kubernetes.io/name: role app.kubernetes.io/instance: leader-election-role app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: leader-election-role rules: diff --git a/controllers/licenseissuer/config/rbac/leader_election_role_binding.yaml b/controllers/license/config/rbac/leader_election_role_binding.yaml similarity index 80% rename from controllers/licenseissuer/config/rbac/leader_election_role_binding.yaml rename to controllers/license/config/rbac/leader_election_role_binding.yaml index aa6fd620f98..02689d9b655 100644 --- a/controllers/licenseissuer/config/rbac/leader_election_role_binding.yaml +++ b/controllers/license/config/rbac/leader_election_role_binding.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: rolebinding app.kubernetes.io/instance: leader-election-rolebinding app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: leader-election-rolebinding roleRef: diff --git a/controllers/licenseissuer/config/rbac/license_editor_role.yaml b/controllers/license/config/rbac/license_editor_role.yaml similarity index 76% rename from controllers/licenseissuer/config/rbac/license_editor_role.yaml rename to controllers/license/config/rbac/license_editor_role.yaml index e7c7c4a3922..af1cbd10191 100644 --- a/controllers/licenseissuer/config/rbac/license_editor_role.yaml +++ b/controllers/license/config/rbac/license_editor_role.yaml @@ -6,13 +6,13 @@ metadata: app.kubernetes.io/name: clusterrole app.kubernetes.io/instance: license-editor-role app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: license-editor-role rules: - apiGroups: - - cloud.sealos.io + - license.sealos.io resources: - licenses verbs: @@ -24,7 +24,7 @@ rules: - update - watch - apiGroups: - - cloud.sealos.io + - license.sealos.io resources: - licenses/status verbs: diff --git a/controllers/licenseissuer/config/rbac/license_viewer_role.yaml b/controllers/license/config/rbac/license_viewer_role.yaml similarity index 75% rename from controllers/licenseissuer/config/rbac/license_viewer_role.yaml rename to controllers/license/config/rbac/license_viewer_role.yaml index 1e59bf77b2f..9b5d0be7157 100644 --- a/controllers/licenseissuer/config/rbac/license_viewer_role.yaml +++ b/controllers/license/config/rbac/license_viewer_role.yaml @@ -6,13 +6,13 @@ metadata: app.kubernetes.io/name: clusterrole app.kubernetes.io/instance: license-viewer-role app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: license-viewer-role rules: - apiGroups: - - cloud.sealos.io + - license.sealos.io resources: - licenses verbs: @@ -20,7 +20,7 @@ rules: - list - watch - apiGroups: - - cloud.sealos.io + - license.sealos.io resources: - licenses/status verbs: diff --git a/controllers/license/config/rbac/role.yaml b/controllers/license/config/rbac/role.yaml new file mode 100644 index 00000000000..43b234b4508 --- /dev/null +++ b/controllers/license/config/rbac/role.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: manager-role +rules: +- apiGroups: + - license.sealos.io + resources: + - licenses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - license.sealos.io + resources: + - licenses/finalizers + verbs: + - update +- apiGroups: + - license.sealos.io + resources: + - licenses/status + verbs: + - get + - patch + - update diff --git a/controllers/licenseissuer/config/rbac/role_binding.yaml b/controllers/license/config/rbac/role_binding.yaml similarity index 80% rename from controllers/licenseissuer/config/rbac/role_binding.yaml rename to controllers/license/config/rbac/role_binding.yaml index e6a530ebc9a..c1e41b4d4cc 100644 --- a/controllers/licenseissuer/config/rbac/role_binding.yaml +++ b/controllers/license/config/rbac/role_binding.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: clusterrolebinding app.kubernetes.io/instance: manager-rolebinding app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: manager-rolebinding roleRef: diff --git a/controllers/licenseissuer/config/rbac/service_account.yaml b/controllers/license/config/rbac/service_account.yaml similarity index 71% rename from controllers/licenseissuer/config/rbac/service_account.yaml rename to controllers/license/config/rbac/service_account.yaml index 8df3efc0ed4..6e2109017b9 100644 --- a/controllers/licenseissuer/config/rbac/service_account.yaml +++ b/controllers/license/config/rbac/service_account.yaml @@ -5,8 +5,8 @@ metadata: app.kubernetes.io/name: serviceaccount app.kubernetes.io/instance: controller-manager-sa app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/created-by: license + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize name: controller-manager namespace: system diff --git a/controllers/licenseissuer/config/samples/kustomization.yaml b/controllers/license/config/samples/kustomization.yaml similarity index 66% rename from controllers/licenseissuer/config/samples/kustomization.yaml rename to controllers/license/config/samples/kustomization.yaml index 2e840a75a17..9ac5719d45f 100644 --- a/controllers/licenseissuer/config/samples/kustomization.yaml +++ b/controllers/license/config/samples/kustomization.yaml @@ -1,5 +1,4 @@ ## Append samples of your project ## resources: -- cloud_v1_license.yaml -- cloud_v1_launcher.yaml +- license_v1_license.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/controllers/licenseissuer/config/samples/cloud_v1_license.yaml b/controllers/license/config/samples/license_v1_license.yaml similarity index 60% rename from controllers/licenseissuer/config/samples/cloud_v1_license.yaml rename to controllers/license/config/samples/license_v1_license.yaml index f0a6383b9d9..e2009a768f1 100644 --- a/controllers/licenseissuer/config/samples/cloud_v1_license.yaml +++ b/controllers/license/config/samples/license_v1_license.yaml @@ -1,12 +1,12 @@ -apiVersion: cloud.sealos.io/v1 +apiVersion: license.sealos.io/v1 kind: License metadata: labels: app.kubernetes.io/name: license app.kubernetes.io/instance: license-sample - app.kubernetes.io/part-of: licenseissuer-controller + app.kubernetes.io/part-of: license app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: licenseissuer-controller + app.kubernetes.io/created-by: license name: license-sample spec: # TODO(user): Add fields here diff --git a/controllers/licenseissuer/go.mod b/controllers/license/go.mod similarity index 65% rename from controllers/licenseissuer/go.mod rename to controllers/license/go.mod index 6970441d706..600c15ab755 100644 --- a/controllers/licenseissuer/go.mod +++ b/controllers/license/go.mod @@ -1,85 +1,89 @@ -module github.com/labring/sealos/controllers/licenseissuer +module github.com/labring/sealos/controllers/license go 1.20 +replace ( + k8s.io/api => k8s.io/api v0.25.6 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.25.6 + k8s.io/apimachinery => k8s.io/apimachinery v0.25.6 + k8s.io/client-go => k8s.io/client-go v0.25.6 + k8s.io/component-base => k8s.io/component-base v0.25.6 +) + require ( - github.com/go-logr/logr v1.2.4 - github.com/golang-jwt/jwt/v4 v4.5.0 - github.com/google/uuid v1.3.0 - github.com/labring/sealos/controllers/account v0.0.0 - github.com/labring/sealos/controllers/pkg v0.0.0-00010101000000-000000000000 github.com/onsi/ginkgo/v2 v2.10.0 github.com/onsi/gomega v1.27.8 - go.mongodb.org/mongo-driver v1.12.1 - k8s.io/api v0.27.4 k8s.io/apimachinery v0.27.4 k8s.io/client-go v0.27.4 sigs.k8s.io/controller-runtime v0.13.0 ) require ( - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.28 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-task/slim-sprig v2.20.0+incompatible // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect - github.com/huandu/xstrings v1.4.0 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/labring/sealos/controllers/user v0.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matoous/go-nanoid/v2 v2.0.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.15.1 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.2 // indirect - github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + github.com/stretchr/testify v1.8.4 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/goleak v1.2.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.9.0 // indirect golang.org/x/text v0.10.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.9.3 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.27.4 // indirect k8s.io/apiextensions-apiserver v0.27.2 // indirect k8s.io/component-base v0.27.2 // indirect k8s.io/klog/v2 v2.100.1 // indirect @@ -90,8 +94,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace ( - github.com/labring/sealos/controllers/account => ../account/ - github.com/labring/sealos/controllers/pkg => ../pkg/ - github.com/labring/sealos/controllers/user => ../user/ -) +replace github.com/labring/sealos => ../../ diff --git a/controllers/licenseissuer/go.sum b/controllers/license/go.sum similarity index 83% rename from controllers/licenseissuer/go.sum rename to controllers/license/go.sum index 8a0759a5583..73903c9d3e4 100644 --- a/controllers/licenseissuer/go.sum +++ b/controllers/license/go.sum @@ -1,12 +1,29 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= +github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk= +github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -24,7 +41,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -33,7 +49,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= @@ -51,10 +68,12 @@ github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTr github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v2.20.0+incompatible h1:4Xh3bDzO29j4TWNOI+24ubc0vbVFMg2PMnXKxK54/CA= -github.com/go-task/slim-sprig v2.20.0+incompatible/go.mod h1:N/mhXZITr/EQAOErEHciKvO1bFei2Lld2Ym6h96pdy0= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -77,9 +96,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -87,7 +103,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -100,8 +115,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -111,9 +124,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -124,9 +134,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U= -github.com/matoous/go-nanoid/v2 v2.0.0 h1:d19kur2QuLeHmJBkvYkFdhFBzLoo1XVm2GgTpL+9Tj0= -github.com/matoous/go-nanoid/v2 v2.0.0/go.mod h1:FtS4aGPVfEkxKxhdWPAspZpZSh1cOjtM7Ej/So3hR0g= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -134,8 +141,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -160,6 +165,7 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -175,38 +181,30 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= -go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -217,7 +215,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -234,7 +231,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -248,9 +244,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -261,13 +254,10 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -275,9 +265,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -291,7 +278,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -328,8 +314,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -337,8 +323,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -351,16 +335,16 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.27.4 h1:0pCo/AN9hONazBKlNUdhQymmnfLRbSZjd5H5H3f0bSs= -k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y= -k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= -k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= -k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs= -k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= -k8s.io/client-go v0.27.4 h1:vj2YTtSJ6J4KxaC88P4pMPEQECWMY8gqPqsTgUKzvjk= -k8s.io/client-go v0.27.4/go.mod h1:ragcly7lUlN0SRPk5/ZkGnDjPknzb37TICq07WhI6Xc= -k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= -k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= +k8s.io/api v0.25.6 h1:LwDY2H6kD/3R8TekJYYaJWOdekNdXDO44eVpX6sNtJA= +k8s.io/api v0.25.6/go.mod h1:bVp01KUcl8VUHFBTJMOknWNo7XvR0cMbeTTuFg1zCUs= +k8s.io/apiextensions-apiserver v0.25.6 h1:MwdaCpHtGVSM5SiA6Hm4g2w5voMNiPCwBjOqz9YTlrg= +k8s.io/apiextensions-apiserver v0.25.6/go.mod h1:aXw8Xmhf6/gfGx3y0xkj8o8evTZbfOFqZeWIigg4XsE= +k8s.io/apimachinery v0.25.6 h1:r6KIF2AHwLqFfZ0LcOA3I11SF62YZK83dxj1fn14NOQ= +k8s.io/apimachinery v0.25.6/go.mod h1:1S2i1QHkmxc8+EZCIxe/fX5hpldVXk4gvnJInMEb8D4= +k8s.io/client-go v0.25.6 h1:CHxACHi0DijmlYyUR7ooZoXnD5P8jYLgBHcxp775x/U= +k8s.io/client-go v0.25.6/go.mod h1:s9mMAGFYiH3Z66j7BESzu0GEradT9GQ2LjFf/YRrnyc= +k8s.io/component-base v0.25.6 h1:v3ci6FbXFcxpjyQJaaLq0MgzT3vyFzwUDWtO+KRv9Bk= +k8s.io/component-base v0.25.6/go.mod h1:k7DfcfJ8cOI6A2xTCfU5LxsnXV+lWw1ME8cRCHzIh6o= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= diff --git a/controllers/licenseissuer/hack/boilerplate.go.txt b/controllers/license/hack/boilerplate.go.txt similarity index 100% rename from controllers/licenseissuer/hack/boilerplate.go.txt rename to controllers/license/hack/boilerplate.go.txt diff --git a/controllers/license/internal/controller/license_controller.go b/controllers/license/internal/controller/license_controller.go new file mode 100644 index 00000000000..45a76b72358 --- /dev/null +++ b/controllers/license/internal/controller/license_controller.go @@ -0,0 +1,83 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "errors" + "github.com/go-logr/logr" + + ctrlsdk "github.com/labring/operator-sdk/controller" + licensev1 "github.com/labring/sealos/controllers/license/api/v1" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// LicenseReconciler reconciles a License object +type LicenseReconciler struct { + client.Client + Scheme *runtime.Scheme + Logger logr.Logger + finalizer *ctrlsdk.Finalizer +} + +// +kubebuilder:rbac:groups=license.sealos.io,resources=licenses,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=license.sealos.io,resources=licenses/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=license.sealos.io,resources=licenses/finalizers,verbs=update + +// TODO add rbac rules + +func (r *LicenseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + r.Logger.V(1).Info("start reconcile for license") + license := &licensev1.License{} + if err := r.Get(ctx, req.NamespacedName, license); err != nil { + return ctrl.Result{}, client.IgnoreNotFound(err) + } + + if ok, err := r.finalizer.RemoveFinalizer(ctx, license, func(ctx context.Context, obj client.Object) error { + return nil + }); ok { + return ctrl.Result{}, err + } + + if ok, err := r.finalizer.AddFinalizer(ctx, license); ok { + if err != nil { + return ctrl.Result{}, err + } + return r.reconcile(ctx, license) + } + return ctrl.Result{}, errors.New("reconcile error from Finalizer") +} + +// TODO do real reconcile + +func (r *LicenseReconciler) reconcile(ctx context.Context, license *licensev1.License) (ctrl.Result, error) { + // TODO check license and do something + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *LicenseReconciler) SetupWithManager(mgr ctrl.Manager) error { + // TODO set controller by mgr + // TODO add predictor + // TODO set logger and finalizer + return ctrl.NewControllerManagedBy(mgr). + For(&licensev1.License{}). + Complete(r) +} diff --git a/controllers/licenseissuer/internal/controller/suite_test.go b/controllers/license/internal/controller/suite_test.go similarity index 92% rename from controllers/licenseissuer/internal/controller/suite_test.go rename to controllers/license/internal/controller/suite_test.go index 627aeb157b8..4a837aa79b5 100644 --- a/controllers/licenseissuer/internal/controller/suite_test.go +++ b/controllers/license/internal/controller/suite_test.go @@ -30,7 +30,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - licenseissuerv1 "github.com/labring/sealos/controllers/licenseissuer/api/v1" + licensev1 "github.com/labring/sealos/controllers/license/api/v1" //+kubebuilder:scaffold:imports ) @@ -41,7 +41,7 @@ var cfg *rest.Config var k8sClient client.Client var testEnv *envtest.Environment -func TestAPIs(t *testing.T) { +func TestControllers(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Controller Suite") @@ -62,7 +62,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = licenseissuerv1.AddToScheme(scheme.Scheme) + err = licensev1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme diff --git a/controllers/license/internal/controller/util/license.go b/controllers/license/internal/controller/util/license.go new file mode 100644 index 00000000000..6acc4337446 --- /dev/null +++ b/controllers/license/internal/controller/util/license.go @@ -0,0 +1,3 @@ +package util + +// TODO add check license func diff --git a/controllers/licenseissuer/.env b/controllers/licenseissuer/.env deleted file mode 100644 index b290686030f..00000000000 --- a/controllers/licenseissuer/.env +++ /dev/null @@ -1,5 +0,0 @@ -# set the environment variables when local testing -MONGO_URI= -PASSWORD_SALT= -NAMESPACE= - diff --git a/controllers/licenseissuer/Dockerfile b/controllers/licenseissuer/Dockerfile deleted file mode 100644 index 3d37776cb0b..00000000000 --- a/controllers/licenseissuer/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH - -WORKDIR / -USER 65532:65532 - -COPY bin/controller-licenseissuer-$TARGETARCH /manager -COPY bin/preset-$TARGETARCH /preset -COPY bin/launcher-$TARGETARCH /launcher - -ENTRYPOINT ["/launcher"] diff --git a/controllers/licenseissuer/PROJECT b/controllers/licenseissuer/PROJECT deleted file mode 100644 index 5d1f709aa96..00000000000 --- a/controllers/licenseissuer/PROJECT +++ /dev/null @@ -1,53 +0,0 @@ -# Code generated by tool. DO NOT EDIT. -# This file is used to track the info used to scaffold your project -# and allow the plugins properly work. -# More info: https://book.kubebuilder.io/reference/project-config.html -domain: sealos.io -layout: -- go.kubebuilder.io/v4 -projectName: licenseissuer-controller -repo: github.com/labring/sealos/controllers/licenseissuer -resources: -- controller: true - domain: sealos.io - group: infostream - kind: Notification - version: v1 -- controller: true - domain: sealos.io - group: infostream - kind: Collector - version: v1 -- controller: true - domain: sealos.io - group: infostream - kind: CloudSync - version: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: sealos.io - group: infostream - kind: License - path: github.com/labring/sealos/controllers/licenseissuer/api/v1 - version: v1 - webhooks: - defaulting: true - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: sealos.io - group: infostream - kind: Launcher - path: github.com/labring/sealos/controllers/licenseissuer/api/v1 - version: v1 -- controller: true - domain: sealos.io - group: infostream - kind: ScaleMonitor - version: v1 -version: "3" diff --git a/controllers/licenseissuer/api/v1/cloudclient_types.go b/controllers/licenseissuer/api/v1/cloudclient_types.go deleted file mode 100644 index a691c7676f4..00000000000 --- a/controllers/licenseissuer/api/v1/cloudclient_types.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// LauncherSpec defines the desired state of Launcher -type LauncherSpec struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` -} - -// LauncherStatus defines the observed state of Launcher -type LauncherStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// Launcher is the Schema for the launchers API -type Launcher struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec LauncherSpec `json:"spec,omitempty"` - Status LauncherStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// LauncherList contains a list of Launcher -type LauncherList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Launcher `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Launcher{}, &LauncherList{}) -} diff --git a/controllers/licenseissuer/config/certmanager/certificate.yaml b/controllers/licenseissuer/config/certmanager/certificate.yaml deleted file mode 100644 index 839201ea61c..00000000000 --- a/controllers/licenseissuer/config/certmanager/certificate.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: system -spec: - # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize - dnsNames: - - SERVICE_NAME.SERVICE_NAMESPACE.svc - - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/controllers/licenseissuer/config/certmanager/kustomization.yaml b/controllers/licenseissuer/config/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a595e..00000000000 --- a/controllers/licenseissuer/config/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/controllers/licenseissuer/config/certmanager/kustomizeconfig.yaml b/controllers/licenseissuer/config/certmanager/kustomizeconfig.yaml deleted file mode 100644 index cf6f89e8892..00000000000 --- a/controllers/licenseissuer/config/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name diff --git a/controllers/licenseissuer/config/crd/bases/infostream.sealos.io_launchers.yaml b/controllers/licenseissuer/config/crd/bases/infostream.sealos.io_launchers.yaml deleted file mode 100644 index 01838f08468..00000000000 --- a/controllers/licenseissuer/config/crd/bases/infostream.sealos.io_launchers.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null - name: launchers.infostream.sealos.io -spec: - group: infostream.sealos.io - names: - kind: Launcher - listKind: LauncherList - plural: launchers - singular: launcher - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Launcher is the Schema for the launchers API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: LauncherSpec defines the desired state of Launcher - properties: - description: - type: string - name: - type: string - type: object - status: - description: LauncherStatus defines the observed state of Launcher - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/controllers/licenseissuer/config/crd/patches/cainjection_in_cloudclients.yaml b/controllers/licenseissuer/config/crd/patches/cainjection_in_cloudclients.yaml deleted file mode 100644 index 45a71e5169d..00000000000 --- a/controllers/licenseissuer/config/crd/patches/cainjection_in_cloudclients.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME - name: launchers.cloud.sealos.io diff --git a/controllers/licenseissuer/config/crd/patches/webhook_in_cloudclients.yaml b/controllers/licenseissuer/config/crd/patches/webhook_in_cloudclients.yaml deleted file mode 100644 index e50803d3840..00000000000 --- a/controllers/licenseissuer/config/crd/patches/webhook_in_cloudclients.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: launchers.cloud.sealos.io -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/controllers/licenseissuer/config/default/manager_webhook_patch.yaml b/controllers/licenseissuer/config/default/manager_webhook_patch.yaml deleted file mode 100644 index 738de350b71..00000000000 --- a/controllers/licenseissuer/config/default/manager_webhook_patch.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert diff --git a/controllers/licenseissuer/config/default/webhookcainjection_patch.yaml b/controllers/licenseissuer/config/default/webhookcainjection_patch.yaml deleted file mode 100644 index 36db3c43859..00000000000 --- a/controllers/licenseissuer/config/default/webhookcainjection_patch.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# This patch add annotation to admission webhook config and -# CERTIFICATE_NAMESPACE and CERTIFICATE_NAME will be substituted by kustomize -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: validatingwebhookconfiguration - app.kubernetes.io/instance: validating-webhook-configuration - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: validating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME diff --git a/controllers/licenseissuer/config/manager/kustomization.yaml b/controllers/licenseissuer/config/manager/kustomization.yaml deleted file mode 100644 index 0498ab8b100..00000000000 --- a/controllers/licenseissuer/config/manager/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: ghcr.io/labring/sealos-licenseissuer-controller - newTag: latest diff --git a/controllers/licenseissuer/config/rbac/cloudclient_editor_role.yaml b/controllers/licenseissuer/config/rbac/cloudclient_editor_role.yaml deleted file mode 100644 index 998e8f38ed0..00000000000 --- a/controllers/licenseissuer/config/rbac/cloudclient_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit launchers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: launcher-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: launcher-editor-role -rules: -- apiGroups: - - cloud.sealos.io - resources: - - launchers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cloud.sealos.io - resources: - - launchers/status - verbs: - - get diff --git a/controllers/licenseissuer/config/rbac/cloudclient_viewer_role.yaml b/controllers/licenseissuer/config/rbac/cloudclient_viewer_role.yaml deleted file mode 100644 index 63ac314fc29..00000000000 --- a/controllers/licenseissuer/config/rbac/cloudclient_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view launchers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: launcher-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: launcher-viewer-role -rules: -- apiGroups: - - cloud.sealos.io - resources: - - launchers - verbs: - - get - - list - - watch -- apiGroups: - - cloud.sealos.io - resources: - - launchers/status - verbs: - - get diff --git a/controllers/licenseissuer/config/rbac/role.yaml b/controllers/licenseissuer/config/rbac/role.yaml deleted file mode 100644 index 2530c066931..00000000000 --- a/controllers/licenseissuer/config/rbac/role.yaml +++ /dev/null @@ -1,113 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: manager-role -rules: -- apiGroups: - - account.sealos.io - resources: - - accounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - account.sealos.io - resources: - - accounts/status - verbs: - - get - - patch - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - nodes - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - persistentvolumes - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - infostream.sealos.io - resources: - - licenses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - infostream.sealos.io - resources: - - licenses/finalizers - verbs: - - update -- apiGroups: - - infostream.sealos.io - resources: - - licenses/status - verbs: - - get - - patch - - update -- apiGroups: - - notification.sealos.io - resources: - - notifications - verbs: - - create - - delete - - get - - list - - patch - - update - - watch diff --git a/controllers/licenseissuer/config/samples/cloud_v1_cloudclient.yaml b/controllers/licenseissuer/config/samples/cloud_v1_cloudclient.yaml deleted file mode 100644 index 3e0266ef299..00000000000 --- a/controllers/licenseissuer/config/samples/cloud_v1_cloudclient.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: cloud.sealos.io/v1 -kind: Launcher -metadata: - labels: - app.kubernetes.io/name: launcher - app.kubernetes.io/instance: launcher-sample - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: licenseissuer-controller - name: launcher-sample -spec: - # TODO(user): Add fields here diff --git a/controllers/licenseissuer/config/webhook/kustomization.yaml b/controllers/licenseissuer/config/webhook/kustomization.yaml deleted file mode 100644 index 6c4ab864e21..00000000000 --- a/controllers/licenseissuer/config/webhook/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# resources: -# - manifests.yaml -# - service.yaml - -# configurations: -# - kustomizeconfig.yaml diff --git a/controllers/licenseissuer/config/webhook/kustomizeconfig.yaml b/controllers/licenseissuer/config/webhook/kustomizeconfig.yaml deleted file mode 100644 index 3e04003ac61..00000000000 --- a/controllers/licenseissuer/config/webhook/kustomizeconfig.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# the following config is for teaching kustomize where to look at when substituting nameReference. -# It requires kustomize v2.1.0 or newer to work properly. -# nameReference: -# - kind: Service -# version: v1 -# fieldSpecs: -# - kind: ValidatingWebhookConfiguration -# group: admissionregistration.k8s.io -# path: webhooks/clientConfig/service/name -# namespace: -# - kind: ValidatingWebhookConfiguration -# group: admissionregistration.k8s.io -# path: webhooks/clientConfig/service/namespace -# create: true diff --git a/controllers/licenseissuer/config/webhook/manifests.yaml b/controllers/licenseissuer/config/webhook/manifests.yaml deleted file mode 100644 index 01ece74173c..00000000000 --- a/controllers/licenseissuer/config/webhook/manifests.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - creationTimestamp: null - name: validating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-infostream-sealos-io-v1-license - failurePolicy: Ignore - name: vlicense.kb.io - rules: - - apiGroups: - - '*' - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - pods - sideEffects: None diff --git a/controllers/licenseissuer/config/webhook/service.yaml b/controllers/licenseissuer/config/webhook/service.yaml deleted file mode 100644 index bf742b43733..00000000000 --- a/controllers/licenseissuer/config/webhook/service.yaml +++ /dev/null @@ -1,20 +0,0 @@ - -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/name: service - app.kubernetes.io/instance: webhook-service - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/part-of: licenseissuer-controller - app.kubernetes.io/managed-by: kustomize - name: webhook-service - namespace: system -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager diff --git a/controllers/licenseissuer/deploy/Kubefile b/controllers/licenseissuer/deploy/Kubefile deleted file mode 100644 index bca9d0ce4a0..00000000000 --- a/controllers/licenseissuer/deploy/Kubefile +++ /dev/null @@ -1,24 +0,0 @@ -FROM scratch - -USER 65532:65532 - -COPY registry registry -COPY manifests manifests - -ENV canConnectToExternalNetwork "true" -ENV enableMonitor "true" -ENV MongoURI "" -ENV PasswordSalt "" -ENV MongoUserDB "test" -ENV MongoUserCollection "user" -ENV Namespace "sealos-system" -ENV CollectorURL "https://license.sealos.io/collector" -ENV NotificationURL "https://license.sealos.io/notify" -ENV RegisterURL "https://license.sealos.io/register" -ENV CloudSyncURL "https://license.sealos.io/datasync" -ENV LicenseMonitorURL "https://license.sealos.io/license" -ENV NetworkProbeURL "https://license.sealos.io/probe" - - - -CMD ["chmod +x manifests/setup.sh && bash manifests/setup.sh"] diff --git a/controllers/licenseissuer/deploy/manifests/configmaps.yaml b/controllers/licenseissuer/deploy/manifests/configmaps.yaml deleted file mode 100644 index 0481d6bd434..00000000000 --- a/controllers/licenseissuer/deploy/manifests/configmaps.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: v1 -data: null -kind: ConfigMap -metadata: - name: license-history - namespace: sealos-system ---- -apiVersion: v1 -kind: Secret -metadata: - name: licenseissuer-env - namespace: sealos-system -stringData: - canConnectToExternalNetwork: "true" - isMonitor: "true" ---- -apiVersion: v1 -data: - config.json: | - { - "CollectorURL": "https://license.sealos.io/collector", - "NotificationURL": "https://license.sealos.io/notify", - "RegisterURL": "https://license.sealos.io/register", - "CloudSyncURL": "https://license.sealos.io/datasync", - "LicenseMonitorURL": "https://license.sealos.io/license", - "NetworkProbeURL": "https://license.sealos.io/probe" - } -kind: ConfigMap -metadata: - name: url-config - namespace: sealos-system - diff --git a/controllers/licenseissuer/deploy/manifests/customconfig.yaml.tmpl b/controllers/licenseissuer/deploy/manifests/customconfig.yaml.tmpl deleted file mode 100644 index 02efee12915..00000000000 --- a/controllers/licenseissuer/deploy/manifests/customconfig.yaml.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: licenseissuer-env - namespace: sealos-system -stringData: - MongoURI: "{{ .MongoURI }}" - PasswordSalt: "{{ .PasswordSalt }}" - MongoUserDB: "{{ .MongoUserDB }}" - MongoUserCollection: "{{ .MongoUserCollection }}" - Namespace: "{{ .Namespace }}" ---- -apiVersion: v1 -data: - config.json: | - { - "CollectorURL": "{{ .CollectorURL }}", - "NotificationURL": "{{ .NotificationURL }}", - "RegisterURL": "{{ .RegisterURL }}", - "CloudSyncURL": "{{ .CloudSyncURL }}", - "LicenseMonitorURL": "{{ .LicenseMonitorURL }}", - "NetworkProbeURL": "{{ .NetworkProbeURL }}" - } -kind: ConfigMap -metadata: - name: url-config - namespace: "{{ .Namespace }}" ---- -apiVersion: v1 -data: null -kind: ConfigMap -metadata: - name: license-history - namespace: sealos-system diff --git a/controllers/licenseissuer/deploy/manifests/deploy.yaml b/controllers/licenseissuer/deploy/manifests/deploy.yaml deleted file mode 100644 index 69cec8976bb..00000000000 --- a/controllers/licenseissuer/deploy/manifests/deploy.yaml +++ /dev/null @@ -1,551 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: system - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: namespace - app.kubernetes.io/part-of: licenseissuer-controller - control-plane: controller-manager - name: sealos-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null - name: launchers.infostream.sealos.io -spec: - group: infostream.sealos.io - names: - kind: Launcher - listKind: LauncherList - plural: launchers - singular: launcher - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Launcher is the Schema for the launchers API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: LauncherSpec defines the desired state of Launcher - properties: - description: - type: string - name: - type: string - type: object - status: - description: LauncherStatus defines the observed state of Launcher - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null - name: licenses.infostream.sealos.io -spec: - group: infostream.sealos.io - names: - kind: License - listKind: LicenseList - plural: licenses - singular: license - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: License is the Schema for the licenses API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: LicenseSpec defines the desired state of License - properties: - key: - type: string - token: - type: string - uid: - type: string - type: object - status: - description: LicenseStatus defines the observed state of License - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: controller-manager-sa - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: serviceaccount - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-controller-manager - namespace: sealos-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: leader-election-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: role - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-leader-election-role - namespace: sealos-system -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: licenseissuer-manager-role -rules: -- apiGroups: - - account.sealos.io - resources: - - accounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - account.sealos.io - resources: - - accounts/status - verbs: - - get - - patch - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - nodes - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - persistentvolumes - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - infostream.sealos.io - resources: - - licenses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - infostream.sealos.io - resources: - - licenses/finalizers - verbs: - - update -- apiGroups: - - infostream.sealos.io - resources: - - licenses/status - verbs: - - get - - patch - - update -- apiGroups: - - notification.sealos.io - resources: - - notifications - verbs: - - create - - delete - - get - - list - - patch - - update - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: leader-election-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: rolebinding - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-leader-election-rolebinding - namespace: sealos-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: licenseissuer-leader-election-role -subjects: -- kind: ServiceAccount - name: licenseissuer-controller-manager - namespace: sealos-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: manager-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: licenseissuer-manager-role -subjects: -- kind: ServiceAccount - name: licenseissuer-controller-manager - namespace: sealos-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: licenseissuer-controller - name: licenseissuer-proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: licenseissuer-proxy-role -subjects: -- kind: ServiceAccount - name: licenseissuer-controller-manager - namespace: sealos-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: service - app.kubernetes.io/part-of: licenseissuer-controller - control-plane: controller-manager - name: licenseissuer-controller-manager-metrics-service - namespace: sealos-system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: licenseissuer-controller - app.kubernetes.io/instance: controller-manager - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: deployment - app.kubernetes.io/part-of: licenseissuer-controller - control-plane: controller-manager - name: licenseissuer-controller-manager - namespace: sealos-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux - containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /launcher - env: - - name: MONGO_URI - valueFrom: - secretKeyRef: - key: MongoURI - name: licenseissuer-env - - name: PASSWORD_SALT - valueFrom: - secretKeyRef: - key: PasswordSalt - name: licenseissuer-env - - name: MONGO_USER_DB - valueFrom: - secretKeyRef: - key: MongoUserDB - name: licenseissuer-env - - name: MONGO_USER_COL - valueFrom: - secretKeyRef: - key: MongoUserCollection - name: licenseissuer-env - - name: NAMESPACE - valueFrom: - secretKeyRef: - key: Namespace - name: licenseissuer-env - image: ghcr.io/labring/sealos-licenseissuer-controller:latest - imagePullPolicy: Always - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 1024Mi - requests: - cpu: 10m - memory: 512Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - securityContext: - runAsNonRoot: true - serviceAccountName: licenseissuer-controller-manager - terminationGracePeriodSeconds: 10 diff --git a/controllers/licenseissuer/deploy/manifests/setup.sh b/controllers/licenseissuer/deploy/manifests/setup.sh deleted file mode 100644 index a47a45e72d0..00000000000 --- a/controllers/licenseissuer/deploy/manifests/setup.sh +++ /dev/null @@ -1,17 +0,0 @@ -#! /bin/bash - -# check and create namespace of sealos-system -if ! kubectl get namespace sealos-system &> /dev/null; then - # if not exist, create namespace and check until it is created - echo "Namespace sealos-system does not exist. Creating..." - kubectl create namespace sealos-system - echo "Waiting for the creation of namespace sealos-system..." - while ! kubectl get namespace sealos-system &> /dev/null; do - sleep 1 - done - echo "Namespace sealos-system created." -else - echo "Namespace sealos-system already exists. Skipping creation." -fi - -kubectl apply -f manifests/deploy.yaml -f manifests/customconfig.yaml \ No newline at end of file diff --git a/controllers/licenseissuer/internal/controller/license_controller.go b/controllers/licenseissuer/internal/controller/license_controller.go deleted file mode 100644 index 0d374a80865..00000000000 --- a/controllers/licenseissuer/internal/controller/license_controller.go +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "errors" - - "github.com/labring/sealos/controllers/pkg/notification/utils" - - "github.com/go-logr/logr" - accountv1 "github.com/labring/sealos/controllers/account/api/v1" - - issuerv1 "github.com/labring/sealos/controllers/licenseissuer/api/v1" - "github.com/labring/sealos/controllers/licenseissuer/internal/controller/util" - notificationv1 "github.com/labring/sealos/controllers/pkg/notification/api/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" -) - -// LicenseReconciler reconciles a License object -type LicenseReconciler struct { - client.Client - Scheme *runtime.Scheme - logger logr.Logger - DBCol util.LicenseDB - payload map[string]interface{} - Recorder util.Map[string] - - account accountv1.Account - license issuerv1.License - configMap corev1.ConfigMap -} - -//+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch -//+kubebuilder:rbac:groups=core,resources=nodes,verbs=get;list;watch -//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch -//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=account.sealos.io,resources=accounts,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=account.sealos.io,resources=accounts/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=notification.sealos.io,resources=notifications,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=infostream.sealos.io,resources=licenses,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=infostream.sealos.io,resources=licenses/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=infostream.sealos.io,resources=licenses/finalizers,verbs=update - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the License object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.4/pkg/reconcile -func (r *LicenseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - r.logger.Info("Enter LicenseReconcile", "namespace:", req.Namespace, "name", req.Name) - r.logger.Info("Start to get license-related resource...") - // for notification - nq := &utils.NoticeEventQueue{} - nm := utils.NewNotificationManager(ctx, r.Client, r.logger, 1, 1) - nb := (&utils.Builder{}).WithLevel(notificationv1.High). - WithTitle(util.LicenseNoticeTitle).WithFrom(util.Sealos). - WithType(utils.General) - receiver := utils.NewReceiver(ctx, r.Client).AddReceiver(req.Namespace) - - reader := &util.Reader{} - // get license - namespace := util.GetOptions().GetEnvOptions().Namespace - reader.Add(&r.license, req.NamespacedName) - reader.Add(&r.configMap, types.NamespacedName{Namespace: namespace, Name: util.LicenseHistory}) - - if err := reader.Read(ctx, r.Client); err != nil { - r.logger.Error(err, "failed to read resources...") - return ctrl.Result{}, err - } - - // check license is valid or not - messgae, err := r.Authorize(ctx) - nb.WithMessage(messgae).AddToEventQueue(nq) - nm.Load(receiver, nq.Events).Run() - if err != nil { - return ctrl.Result{}, r.Delete(ctx, &r.license) - } - - _ = r.RecordLicense(r.payload) - - return ctrl.Result{}, r.Delete(ctx, &r.license) -} - -// SetupWithManager sets up the controller with the Manager. -func (r *LicenseReconciler) SetupWithManager(mgr ctrl.Manager) error { - r.logger = ctrl.Log.WithName("LicenseReconcile") - - // set up predicate - Predicate := predicate.Funcs{ - DeleteFunc: func(e event.DeleteEvent) bool { - // Ignore delete events - return false - }, - } - - return ctrl.NewControllerManagedBy(mgr). - For(&issuerv1.License{}, builder.WithPredicates(Predicate)). - Complete(r) -} - -func (r *LicenseReconciler) CheckLicense(ctx context.Context) (string, map[string]interface{}, bool) { - options := util.GetOptions() - // Check if the license is already used - ok, err := r.CheckLicenseExists() - if err != nil { - r.logger.Error(err, "failed to check license exists") - return util.DuplicateLicenseMessage, nil, false - } - - if ok { - return util.DuplicateLicenseMessage, nil, false - } - // Check if the license is valid - if options.GetNetWorkOptions().EnableExternalNetWork { - payload, ok := util.LicenseCheckOnExternalNetwork(ctx, r.Client, r.license) - if !ok { - return util.InvalidLicenseMessage, nil, false - } - return "", payload, true - } - payload, ok := util.LicenseCheckOnInternalNetwork(r.license) - if !ok { - return util.InvalidLicenseMessage, nil, false - } - return "", payload, true -} - -func (r *LicenseReconciler) CheckLicenseExists() (bool, error) { - ok := r.Recorder.Find(r.license.Spec.Token) - if ok { - return true, nil - } - ok, err := util.CheckLicenseExists(r.DBCol, r.license.Spec.UID, r.license.Spec.Token) - if err != nil { - r.logger.Error(err, "failed to check license exists") - return false, err - } - return ok, nil -} - -func (r *LicenseReconciler) Authorize(ctx context.Context) (string, error) { - message, payload, ok := r.CheckLicense(ctx) - if !ok { - return message, errors.New("invalid license") - } - r.payload = payload - // get account - id := types.NamespacedName{ - Namespace: util.GetOptions().GetEnvOptions().Namespace, - Name: r.license.Spec.UID, - } - err := r.Client.Get(ctx, id, &r.account) - if err != nil { - r.logger.Error(err, "failed to get account") - return util.RechargeFailedMessage, err - } - // recharge - if util.ContainsFields(payload, util.AmountField) { - err := util.RechargeByLicense(ctx, r.Client, r.account, payload) - if err != nil { - return util.RechargeFailedMessage, err - } - } - return util.ValidLicenseMessage, nil -} - -func (r *LicenseReconciler) RecordLicense(payload map[string]interface{}) error { - r.Recorder.Add(r.license.Spec.Token) - return util.RecordLicense(r.DBCol, util.NewLicense(r.license.Spec.UID, r.license.Spec.Token, payload)) -} diff --git a/controllers/licenseissuer/internal/controller/util/collect.go b/controllers/licenseissuer/internal/controller/util/collect.go deleted file mode 100644 index 026f3efc405..00000000000 --- a/controllers/licenseissuer/internal/controller/util/collect.go +++ /dev/null @@ -1,262 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "strconv" - "sync" - "time" - - ntf "github.com/labring/sealos/controllers/pkg/notification/utils" - - accountv1 "github.com/labring/sealos/controllers/account/api/v1" - account "github.com/labring/sealos/controllers/pkg/account" - "github.com/labring/sealos/controllers/pkg/database" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" -) - -const dateFormat = "2006-01-02" - -type TypeInfo string -type Date string - -const ( - ResourceOnCluster TypeInfo = "ClusterResource" - DailyUsage TypeInfo = "DailyUsage" -) - -type CollectorInfo struct { - UID string `json:"uid"` - InfoType TypeInfo `json:"infoType"` - DailyUsage DailyClusterUsage `json:"dailyUsage,omitempty"` - ClusterResource ClusterResource `json:"clusterResource,omitempty"` -} - -type DailyClusterUsage struct { - Date Date `json:"date"` - TotalUsageFee float64 `json:"totalUsageFee"` - HourlyUsage []float64 `json:"hourlyUsage"` -} - -type TotalNodesResource struct { - mutex sync.Mutex - TotalNodes string - TotalPVCapacity resource.Quantity - TotalMemory resource.Quantity - TotalCPU resource.Quantity -} - -type ClusterResource struct { - Nodes string `json:"nodes"` - CPU string `json:"cpu"` - GPU string `json:"gpu"` - Memory string `json:"memery"` - Disk string `json:"disk"` -} - -type Collect struct { - url string - // resource collect time of last - lastTimeForResource int64 - // usgae collect time of last - lastTimeForUsage int64 - - ClusterResource ClusterResource - DailyClusterUsage DailyClusterUsage - CollectorInfo CollectorInfo - - options OptionsReadOnly -} - -func NewCollect(o OptionsReadOnly) *Collect { - return &Collect{ - options: o, - } -} - -func (c *Collect) collectWork(instance *TaskInstance) error { - uid, urlMap, err := GetUIDURL(instance.ctx, instance.Client) - if err != nil { - instance.logger.Error(err, "failed to get uid and url") - return err - } - c.CollectorInfo.UID = uid - c.url = urlMap[CollectorURL] - if time.Unix(c.lastTimeForResource, 0).Add(time.Hour * 24).Before(time.Now()) { - err := c.doResourceCollect(instance) - if err != nil { - return err - } - } - if time.Unix(c.lastTimeForUsage, 0).Add(time.Hour * 24).Before(time.Now()) { - err := c.doUsageCollect(instance) - if err != nil { - return err - } - } - return nil -} - -func (c *Collect) collectResource(instance *TaskInstance) error { - tnr := TotalNodesResource{} - err := c.getNodeResource(instance, &tnr) - if err != nil { - instance.logger.Error(err, "failed to get node resource") - return err - } - err = c.getPVResource(instance, &tnr) - if err != nil { - instance.logger.Error(err, "failed to get pv resource") - return err - } - - c.ClusterResource.CPU = tnr.TotalCPU.String() - c.ClusterResource.Memory = tnr.TotalMemory.String() - c.ClusterResource.Disk = tnr.TotalPVCapacity.String() - c.ClusterResource.Nodes = tnr.TotalNodes - return nil -} - -func (c *Collect) collectUsage(instance *TaskInstance) error { - err := c.getUsageYesterday(instance) - if err != nil { - instance.logger.Info("failed to get usage yesterday") - return err - } - return nil -} - -// TotalNodesResource is used to collect the total resource of the cluster. -func (tnr *TotalNodesResource) getCPUMemoryResource(node *corev1.Node) { - var nodeMemory resource.Quantity - var nodeCPU resource.Quantity - - nodeMemory.Add(*node.Status.Capacity.Memory()) - nodeCPU.Add(*node.Status.Capacity.Cpu()) - - tnr.mutex.Lock() - - defer tnr.mutex.Unlock() - tnr.TotalMemory.Add(nodeMemory) - tnr.TotalCPU.Add(nodeCPU) -} - -func (c *Collect) getUsageYesterday(instance *TaskInstance) error { - MongoURI := c.options.GetEnvOptions().MongoURI - dailyClusterUsage := DailyClusterUsage{} - db, err := database.NewMongoDB(instance.ctx, MongoURI) - if err != nil { - instance.logger.Error(err, "failed to get mongo db") - return err - } - start, end := GetYesterdayAndTodayMidnight() - dailyClusterUsage.Date = Date(start.Format(dateFormat)) - // get billing amount for yesterday total usage fee - _, amount, err := db.GetBillingCount(accountv1.Consumption, start, end) - if err != nil { - instance.logger.Error(err, "failed to get billing amount") - return err - } - dailyClusterUsage.TotalUsageFee = float64(amount) / float64(account.CurrencyUnit) - // get billing amount for yesterday hourly usage fee - hourlyUsage := make([]float64, 24) - for cnt := 0; cnt < 24; cnt++ { - st := start.Add(time.Duration(cnt) * time.Hour) - ed := start.Add(time.Duration(cnt+1) * time.Hour) - _, amount, err := db.GetBillingCount(accountv1.Consumption, st, ed) - if err != nil { - instance.logger.Error(err, "failed to get billing amount") - return err - } - hourlyUsage[cnt] = float64(amount) / float64(account.CurrencyUnit) - } - dailyClusterUsage.HourlyUsage = hourlyUsage - c.DailyClusterUsage = dailyClusterUsage - return nil -} - -func GetYesterdayAndTodayMidnight() (time.Time, time.Time) { - now := time.Now() - midnightToday := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) - midnightYesterday := midnightToday.AddDate(0, 0, -1) - return midnightYesterday, midnightToday -} - -func (c *Collect) doResourceCollect(instance *TaskInstance) error { - err := c.collectResource(instance) - if err != nil { - return err - } - c.CollectorInfo.InfoType = ResourceOnCluster - c.CollectorInfo.ClusterResource = c.ClusterResource - err = Push(c.url, c.CollectorInfo) - if err != nil { - return err - } - c.lastTimeForResource = time.Now().Unix() - return nil -} - -func (c *Collect) doUsageCollect(instance *TaskInstance) error { - err := c.collectUsage(instance) - if err != nil { - return err - } - c.CollectorInfo.InfoType = DailyUsage - c.CollectorInfo.DailyUsage = c.DailyClusterUsage - err = Push(c.url, c.CollectorInfo) - if err != nil { - return err - } - c.lastTimeForUsage = time.Now().Unix() - return nil -} - -func (c *Collect) getPVResource(instance *TaskInstance, tnr *TotalNodesResource) error { - pvList := &corev1.PersistentVolumeList{} - err := instance.List(instance.ctx, pvList) - if err != nil { - instance.logger.Error(err, "failed to list pv") - return err - } - for _, pv := range pvList.Items { - storage := pv.Spec.Capacity[corev1.ResourceStorage] - tnr.TotalPVCapacity.Add(storage) - } - return nil -} - -func (c *Collect) getNodeResource(instance *TaskInstance, tnr *TotalNodesResource) error { - nodeList := &corev1.NodeList{} - err := instance.List(instance.ctx, nodeList) - if err != nil { - instance.logger.Error(err, "failed to list node") - return err - } - pool := ntf.NewPool(maxBatchSize) - pool.Run(maxChannelSize) - for _, node := range nodeList.Items { - node := node - pool.Add(func() { - tnr.getCPUMemoryResource(&node) - }) - } - pool.Wait() - tnr.TotalNodes = strconv.Itoa(len(nodeList.Items)) - return nil -} diff --git a/controllers/licenseissuer/internal/controller/util/const.go b/controllers/licenseissuer/internal/controller/util/const.go deleted file mode 100644 index 8eb80086e68..00000000000 --- a/controllers/licenseissuer/internal/controller/util/const.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -const ( - // SealosNamespace = "sealos-system" - ClusterInfo = "cluster-info" - URLConfig = "url-config" - LicenseHistory = "license-history" - LicenseName = "license" - // add more resource name here -) - -const ( - ContentType = "Content-Type" - ContentTypePlain = "text/plain" - ContentTypeHTML = "text/html" - ContentTypeJSON = "application/json" -) - -const ( - CollectorURL = "CollectorURL" - NotificationURL = "NotificationURL" - RegisterURL = "RegisterURL" - CloudSyncURL = "CloudSyncURL" - LicenseMonitorURL = "LicenseMonitorURL" - NetworkProbeURL = "NetworkProbeURL" - // Add more url here -) - -const NoticeFrom = "Sealos Cloud" - -var Key = "asdhjkwqdaskdjhqjwdakxausdasdajs" - -const ( - Sealos string = "Sealos Cloud" - ClusterCapacityNoticeTitle string = "Attention: Cluster Capacity Alert" - LicenseNoticeTitle string = "Attention: License Issue" - InvalidLicenseMessage string = "The license provided appears to be invalid. Please verify and try again." - ExpiredLicenseMessage string = "The license provided has expired. Please renew and try again." - ValidLicenseMessage string = "Your license has been successfully activated and is now ready for use. Enjoy your Sealos experience!" - DuplicateLicenseMessage string = "The license provided has already been activated. Please use a different license." - RechargeFailedMessage string = "License recharge operation failed." -) - -const ( - CreatTimeField = "iat" - AmountField = "amt" - NodeField = "nod" - CPUField = "cpu" - DurationField = "tte" - AddNodeField = "and" - AddCPUField = "adc" -) - -const ( - PeriodicPolicy = "Periodic" - PeriodicWithProbePolicy = "PeriodicWithProbe" - OncePolicy = "Once" - OnceWithProbePolicy = "OnceWithProbe" -) - -const ( - Collector task = "Collector" - DataSync task = "DataSync" - Init task = "Init" - Register task = "Register" - Notice task = "Notice" - NoticeCleanup task = "NoticeCleanup" - NetWorkConfig task = "NetWorkConfig" - MemoryCleanup task = "MemoryCleanup" - // Add more tasks here -) diff --git a/controllers/licenseissuer/internal/controller/util/datasync.go b/controllers/licenseissuer/internal/controller/util/datasync.go deleted file mode 100644 index 9ace748967f..00000000000 --- a/controllers/licenseissuer/internal/controller/util/datasync.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -type DataSycn struct { -} - -func NewDataSync() *DataSycn { - return &DataSycn{} -} - -type SyncRequest struct { - UID string `json:"uid"` -} - -type SyncResponse struct { - Config `json:",inline"` -} - -type Config struct { - CollectorURL string `json:"CollectorURL"` - NotificationURL string `json:"NotificationURL"` - RegisterURL string `json:"RegisterURL"` - CloudSyncURL string `json:"CloudSyncURL"` - LicenseMonitorURL string `json:"LicenseMonitorURL"` - // Add other fields here to support future expansion needs. -} - -func (d *DataSycn) sync(instance *TaskInstance) error { - uid, urlMap, err := GetUIDURL(instance.ctx, instance.Client) - if err != nil { - instance.logger.Info("failed to get uid and url map") - return err - } - // pull sync data from cloud - syncRequest := SyncRequest{ - UID: uid, - } - body, err := Pull(urlMap[CloudSyncURL], syncRequest) - if err != nil { - instance.logger.Info("failed to pull sync data from cloud") - return err - } - var syncResponse map[string]string - err = Convert(body.Body, &syncResponse) - if err != nil { - instance.logger.Info("failed to convert sync response") - return err - } - // update configmap - err = d.updateConfigMap(instance, syncResponse, types.NamespacedName{ - Namespace: GetOptions().GetEnvOptions().Namespace, - Name: URLConfig, - }) - - if err != nil { - instance.logger.Info("failed to update configmap") - return err - } - - return nil -} - -func (d *DataSycn) updateConfigMap(instance *TaskInstance, new map[string]string, id types.NamespacedName) error { - configMap := &corev1.ConfigMap{} - err := instance.Client.Get(instance.ctx, id, configMap) - if err != nil { - instance.logger.Info("failed to get configmap") - return err - } - if IsConfigMapChanged(new, configMap) { - err = instance.Client.Update(instance.ctx, configMap) - if err != nil { - instance.logger.Info("failed to update configmap") - return err - } - } - return nil -} diff --git a/controllers/licenseissuer/internal/controller/util/external.go b/controllers/licenseissuer/internal/controller/util/external.go deleted file mode 100644 index 9d5535717ac..00000000000 --- a/controllers/licenseissuer/internal/controller/util/external.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "reflect" -) - -type HTTPBody struct { - ContentType string - StatusCode int - Body []byte -} - -type HTTPResponse struct { - ContentType string - StatusCode int - Body []byte -} - -// The Get method is used to handle "GET" request. -func Get(url string) (HTTPResponse, error) { - body, err := CommunicateWithCloud("GET", url, nil) - if err != nil { - return HTTPResponse{}, fmt.Errorf("communicateWithCloud: %w", err) - } - if !IsSuccessfulStatusCode(body.StatusCode) { - return HTTPResponse{}, fmt.Errorf("error status: %s", http.StatusText(body.StatusCode)) - } - return body, nil -} - -// The Push method is used to handle one-way interaction, that is, -// there is no need to obtain information from the cloud, only need to send information to the cloud. -func Push(url string, content interface{}) error { - body, err := CommunicateWithCloud("POST", url, content) - if err != nil { - return fmt.Errorf("communicateWithCloud: %w", err) - } - if !IsSuccessfulStatusCode(body.StatusCode) { - return fmt.Errorf("error status: %s", http.StatusText(body.StatusCode)) - } - return nil -} - -// The Pull method is used to handle two-way interaction, -// that is, there is a need to obtain information from the cloud, -// and then send information to the cloud. -func Pull(url string, content interface{}) (HTTPResponse, error) { - body, err := CommunicateWithCloud("POST", url, content) - if err != nil { - return HTTPResponse{}, fmt.Errorf("communicateWithCloud: %w", err) - } - if !IsSuccessfulStatusCode(body.StatusCode) { - return HTTPResponse{}, fmt.Errorf("error status: %s", http.StatusText(body.StatusCode)) - } - return body, nil -} - -func CommunicateWithCloud(method string, url string, content interface{}) (HTTPResponse, error) { - var req *http.Request - var resp *http.Response - var err error - // create a http request to cloud - req, err = sendRequest(method, url, content) - if err != nil { - return HTTPResponse{}, fmt.Errorf("sendRequest: %w", err) - } - resp, err = getResponse(req) - if err != nil { - return HTTPResponse{}, fmt.Errorf("getResponse: %w", err) - } - defer resp.Body.Close() - return readResponse(resp) -} - -func Convert(body []byte, content interface{}) error { - if body == nil { - return fmt.Errorf("Convert: the body is empty") - } - contentValue := reflect.ValueOf(content) - if contentValue.Kind() != reflect.Ptr || contentValue.IsNil() { - return fmt.Errorf("Convert: content must be a non-nil pointer") - } - - if err := json.Unmarshal(body, content); err != nil { - return fmt.Errorf("Convert: json.Unmarshal: %w", err) - } - - return nil -} - -func IsSuccessfulStatusCode(statusCode int) bool { - return statusCode == http.StatusOK || statusCode == http.StatusCreated || statusCode == http.StatusAccepted || statusCode == http.StatusNoContent -} - -func sendRequest(method string, url string, content interface{}) (*http.Request, error) { - var body []byte - var req *http.Request - var err error - - if body, err = json.Marshal(content); err != nil { - return nil, fmt.Errorf("json.Marshal: %w", err) - } - req, err = http.NewRequest(method, url, bytes.NewBuffer(body)) - if err != nil { - return nil, fmt.Errorf("http.NewRequest: %w", err) - } - if method == "POST" { - req.Header.Set(ContentType, ContentTypeJSON) - } - return req, nil -} - -func getResponse(req *http.Request) (*http.Response, error) { - if req == nil { - return nil, fmt.Errorf("getResponse: no http request") - } - defer req.Body.Close() - var resp *http.Response - var err error - client := http.Client{} - resp, err = client.Do(req) - if err != nil { - return nil, fmt.Errorf("getResponse: %w", err) - } - return resp, nil -} - -func readResponse(resp *http.Response) (HTTPResponse, error) { - defer resp.Body.Close() - var httpResp HTTPResponse - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return HTTPResponse{}, fmt.Errorf("readResponse: %w", err) - } - httpResp.Body = bodyBytes - httpResp.ContentType = resp.Header.Get(ContentType) - httpResp.StatusCode = resp.StatusCode - return httpResp, nil -} diff --git a/controllers/licenseissuer/internal/controller/util/init.go b/controllers/licenseissuer/internal/controller/util/init.go deleted file mode 100644 index 23cd849ac3c..00000000000 --- a/controllers/licenseissuer/internal/controller/util/init.go +++ /dev/null @@ -1,140 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "sync" - - "github.com/google/uuid" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" -) - -const MaxRetryForConnectDB = 5 - -type RegisterRequest struct { - UID string `json:"uid"` -} - -// The following code is used to implement the instance of sub-task which is used to -// initialize the cluster uuid and preset root user for mongoDB -type InitTask struct { - options OptionsReadOnly - probe InitProbe -} - -func NewInitTask(o OptionsReadOnly) *InitTask { - return &InitTask{ - options: o, - probe: GetInitProbe(), - } -} - -func (t *InitTask) initWork(instance *TaskInstance) error { - // register function is idempotent - err := t.register(instance) - if err != nil { - instance.logger.Info("failed to register", "err", err) - return err - } - t.probe.Completed() - return nil -} - -// 1. check if the cluster has been registered -// 2. store cluster-info to k8s - -func (t *InitTask) register(instance *TaskInstance) error { - ClusterInfo := createClusterInfo() - // step 1 - // check if the cluster has been registered - registered, err := t.checkRegister(instance) - if err != nil { - instance.logger.Info("failed to check if the cluster has been registered") - return err - } - if registered { - instance.logger.Info("cluster has been registered") - return nil - } - - // step 2 - // only after register to cloud, the store-behavior will be executed. - err = instance.Create(instance.ctx, ClusterInfo) - if err != nil { - instance.logger.Info("failed to store cluster info", "err", err) - } - return err -} - -// check if the cluster has been registered. -func (t *InitTask) checkRegister(instance *TaskInstance) (bool, error) { - info := &corev1.Secret{} - err := instance.Get(instance.ctx, types.NamespacedName{ - Name: ClusterInfo, - Namespace: GetOptions().GetEnvOptions().Namespace, - }, info) - if err != nil && apierrors.IsNotFound(err) { - return false, nil - } - return true, err -} - -func createClusterInfo() *corev1.Secret { - uuid := uuid.New().String() - secret := &corev1.Secret{} - secret.Name = ClusterInfo - secret.Namespace = GetOptions().GetEnvOptions().Namespace - secret.Data = map[string][]byte{ - "uuid": []byte(uuid), - } - return secret -} - -var onceForInit sync.Once -var flag Flag -var _ InitProbe = &Flag{} -var _ Probe = &Flag{} - -type InitProbe interface { - Probe - Completed() -} - -type Flag struct { - flag bool -} - -func (f *Flag) Completed() { - f.flag = true -} - -func (f *Flag) Probe() bool { - return f.flag -} - -func GetInitProbe() InitProbe { - onceForInit.Do(func() { - flag.flag = false - }) - return &flag -} - -func ProbeForInit() Probe { - return GetInitProbe() -} diff --git a/controllers/licenseissuer/internal/controller/util/license.go b/controllers/licenseissuer/internal/controller/util/license.go deleted file mode 100644 index 87bd6206a42..00000000000 --- a/controllers/licenseissuer/internal/controller/util/license.go +++ /dev/null @@ -1,372 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - "encoding/base64" - "errors" - "reflect" - "time" - - "github.com/golang-jwt/jwt/v4" - - accountv1 "github.com/labring/sealos/controllers/account/api/v1" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - - "github.com/go-logr/logr" - issuerv1 "github.com/labring/sealos/controllers/licenseissuer/api/v1" - count "github.com/labring/sealos/controllers/pkg/account" - "github.com/labring/sealos/controllers/pkg/crypto" - "github.com/labring/sealos/controllers/pkg/database" - mongoOptions "go.mongodb.org/mongo-driver/mongo/options" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type LicenseMonitorRequest struct { - UID string `json:"uid"` - Token string `json:"token"` -} - -type LicenseMonitorResponse struct { - Key string `json:"key"` -} - -var logger logr.Logger - -func init() { - logger = ctrl.Log.WithName("License") -} - -func LicenseCheckOnExternalNetwork(ctx context.Context, client client.Client, license issuerv1.License) (map[string]interface{}, bool) { - license.Spec.Key = Key - payload, ok := IsLicenseValid(license) - if ok { - return payload, ok - } - uid, urlMap, err := GetUIDURL(ctx, client) - res := LicenseMonitorRequest{ - UID: uid, - Token: license.Spec.Token, - } - if err != nil { - logger.Error(err, "failed to get uid and url when license check on external network") - return nil, false - } - if !ok { - var resp LicenseMonitorResponse - httpBody, err := Pull(urlMap[LicenseMonitorURL], res) - if err != nil { - logger.Error(err, "failed to pull license monitor request") - return nil, false - } - err = Convert(httpBody.Body, &resp) - if err != nil { - logger.Error(err, "failed to convert") - return nil, false - } - license.Spec.Key = resp.Key - return IsLicenseValid(license) - } - return payload, ok -} - -func LicenseCheckOnInternalNetwork(license issuerv1.License) (map[string]interface{}, bool) { - license.Spec.Key = Key - return IsLicenseValid(license) -} - -func IsLicenseValid(license issuerv1.License) (map[string]interface{}, bool) { - decodeKey, err := base64.StdEncoding.DecodeString(license.Spec.Key) - if err != nil { - return nil, false - } - publicKey, err := crypto.ParseRSAPublicKeyFromPEM(string(decodeKey)) - //fmt.Println(string(decodeKey)) - if err != nil { - return nil, false - } - keyFunc := func(token *jwt.Token) (interface{}, error) { - return publicKey, nil - } - parsedToken, err := jwt.Parse(license.Spec.Token, keyFunc) - if err != nil { - return nil, false - } - - claims, ok := parsedToken.Claims.(jwt.MapClaims) - if ok && parsedToken.Valid { - return claims, ok - } - return nil, false -} - -func RechargeByLicense(ctx context.Context, client client.Client, account accountv1.Account, payload map[string]interface{}) error { - if !ContainsFields(payload, "amt") { - return nil - } - amount, err := InterfaceToInt64(payload["amt"]) - if err != nil { - return errors.New("amount error type") - } - charge := amount * count.CurrencyUnit - account.Status.Balance += charge - err = crypto.RechargeBalance(account.Status.EncryptBalance, charge) - if err != nil { - logger.Error(err, "Failed to crypto the account balance") - return err - } - err = client.Status().Update(ctx, &account) - if err != nil { - logger.Error(err, "Recharge Failed, failed to modify the status") - return err - } - - return nil -} - -func RecordLicense(dbCol LicenseDB, license License) error { - err := dbCol.Record(license) - if err != nil { - logger.Error(err, "failed to record license") - return err - } - return nil -} - -func CheckLicenseExists(dbCol LicenseDB, uid string, token string) (bool, error) { - ok, err := dbCol.IsExisted(uid, token) - if err != nil { - logger.Info("failed to check license exists") - return false, err - } - - return ok, nil -} - -func ContainsFields(data map[string]interface{}, fields ...string) bool { - for _, field := range fields { - _, ok := data[field] - if !ok { - return false - } - } - return true -} - -func InterfaceToInt64(value interface{}) (int64, error) { - switch v := value.(type) { - case int64: - return v, nil - case float64: - return int64(v), nil - default: - return 0, errors.New("cannot convert value of type to int64") - } -} - -//--------------------- license Data --------------------- // - -type LicenseDB interface { - Record(license License) error - QueryByUID(ns string, st int64, ed int64) ([]LicenseResult, error) - - IsExisted(uid string, token string) (bool, error) - Disconnect() error -} - -const DefaultColForLicense = "license" - -type licenseDB struct { - URI string - Client *mongo.Client - DBName string - COLName string -} - -type License struct { - UID string `bson:"uid"` - Token string `bson:"token"` - CreateTime string `bson:"createTime"` - Payload map[string]interface{} `bson:"payload"` -} - -type LicenseResult struct { - License License `bson:"license"` -} - -func NewLicense(uid string, token string, payload map[string]interface{}) License { - return License{ - UID: uid, - Token: token, - CreateTime: time.Now().Format("2006-01-02 15:04:05"), - Payload: payload, - } -} - -var _ LicenseDB = &licenseDB{} - -func (db *licenseDB) IsExisted(uid string, token string) (bool, error) { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - filter := bson.M{"uid": uid, "license": bson.M{"$elemMatch": bson.M{"token": token}}} - res := db.Client.Database(db.DBName).Collection(db.COLName).FindOne(ctx, filter) - if res.Err() != nil { - if res.Err().Error() == mongo.ErrNoDocuments.Error() { - // not found - return false, nil - } - return false, res.Err() - } - // found - return true, nil -} - -func (db *licenseDB) QueryByUID(uid string, st int64, ed int64) ([]LicenseResult, error) { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - pipeline := []bson.M{ - {"$match": bson.M{"uid": uid}}, - {"$unwind": "$license"}, - {"$project": bson.M{"license": 1}}, - {"$project": bson.M{"_id": 0}}, - {"$match": bson.M{"license.token": bson.M{"$ne": ""}}}, - {"$sort": bson.M{"license.createTime": -1}}, - {"$skip": st}, - {"$limit": ed - st + 1}, - } - - cursor, err := db.Client.Database(db.DBName).Collection(db.COLName).Aggregate(ctx, pipeline) - if err != nil { - return nil, err - } - - var res []LicenseResult - err = cursor.All(ctx, &res) - if err != nil { - return nil, err - } - return res, nil -} - -func (db *licenseDB) Record(license License) error { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - filter := bson.M{"uid": license.UID} - update := bson.M{"$push": bson.M{"license": license}} - updateOptions := mongoOptions.Update().SetUpsert(true) - _, err := db.Client.Database(db.DBName).Collection(db.COLName).UpdateOne(ctx, filter, update, updateOptions) - return err -} - -func (db *licenseDB) Disconnect() error { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - return db.Client.Disconnect(ctx) -} - -func NewLicenseDB(uri string) (LicenseDB, error) { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - clientOptions := mongoOptions.Client().ApplyURI(uri) - client, err := mongo.Connect(ctx, clientOptions) - if err != nil { - return &licenseDB{}, err - } - return &licenseDB{ - URI: uri, - Client: client, - DBName: database.DefaultDBName, - COLName: DefaultColForLicense, - }, nil -} - -type Map[T any] interface { - Find(T) bool - Add(T) - Remove() -} - -type HashMap[T comparable] struct { - m map[T]int64 -} - -func NewHashMap[T comparable]() Map[T] { - return &HashMap[T]{ - m: make(map[T]int64), - } -} - -func (hs *HashMap[T]) Find(item T) bool { - _, ok := hs.m[item] - return ok -} - -func (hs *HashMap[T]) Add(item T) { - hs.m[item] = time.Now().Unix() -} - -func (hs *HashMap[T]) Remove() { - // lifetime of item is 24 hours - for k, v := range hs.m { - if v+24*60*60*3 < time.Now().Unix() { - delete(hs.m, k) - } - } -} - -var singleton Map[string] - -func GetHashMap() Map[string] { - if singleton == nil { - singleton = NewHashMap[string]() - } - return singleton -} - -type Memory[T any] interface { - Remove() -} - -type MemoryClean struct { - MM1 Memory[string] -} - -func NewMemoryCleaner() *MemoryClean { - return &MemoryClean{ - MM1: GetHashMap(), - } -} - -func (mc *MemoryClean) cleanWork(_ *TaskInstance) error { - // range field - v := reflect.ValueOf(mc) - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - for i := 0; i < v.NumField(); i++ { - value := v.Field(i) - method := value.MethodByName("Remove") - if method.IsValid() { - method.Call(nil) - } - } - return nil -} diff --git a/controllers/licenseissuer/internal/controller/util/notice.go b/controllers/licenseissuer/internal/controller/util/notice.go deleted file mode 100644 index 62ab7f5c67c..00000000000 --- a/controllers/licenseissuer/internal/controller/util/notice.go +++ /dev/null @@ -1,266 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - "fmt" - "strings" - "time" - - "github.com/labring/sealos/controllers/pkg/notification/utils" - - notificationv1 "github.com/labring/sealos/controllers/pkg/notification/api/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// the NoticeWork task is used to get the notification from the cloud. -// And then send the notification to the cluster. -type NoticeWork struct { - lastTime int64 -} - -type NotificationResponse struct { - ID string `json:"_id"` - Type string `json:"msgType"` - Title string `json:"title"` - Message string `json:"message"` - Timestamp int64 `json:"timestamp"` -} - -type NotificationRequest struct { - UID string `json:"uid"` - Timestamp int64 `json:"timestamp"` -} - -func (nr *NotificationRequest) setUID(uid string) *NotificationRequest { - nr.UID = uid - return nr -} - -func (nr *NotificationRequest) setTimestamp(timestamp int64) *NotificationRequest { - nr.Timestamp = timestamp - return nr -} - -func (n *NoticeWork) noticeWork(instance *TaskInstance) error { - // init - receiver := utils.NewReceiver(instance.ctx, instance.Client) - manager := utils.NewNotificationManager(instance.ctx, instance.Client, - instance.logger, maxBatchSize, maxChannelSize) - // get uid and url-map - uid, urlMap, err := GetUIDURL(instance.ctx, instance.Client) - if err != nil { - instance.logger.Info("failed to get uid and url-map", "err", err) - return err - } - - request := (&NotificationRequest{}).setTimestamp(n.lastTime).setUID(uid) - - // pull from the cloud - response, err := Pull(urlMap[NotificationURL], request) - if err != nil { - instance.logger.Info("failed to pull from cloud", "err", err) - return err - } - - // get notice-events from response - events, err := n.getEvents(instance, response.Body) - if err != nil { - instance.logger.Info("failed to get events", "err", err) - return err - } - - // get receivers - receiver.AddReceivers(n.getUserNamespace(instance, filter)) - - manager.Load(receiver, events).Run() - return nil -} - -func GetUIDURL(ctx context.Context, client client.Client) (string, map[string]string, error) { - urlMap, err := GetURL(ctx, client) - if err != nil { - return "", nil, fmt.Errorf("failed to get url-map: %w", err) - } - uid, err := GetUID(ctx, client) - if err != nil { - return "", nil, fmt.Errorf("failed to get uid: %w", err) - } - return uid, urlMap, nil -} - -func GetURL(ctx context.Context, client client.Client) (map[string]string, error) { - urlConfigMap := &corev1.ConfigMap{} - id := types.NamespacedName{ - Name: URLConfig, - Namespace: GetOptions().GetEnvOptions().Namespace, - } - // get url-config from k8s - err := client.Get(ctx, id, urlConfigMap) - if err != nil { - return nil, fmt.Errorf("failed to get url-config: %w", err) - } - // get url-map from url-config - urlMap, err := GetConfigFromConfigMap(URLConfig, urlConfigMap) - if err != nil { - return nil, fmt.Errorf("failed to get url-map: %w", err) - } - return urlMap, nil -} - -func GetUID(ctx context.Context, client client.Client) (string, error) { - info := &corev1.Secret{} - err := client.Get(ctx, types.NamespacedName{ - Name: ClusterInfo, - Namespace: GetOptions().GetEnvOptions().Namespace, - }, info) - if err != nil { - return "", fmt.Errorf("failed to get cluster-info: %w", err) - } - uid := string(info.Data["uuid"]) - return uid, nil -} - -func NewNotice() *NoticeWork { - return &NoticeWork{lastTime: time.Now().Add(-7 * time.Hour).Unix()} -} - -func (n *NoticeWork) getEvents(instance *TaskInstance, body []byte) ([]utils.Event, error) { - var resps []NotificationResponse - var events []utils.Event - err := Convert(body, &resps) - if err != nil { - instance.logger.Info("failed to convert body", "err", err) - return nil, err - } - for _, resp := range resps { - // get notification from response - events = append(events, utils.NewNotificationEvent( - resp.Title, - resp.Message, - utils.General, - NoticeFrom, - notificationv1.Low, - )) - if resp.Timestamp > n.lastTime { - n.lastTime = resp.Timestamp - } - } - - return events, nil -} - -// the NoticeCleaner task is used to clean the notification in the cluster periodically. -type NoticeCleaner struct { - lastTime int64 -} - -func NewNoticeCleaner() *NoticeCleaner { - return &NoticeCleaner{lastTime: time.Now().Unix()} -} - -func (nc *NoticeCleaner) cleanWork(instance *TaskInstance) error { - // catch all notification in the cluster - notifications := ¬ificationv1.NotificationList{} - - err := instance.List(instance.ctx, notifications) - if err != nil { - instance.logger.Info("failed to list notification", "err", err) - return err - } - // Get the notification that needs to be deleted - expiredNotifications, err := nc.getNotificationsExpired(instance) - if err != nil { - instance.logger.Info("failed to get expired notification", "err", err) - return err - } - // delete the notification - pool := utils.NewPool(maxBatchSize) - pool.Run(maxChannelSize) - for _, notification := range expiredNotifications { - newCopy := notification - pool.Add(func() { - err := instance.Delete(instance.ctx, &newCopy) - if err != nil { - instance.logger.Info("failed to delete notification", "err", err) - } - }) - } - pool.Wait() - return nil -} - -func (nc *NoticeCleaner) getNotificationsExpired(instance *TaskInstance) ([]notificationv1.Notification, error) { - notifications := ¬ificationv1.NotificationList{} - err := instance.List(instance.ctx, notifications) - if err != nil { - instance.logger.Info("failed to list notification", "err", err) - return nil, err - } - var expiredNotifications []notificationv1.Notification - - for _, notification := range notifications.Items { - timeStamp := notification.Spec.Timestamp - switch notification.Spec.Importance { - case notificationv1.High: - if time.Unix(timeStamp, 0).Add(time.Hour * 24 * 15).Before(time.Now()) { - expiredNotifications = append(expiredNotifications, notification) - } - case notificationv1.Medium: - if time.Unix(timeStamp, 0).Add(time.Hour * 24 * 7).Before(time.Now()) { - expiredNotifications = append(expiredNotifications, notification) - } - case notificationv1.Low: - if time.Unix(timeStamp, 0).Add(time.Hour * 24 * 3).Before(time.Now()) { - expiredNotifications = append(expiredNotifications, notification) - } - default: - if time.Unix(timeStamp, 0).Add(time.Hour * 24 * 3).Before(time.Now()) { - expiredNotifications = append(expiredNotifications, notification) - } - } - } - return expiredNotifications, nil -} - -const maxBatchSize = 100 -const maxChannelSize = 500 - -type FilterFunc func(string) bool - -func (n *NoticeWork) getUserNamespace(instance *TaskInstance, opt FilterFunc) []string { - namespaceList := &corev1.NamespaceList{} - err := instance.List(instance.ctx, namespaceList) - if err != nil { - instance.logger.Info("failed to list namespace", "err", err) - return nil - } - var namespaces []string - for _, namespace := range namespaceList.Items { - if opt(namespace.Name) { - namespaces = append(namespaces, namespace.Name) - } - } - return namespaces -} - -func filter(ns string) bool { - return strings.HasPrefix(ns, utils.GeneralPrefix) -} diff --git a/controllers/licenseissuer/internal/controller/util/options.go b/controllers/licenseissuer/internal/controller/util/options.go deleted file mode 100644 index ccdb62bfac0..00000000000 --- a/controllers/licenseissuer/internal/controller/util/options.go +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "os" - "sync" - "time" -) - -type task string - -// A interface for options to implement read-only access. -type Options interface { - OptionsReadOnly - OptionsReadWrite -} - -type OptionsReadOnly interface { - GetPolicy(name task) string - GetPeriod(name task) time.Duration - GetDefaultPeriod() time.Duration - GetEnvOptions() EnvOptions - GetNetWorkOptions() NetWorkOptions - GetRunnableOptions() RunnableOptions - GetDBOptions() DBOptions -} - -type OptionsReadWrite interface { - SetNetworkConfig(flag bool) -} - -// a singleton instance of Options -var options Options -var once sync.Once - -// GetOptions returns the singleton instance of Options. -func GetOptions() Options { - once.Do(func() { - options = NewOptions() - }) - return options -} - -// GetOptionsReadOnly returns the singleton instance of OptionsReadOnly. -func GetOptionsReadOnly() OptionsReadOnly { - return GetOptions() -} - -// GetOptionsReadWrite returns the singleton instance of OptionsReadWrite. -func GetOptionsReadWrite() OptionsReadWrite { - return GetOptions() -} - -// The OperatorOptions struct is used to make configuration options available to -// licenseissuer operators. -type OperatorOptions struct { - // The EnvOptions is used to store environment variables. - EnvOptions EnvOptions - // The DBOptions is used to store options for the database. - DBOptions DBOptions - // The RunnableOptions is used to store options for the Runnable instance - RunnableOptions RunnableOptions - // The NetWorkOptions is used to store options for the NetWork instance - NetWorkOptions NetWorkOptions -} - -func (o *OperatorOptions) SetNetworkConfig(flag bool) { - o.NetWorkOptions.EnableExternalNetWork = flag -} - -func (o *OperatorOptions) GetPolicy(tkname task) string { - return o.RunnableOptions.Policy[tkname] -} - -func (o *OperatorOptions) GetPeriod(tkname task) time.Duration { - if o.GetPolicy(tkname) == "Once" { - return 0 - } - if o.RunnableOptions.Period[tkname] == 0 { - return o.RunnableOptions.DefaultPeriod - } - return o.RunnableOptions.Period[tkname] -} - -func (o *OperatorOptions) GetEnvOptions() EnvOptions { - return o.EnvOptions -} - -func (o *OperatorOptions) GetDefaultPeriod() time.Duration { - return o.RunnableOptions.DefaultPeriod -} - -func (o *OperatorOptions) GetRunnableOptions() RunnableOptions { - return o.RunnableOptions -} - -func (o *OperatorOptions) GetDBOptions() DBOptions { - return o.DBOptions -} -func (o *OperatorOptions) GetNetWorkOptions() NetWorkOptions { - return o.NetWorkOptions -} - -func NewOptions() *OperatorOptions { - o := &OperatorOptions{} - o.initOptions() - return o -} - -func (o *OperatorOptions) initOptions() { - o.EnvOptions.initOptions() - o.RunnableOptions.initOptions() - o.DBOptions.initOptions() - o.NetWorkOptions.initOptions() - - // allow developer to choose the policy and period of the task - o.RunnableOptions.Policy[Init] = OncePolicy - o.RunnableOptions.Period[Init] = 0 - - o.RunnableOptions.Policy[Collector] = PeriodicWithProbePolicy - o.RunnableOptions.Period[Collector] = 8 * time.Hour - - o.RunnableOptions.Policy[DataSync] = PeriodicWithProbePolicy - o.RunnableOptions.Period[DataSync] = 1 * time.Hour - - o.RunnableOptions.Policy[Notice] = PeriodicWithProbePolicy - o.RunnableOptions.Period[Notice] = 3 * time.Hour - - o.RunnableOptions.Policy[NoticeCleanup] = PeriodicPolicy - o.RunnableOptions.Period[NoticeCleanup] = 24 * time.Hour - - o.RunnableOptions.Policy[NetWorkConfig] = PeriodicPolicy - o.RunnableOptions.Period[NetWorkConfig] = 30 * time.Minute - - o.RunnableOptions.Policy[Register] = OnceWithProbePolicy - o.RunnableOptions.Period[Register] = 5 * time.Minute - - o.RunnableOptions.Policy[MemoryCleanup] = PeriodicPolicy - o.RunnableOptions.Period[MemoryCleanup] = 5 * time.Minute - // Add more tasks Policy and Period here -} - -// The EnvOptions is used to store environment variables. -type EnvOptions struct { - - // The MongoURI is used to connect to the MongoDB database. - MongoURI string - - // The SaltKey is used to encrypt the password for pre-registered users. - SaltKey string - - // Namespace - Namespace string -} - -func (eo *EnvOptions) initOptions() { - eo.MongoURI = os.Getenv("MONGO_URI") - eo.SaltKey = os.Getenv("PASSWORD_SALT") - eo.Namespace = os.Getenv("NAMESPACE") -} - -type RunnableOptions struct { - // The Policy is configured the task of framework. - // --> Once: The task is executed only once. - // --> Periodic: The task is executed periodically. - Policy map[task]string - // The Period is configured the period of the task - // if empty, use the default period. - Period map[task]time.Duration - DefaultPeriod time.Duration -} - -type NetWorkOptions struct { - // EnableExternalNetWork is used to distinguish between - // external and internal networks. - EnableExternalNetWork bool -} - -func (no *NetWorkOptions) initOptions() { - no.EnableExternalNetWork = false -} - -func (ro *RunnableOptions) initOptions() { - ro.Policy = make(map[task]string) - ro.Period = make(map[task]time.Duration) - ro.DefaultPeriod = 1 * time.Hour -} - -type DBOptions struct { - // The MongoOptions is used to store options for the MongoDB database. - MongoOptions MongoOptions -} - -func (do *DBOptions) initOptions() { - do.MongoOptions.initOptions() -} - -type MongoOptions struct { - // The MongoURI is used to connect to the MongoDB database. - MongoURI string - // The UserDB is the db reference of the MongoDB database. - UserDB string - // The UserCol is the collection of the UserDB to store user information. - UserCol string -} - -func (mo *MongoOptions) initOptions() { - mo.MongoURI = os.Getenv("MONGO_URI") - mo.UserDB = os.Getenv("MONGO_USER_DB") - mo.UserCol = os.Getenv("MONGO_USER_COL") -} diff --git a/controllers/licenseissuer/internal/controller/util/prob.go b/controllers/licenseissuer/internal/controller/util/prob.go deleted file mode 100644 index 617ea25a526..00000000000 --- a/controllers/licenseissuer/internal/controller/util/prob.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "sync" -) - -// Probe is an interface for a probe check -type Probe interface { - Probe() bool -} - -// ProbeFor return the Probe interface for the given task type -func ProbeFor(taskType task) []Probe { - switch taskType { - case Collector, DataSync, Notice: - return []Probe{ProbeForInit(), ProbeForNetWork(), ProbeForRegister()} - case Register: - return []Probe{ProbeForInit()} - default: - return nil - } -} - -// NetworkProbe is an interface for a network probe check - -type NetworkProbe interface { - Probe - ProbeForNetWork(url string) -} - -type networkProbe struct { - options OptionsReadWrite -} - -type NetworkConfig struct { - url string - np NetworkProbe -} - -func NewNetworkConfig() *NetworkConfig { - return &NetworkConfig{ - np: GetNetworkProbe(), - } -} - -func (n *NetworkConfig) probe(instance *TaskInstance) error { - urlMap, err := GetURL(instance.ctx, instance.Client) - if err != nil { - instance.logger.Info("get url error", "error", err) - return err - } - n.url = urlMap[NetworkProbeURL] - n.np.ProbeForNetWork(n.url) - return nil -} - -func (n *networkProbe) Probe() bool { - return options.GetNetWorkOptions().EnableExternalNetWork -} - -func (n *networkProbe) ProbeForNetWork(url string) { - _, err := Get(url) - if err != nil { - // The network is not available - n.options.SetNetworkConfig(false) - return - } - // The network is available - n.options.SetNetworkConfig(true) -} - -var onceForNetworkProbe sync.Once -var networkProbeInstance networkProbe - -var _ NetworkProbe = &networkProbe{} -var _ Probe = &networkProbe{} - -func GetNetworkProbe() NetworkProbe { - onceForNetworkProbe.Do(func() { - networkProbeInstance = networkProbe{ - options: GetOptionsReadWrite(), - } - }) - return &networkProbeInstance -} - -func ProbeForNetWork() Probe { - return GetNetworkProbe() -} - -type RegisterProbe interface { - Probe - SetFlag(flag bool) -} - -type RegisterWork struct { - probe RegisterProbe -} - -type registerProbe struct { - flag bool -} - -var onceForRegisterProbe sync.Once -var registerProbeInstance registerProbe - -var _ RegisterProbe = ®isterProbe{} -var _ Probe = ®isterProbe{} - -func GetRegisterProbe() RegisterProbe { - onceForRegisterProbe.Do(func() { - registerProbeInstance = registerProbe{} - }) - return ®isterProbeInstance -} - -func NewRegister() *RegisterWork { - return &RegisterWork{ - probe: GetRegisterProbe(), - } -} - -func (r *RegisterWork) register(instance *TaskInstance) error { - return r.registerToCloud(instance) -} - -func (r *RegisterWork) registerToCloud(instance *TaskInstance) error { - uid, urlMap, err := GetUIDURL(instance.ctx, instance.Client) - if err != nil { - instance.logger.Info("get uid and url error", "error", err) - return err - } - rr := RegisterRequest{ - UID: uid, - } - // send info to cloud - err = Push(urlMap[RegisterURL], rr) - if err != nil { - instance.logger.Info("write to cloud error", "error", err) - return err - } - r.probe.SetFlag(true) - return nil -} - -func (r *registerProbe) SetFlag(flag bool) { - r.flag = flag -} - -func ProbeForRegister() Probe { - return GetRegisterProbe() -} - -func (r *registerProbe) Probe() bool { - return r.flag -} diff --git a/controllers/licenseissuer/internal/controller/util/reader.go b/controllers/licenseissuer/internal/controller/util/reader.go deleted file mode 100644 index ab2bee28963..00000000000 --- a/controllers/licenseissuer/internal/controller/util/reader.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// This module provides a highly extensible method for reading k8s resources - -type Reader struct { - objArray []client.Object - idArray []types.NamespacedName -} - -func (r *Reader) Add(obj client.Object, id types.NamespacedName) { - r.objArray = append(r.objArray, obj) - r.idArray = append(r.idArray, id) -} - -func (r *Reader) Read(ctx context.Context, client client.Client) error { - size := len(r.objArray) - for i := 0; i < size; i++ { - err := client.Get(ctx, r.idArray[i], r.objArray[i]) - if err != nil { - return err - } - } - return nil -} diff --git a/controllers/licenseissuer/internal/controller/util/runnable.go b/controllers/licenseissuer/internal/controller/util/runnable.go deleted file mode 100644 index 9d8987ca090..00000000000 --- a/controllers/licenseissuer/internal/controller/util/runnable.go +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - "fmt" - "time" - - "github.com/go-logr/logr" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// This file provided a framework which can be used to build a runnable task. -// With this framework, developers can easily build a runnable task and add it to the manager. -func BuildForRunnable(ctx context.Context, client client.Client, options Options) []manager.Runnable { - pool := NewTaskBuilder(ctx, client, options) - tasks := pool.tasks - runnables := make([]manager.Runnable, len(tasks)) - for i := range tasks { - runnables[i] = tasks[i] - } - return runnables -} - -// TaskInstance implements the Task interface. -type Task interface { - Run() error - Log() *logr.Logger - Probe() bool -} - -// allow the user to define their own runnable task -type TaskFunc func(context.Context) error - -// Once func is used to run a task only once. -func Once(_ context.Context, _ time.Duration, t Task) error { - err := t.Run() - if err != nil { - (t.Log()).Error(err, "failed to run task") - } - return nil -} - -// OnceWithProbe func is used to run a task only once. -func OnceWithProbe(ctx context.Context, period time.Duration, t Task) error { - for { - select { - case <-ctx.Done(): - return nil - default: - if !t.Probe() { - (t.Log()).Info("the probe is not ready, try again after some time") - time.Sleep(period) - continue - } - err := t.Run() - if err != nil { - (t.Log()).Error(err, "failed to run task") - time.Sleep(period) - continue - } - } - break - } - return nil -} - -// Periodic func is used to run a task periodically. -func Periodic(ctx context.Context, period time.Duration, t Task) error { - for { - select { - case <-ctx.Done(): - return nil - default: - err := t.Run() - if err != nil { - (t.Log()).Error(err, "failed to run task") - time.Sleep(time.Minute * 5) - continue - } - time.Sleep(period) - } - } -} - -func PeriodicWithProbe(ctx context.Context, period time.Duration, t Task) error { - for { - select { - case <-ctx.Done(): - return nil - default: - if !t.Probe() { - (t.Log()).Info("the probe is not ready, try again after some time") - time.Sleep(time.Minute * 10) - continue - } - err := t.Run() - if err != nil { - (t.Log()).Error(err, "failed to run task, try again after 5 minutes") - time.Sleep(time.Minute * 5) - continue - } - time.Sleep(period) - } - } -} - -// The TaskPool struct is used to build a task. -type TaskPool struct { - client.Client - ctx context.Context - options Options - tasks []*TaskInstance -} - -func NewTaskBuilder(ctx context.Context, client client.Client, options Options) *TaskPool { - return (&TaskPool{ - ctx: ctx, - options: options, - Client: client, - }).init() -} - -func (tb *TaskPool) init() *TaskPool { - for o := range tb.options.GetRunnableOptions().Policy { - tb.tasks = append(tb.tasks, &TaskInstance{ - name: o, - logger: ctrl.Log.WithName(string(o)), - ctx: tb.ctx, - policy: tb.options.GetRunnableOptions().Policy[o], - period: tb.options.GetRunnableOptions().Period[o], - Client: tb.Client, - probe: ProbeFor(o), - }) - } - return tb -} - -// The TaskInstance struct is used to store the task information. -type TaskInstance struct { - client.Client - name task - logger logr.Logger - ctx context.Context - policy string - period time.Duration - probe []Probe -} - -var _ manager.Runnable = &TaskInstance{} -var _ Task = &TaskInstance{} - -func (ti *TaskInstance) Start(ctx context.Context) error { - switch ti.policy { - case "Once": - return Once(ctx, ti.period, ti) - case "OnceWithProbe": - return OnceWithProbe(ctx, ti.period, ti) - case "Periodic": - return Periodic(ctx, ti.period, ti) - case "PeriodicWithProbe": - return PeriodicWithProbe(ctx, ti.period, ti) - default: - return fmt.Errorf("the policy is not supported") - } -} - -func (ti *TaskInstance) Run() error { - switch ti.name { - case Init: - return NewInitTask(GetOptionsReadOnly()).initWork(ti) - case Notice: - return NewNotice().noticeWork(ti) - case NoticeCleanup: - return NewNoticeCleaner().cleanWork(ti) - case Collector: - return NewCollect(GetOptionsReadOnly()).collectWork(ti) - case DataSync: - return NewDataSync().sync(ti) - case NetWorkConfig: - return NewNetworkConfig().probe(ti) - case Register: - return NewRegister().register(ti) - case MemoryCleanup: - return NewMemoryCleaner().cleanWork(ti) - default: - return fmt.Errorf("the task is not supported") - // allow developers to add their own runnable task - } -} - -func (ti *TaskInstance) Log() *logr.Logger { - return &ti.logger -} - -func (ti *TaskInstance) Probe() bool { - if len(ti.probe) == 0 { - return false - } - for _, p := range ti.probe { - if !p.Probe() { - return false - } - } - return true -} diff --git a/controllers/licenseissuer/internal/controller/util/util.go b/controllers/licenseissuer/internal/controller/util/util.go deleted file mode 100644 index 5577b27f798..00000000000 --- a/controllers/licenseissuer/internal/controller/util/util.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "encoding/json" - "errors" - - corev1 "k8s.io/api/core/v1" -) - -func GetConfigFromConfigMap(expectName string, - configMap *corev1.ConfigMap) (map[string]string, error) { - if configMap.Name != expectName { - err := errors.New("not expected configmap") - return nil, err - } - var res map[string]string - err := json.Unmarshal([]byte(configMap.Data["config.json"]), &res) - if err != nil { - return nil, err - } - return res, nil -} - -func IsConfigMapChanged(expect map[string]string, cm *corev1.ConfigMap) bool { - var changed bool - var configMapJSON map[string]string - if err := json.Unmarshal([]byte(cm.Data["config.json"]), &configMapJSON); err != nil { - return false - } - for key, value := range expect { - if cmValue, ok := cm.Data[key]; !ok || cmValue != value { - configMapJSON[key] = value - changed = true - } - } - if changed { - updatedJSON, err := json.Marshal(configMapJSON) - if err != nil { - panic(err) - } - cm.Data["config.json"] = string(updatedJSON) - } - return changed -} diff --git a/controllers/licenseissuer/launcher/main.go b/controllers/licenseissuer/launcher/main.go deleted file mode 100644 index bc251aad8cc..00000000000 --- a/controllers/licenseissuer/launcher/main.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "os" - "os/exec" - "sync" - - "github.com/labring/sealos/controllers/pkg/utils/logger" -) - -func main() { - launch("/preset", "/manager") -} - -func run(path string) error { - // nosemgrep: go.lang.security.audit.dangerous-exec-command.dangerous-exec-command - cmd := exec.Command(path) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} - -func launch(path ...string) { - var wg sync.WaitGroup - for _, p := range path { - wg.Add(1) - go func(p string) { - defer wg.Done() - if err := run(p); err != nil { - logger.Error(err, "Failed to run "+p) - } - }(p) - } - wg.Wait() -} diff --git a/controllers/licenseissuer/preset/main.go b/controllers/licenseissuer/preset/main.go deleted file mode 100644 index 4e7ad5f7e92..00000000000 --- a/controllers/licenseissuer/preset/main.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "context" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "fmt" - "os" - "time" - - "github.com/google/uuid" - "github.com/labring/sealos/controllers/licenseissuer/internal/controller/util" - "github.com/labring/sealos/controllers/pkg/utils/logger" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - mongoOptions "go.mongodb.org/mongo-driver/mongo/options" -) - -const MaxRetryForConnectDB = 10 - -func main() { - var err error - options := util.GetOptions() - err = presetRootUser(context.Background(), options) - if err != nil { - logger.Error(err, "Failed to preset root user") - return - } - logger.Info("Preset root user successfully") -} - -const ( - // pre-defined user name and password - defaultUser = "admin" - defaultPassword = "sealos2023" - - // kubernetes default user cr is admin - // it is corresponding to the root account - defaultK8sUser = "admin" -) - -type K8sUser struct { - Name string `bson:"name" json:"name"` -} - -// the following code is the struct of user stored in mongoDB. -type User struct { - UID string `bson:"uid" json:"uid"` - Name string `bson:"name" json:"name"` - PasswordUser string `bson:"password_user" json:"password_user"` - Password string `bson:"password" json:"password"` - CreatedTime string `bson:"created_time" json:"created_time"` - K8sUsers []K8sUser `bson:"k8s_users" json:"k8s_users"` -} - -func newUser(uid, name, passwordUser, password, k8sUser string) User { - return User{ - UID: uid, - Name: name, - PasswordUser: passwordUser, - Password: password, - // to iso string - CreatedTime: time.Now().Format(time.RFC3339), - K8sUsers: []K8sUser{ - { - Name: k8sUser, - }, - }, - } -} - -func presetRootUser(ctx context.Context, o util.Options) error { - // init mongoDB client - client, err := initMongoDB(ctx, o) - if err != nil { - return fmt.Errorf("failed to init mongoDB: %w", err) - } - defer func() { - err := client.Disconnect(ctx) - if err != nil { - logger.Error(err, "failed to disconnect mongoDB") - } - }() - - // preset root user - uuid := uuid.New().String() - passwd := hashPassword(defaultPassword, o.GetEnvOptions().SaltKey) - user := newUser(uuid, defaultUser, defaultUser, passwd, defaultK8sUser) - userDB := o.GetDBOptions().MongoOptions.UserDB - userCol := o.GetDBOptions().MongoOptions.UserCol - collection := client.Database(userDB).Collection(userCol) - - // check if the user already exists - isExists := preCheck(ctx, collection) - if isExists { - logger.Info("root user already exists") - return nil - } - // insert root user - insertResult, err := collection.InsertOne(context.Background(), user) - if err != nil { - logger.Error(err, "failed to insert root user") - return err - } - logger.Info("insert root user successfully", "insertResult", insertResult) - return nil -} - -func initMongoDB(ctx context.Context, o util.Options) (*mongo.Client, error) { - var client *mongo.Client - var err error - MongoURI := o.GetEnvOptions().MongoURI - clientOptions := mongoOptions.Client().ApplyURI(MongoURI) - for i := 0; i < MaxRetryForConnectDB; i++ { - client, err = mongo.Connect(ctx, clientOptions) - if err != nil { - logger.Error(err, "failed to connect to mongo") - time.Sleep(5 * time.Second) - continue - } - err = client.Ping(ctx, nil) - if err != nil { - logger.Error(err, "failed to ping mongo") - time.Sleep(5 * time.Second) - continue - } - logger.Info("connect to mongo successfully") - break - } - if err != nil { - return nil, fmt.Errorf("failed to connect to mongo: %w", err) - } - return client, nil -} - -// makesure the user does not exist -func preCheck(ctx context.Context, collection *mongo.Collection) bool { - filter := bson.M{"password_user": defaultUser} - var existingUser User - err := collection.FindOne(ctx, filter).Decode(&existingUser) - return err == nil -} - -// the following code is consistent with the front-end login logic -func hashPassword(password string, key string) string { - hash := sha256.New() - validSalt, err := decodeBase64(key) - if err != nil { - logger.Error(err, "Failed to decode salt") - os.Exit(1) - } - hash.Write([]byte(password + string(validSalt))) - return hex.EncodeToString(hash.Sum(nil)) -} - -func decodeBase64(s string) ([]byte, error) { - data, err := base64.StdEncoding.DecodeString(s) - if err != nil { - logger.Error(err, "Failed to decode base64") - return nil, err - } - return data, nil -} diff --git a/go.work b/go.work index bfbe890f469..ce10e478b46 100644 --- a/go.work +++ b/go.work @@ -7,7 +7,7 @@ use ( ./controllers/app ./controllers/db/adminer ./controllers/db/bytebase - ./controllers/licenseissuer + ./controllers/license ./controllers/terminal ./controllers/node ./controllers/user From 6f04ec1524f26327a61ddd7000e0a71a0c147105 Mon Sep 17 00:00:00 2001 From: yy Date: Thu, 12 Oct 2023 19:06:24 +0800 Subject: [PATCH 2/5] add more logic. --- controllers/license/Dockerfile | 34 +- controllers/license/cmd/manager/main.go | 2 +- .../crd/bases/license.sealos.io_licenses.yaml | 9 +- .../license/config/manager/kustomization.yaml | 6 + controllers/license/config/rbac/role.yaml | 1 + controllers/license/deploy/kubefile | 0 .../license/deploy/manifests/deploy.yaml | 378 ++++++++++++++++++ .../internal/controller/license_controller.go | 26 +- .../internal/controller/license_validator.go | 22 + .../internal/controller/util/license.go | 3 - controllers/license/internal/util/account.go | 3 + controllers/license/internal/util/database.go | 6 + controllers/license/internal/util/license.go | 1 + 13 files changed, 451 insertions(+), 40 deletions(-) create mode 100644 controllers/license/deploy/kubefile create mode 100644 controllers/license/deploy/manifests/deploy.yaml create mode 100644 controllers/license/internal/controller/license_validator.go delete mode 100644 controllers/license/internal/controller/util/license.go create mode 100644 controllers/license/internal/util/account.go create mode 100644 controllers/license/internal/util/database.go create mode 100644 controllers/license/internal/util/license.go diff --git a/controllers/license/Dockerfile b/controllers/license/Dockerfile index c389c0981af..c82354f221f 100644 --- a/controllers/license/Dockerfile +++ b/controllers/license/Dockerfile @@ -1,33 +1,11 @@ -# Build the manager binary -FROM golang:1.20 as builder -ARG TARGETOS +FROM gcr.io/distroless/static:nonroot ARG TARGETARCH -WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download - -# Copy the go source -COPY cmd/main.go cmd/main.go -COPY api/ api/ -COPY internal/controller/ internal/controller/ - -# Build -# the GOARCH has not a default value to allow the binary be built according to the host where the command -# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO -# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, -# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go - -# Use distroless as minimal base image to package the manager binary -# Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM gcr.io/distroless/static:nonroot WORKDIR / -COPY --from=builder /workspace/manager . USER 65532:65532 -ENTRYPOINT ["/manager"] +COPY bin/controller-licenseissuer-$TARGETARCH /manager +COPY bin/preset-$TARGETARCH /preset +COPY bin/launcher-$TARGETARCH /launcher + +ENTRYPOINT ["/launcher"] \ No newline at end of file diff --git a/controllers/license/cmd/manager/main.go b/controllers/license/cmd/manager/main.go index c75ba6301ce..6669b87dd58 100644 --- a/controllers/license/cmd/manager/main.go +++ b/controllers/license/cmd/manager/main.go @@ -53,7 +53,7 @@ func main() { var enableLeaderElection bool var probeAddr string - // TODO add more flags here + // TODO add more flags here such as mongo uri, billing type, etc... flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") diff --git a/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml index bdb336e8569..ceca7c93b46 100644 --- a/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml +++ b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml @@ -3,7 +3,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: licenses.license.sealos.io spec: group: license.sealos.io @@ -55,3 +56,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/controllers/license/config/manager/kustomization.yaml b/controllers/license/config/manager/kustomization.yaml index 5c5f0b84cba..4ef792a3a94 100644 --- a/controllers/license/config/manager/kustomization.yaml +++ b/controllers/license/config/manager/kustomization.yaml @@ -1,2 +1,8 @@ resources: - manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: ghcr.io/labring/sealos-license-controller + newTag: latest diff --git a/controllers/license/config/rbac/role.yaml b/controllers/license/config/rbac/role.yaml index 43b234b4508..54a00a4689e 100644 --- a/controllers/license/config/rbac/role.yaml +++ b/controllers/license/config/rbac/role.yaml @@ -2,6 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + creationTimestamp: null name: manager-role rules: - apiGroups: diff --git a/controllers/license/deploy/kubefile b/controllers/license/deploy/kubefile new file mode 100644 index 00000000000..e69de29bb2d diff --git a/controllers/license/deploy/manifests/deploy.yaml b/controllers/license/deploy/manifests/deploy.yaml new file mode 100644 index 00000000000..feb3d4823c4 --- /dev/null +++ b/controllers/license/deploy/manifests/deploy.yaml @@ -0,0 +1,378 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: system + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: namespace + app.kubernetes.io/part-of: license + control-plane: controller-manager + name: license-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: licenses.license.sealos.io +spec: + group: license.sealos.io + names: + kind: License + listKind: LicenseList + plural: licenses + singular: license + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: License is the Schema for the licenses API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: LicenseSpec defines the desired state of License + properties: + key: + type: string + token: + type: string + type: + enum: + - Account + - Cluster + type: string + type: object + status: + description: LicenseStatus defines the observed state of License + properties: + phase: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: controller-manager-sa + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: license + name: license-controller-manager + namespace: license-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: role + app.kubernetes.io/part-of: license + name: license-leader-election-role + namespace: license-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: license-manager-role +rules: +- apiGroups: + - license.sealos.io + resources: + - licenses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - license.sealos.io + resources: + - licenses/finalizers + verbs: + - update +- apiGroups: + - license.sealos.io + resources: + - licenses/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: metrics-reader + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: license + name: license-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: proxy-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: license + name: license-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: rolebinding + app.kubernetes.io/part-of: license + name: license-leader-election-rolebinding + namespace: license-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: license-leader-election-role +subjects: +- kind: ServiceAccount + name: license-controller-manager + namespace: license-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: license + name: license-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: license-manager-role +subjects: +- kind: ServiceAccount + name: license-controller-manager + namespace: license-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: proxy-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: license + name: license-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: license-proxy-role +subjects: +- kind: ServiceAccount + name: license-controller-manager + namespace: license-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: controller-manager-metrics-service + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: service + app.kubernetes.io/part-of: license + control-plane: controller-manager + name: license-controller-manager-metrics-service + namespace: license-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: license + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: deployment + app.kubernetes.io/part-of: license + control-plane: controller-manager + name: license-controller-manager + namespace: license-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: ghcr.io/labring/sealos-license-controller:latest + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + securityContext: + runAsNonRoot: true + serviceAccountName: license-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/controllers/license/internal/controller/license_controller.go b/controllers/license/internal/controller/license_controller.go index 45a76b72358..3554448e766 100644 --- a/controllers/license/internal/controller/license_controller.go +++ b/controllers/license/internal/controller/license_controller.go @@ -26,7 +26,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/predicate" ) // LicenseReconciler reconciles a License object @@ -35,6 +37,8 @@ type LicenseReconciler struct { Scheme *runtime.Scheme Logger logr.Logger finalizer *ctrlsdk.Finalizer + + validator *LicenseValidator } // +kubebuilder:rbac:groups=license.sealos.io,resources=licenses,verbs=get;list;watch;create;update;patch;delete @@ -50,7 +54,9 @@ func (r *LicenseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, client.IgnoreNotFound(err) } + // on delete reconcile, do nothing but remove finalizer and log if ok, err := r.finalizer.RemoveFinalizer(ctx, license, func(ctx context.Context, obj client.Object) error { + r.Logger.V(1).Info("reconcile for license delete") return nil }); ok { return ctrl.Result{}, err @@ -65,19 +71,25 @@ func (r *LicenseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, errors.New("reconcile error from Finalizer") } -// TODO do real reconcile - func (r *LicenseReconciler) reconcile(ctx context.Context, license *licensev1.License) (ctrl.Result, error) { - // TODO check license and do something + r.Logger.V(1).Info("reconcile for license", "license", license.Namespace+"/"+license.Name) + return ctrl.Result{}, nil } // SetupWithManager sets up the controller with the Manager. func (r *LicenseReconciler) SetupWithManager(mgr ctrl.Manager) error { - // TODO set controller by mgr - // TODO add predictor - // TODO set logger and finalizer + r.Logger = mgr.GetLogger().WithName("controller").WithName("License") + r.finalizer = ctrlsdk.NewFinalizer(r.Client, "license.sealos.io/finalizer") + r.Client = mgr.GetClient() + + // TODO fix this + r.validator = &LicenseValidator{ + Client: r.Client, + } + + // reconcile on generation change return ctrl.NewControllerManagedBy(mgr). - For(&licensev1.License{}). + For(&licensev1.License{}, builder.WithPredicates(predicate.And(predicate.GenerationChangedPredicate{}))). Complete(r) } diff --git a/controllers/license/internal/controller/license_validator.go b/controllers/license/internal/controller/license_validator.go new file mode 100644 index 00000000000..9c3ee5e0dc9 --- /dev/null +++ b/controllers/license/internal/controller/license_validator.go @@ -0,0 +1,22 @@ +package controller + +import ( + licensev1 "github.com/labring/sealos/controllers/license/api/v1" + "github.com/labring/sealos/controllers/license/internal/util" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type LicenseValidator struct { + // maybe you need more or less information to validate license, add/delete if you need + client.Client + db *util.DataBase +} + +func (v *LicenseValidator) Validate(license licensev1.License) (bool, error) { + // TODO validate license + // step1: check if license type matches license mode (P2) + // step2: check if license token and key is valid (P1) + // step3: check if license token and key already been used (P1) + return true, nil +} diff --git a/controllers/license/internal/controller/util/license.go b/controllers/license/internal/controller/util/license.go deleted file mode 100644 index 6acc4337446..00000000000 --- a/controllers/license/internal/controller/util/license.go +++ /dev/null @@ -1,3 +0,0 @@ -package util - -// TODO add check license func diff --git a/controllers/license/internal/util/account.go b/controllers/license/internal/util/account.go new file mode 100644 index 00000000000..dccd7af7a38 --- /dev/null +++ b/controllers/license/internal/util/account.go @@ -0,0 +1,3 @@ +package util + +// TODO add recharge func diff --git a/controllers/license/internal/util/database.go b/controllers/license/internal/util/database.go new file mode 100644 index 00000000000..14c5f9c65ec --- /dev/null +++ b/controllers/license/internal/util/database.go @@ -0,0 +1,6 @@ +package util + +// TODO fix this + +type DataBase interface { +} diff --git a/controllers/license/internal/util/license.go b/controllers/license/internal/util/license.go new file mode 100644 index 00000000000..c7d868219f5 --- /dev/null +++ b/controllers/license/internal/util/license.go @@ -0,0 +1 @@ +package util From cb84e27974b8bc6c8646733879f133f20b0d09f0 Mon Sep 17 00:00:00 2001 From: yy Date: Thu, 12 Oct 2023 19:07:36 +0800 Subject: [PATCH 3/5] fix docker ignore file --- controllers/license/.dockerignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/license/.dockerignore b/controllers/license/.dockerignore index a3aab7af70c..8e6fac709b6 100644 --- a/controllers/license/.dockerignore +++ b/controllers/license/.dockerignore @@ -1,3 +1,3 @@ # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file # Ignore build and test binaries. -bin/ +testbin/ From 66783aac4ac56ebf061186ef2431d8582fcb4ab4 Mon Sep 17 00:00:00 2001 From: yy Date: Thu, 12 Oct 2023 19:26:58 +0800 Subject: [PATCH 4/5] add recorder interface --- controllers/license/api/v1/license_types.go | 4 +- .../internal/controller/license_controller.go | 42 +++++++++++++++++++ .../internal/controller/license_recorder.go | 23 ++++++++++ .../internal/controller/license_validator.go | 1 - 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 controllers/license/internal/controller/license_recorder.go diff --git a/controllers/license/api/v1/license_types.go b/controllers/license/api/v1/license_types.go index 40396fa1e97..f9258c4abf5 100644 --- a/controllers/license/api/v1/license_types.go +++ b/controllers/license/api/v1/license_types.go @@ -39,11 +39,13 @@ type LicenseStatusPhase string const ( LicenseStatusPhasePending LicenseStatusPhase = "Pending" - LicenseStatusPhaseSuccess LicenseStatusPhase = "Active" + LicenseStatusPhaseFailed LicenseStatusPhase = "Failed" + LicenseStatusPhaseActive LicenseStatusPhase = "Active" ) // LicenseStatus defines the observed state of License type LicenseStatus struct { + // +kubebuilder:validation:Enum=Pending;Failed;Active:default=Pending Phase LicenseStatusPhase `json:"phase,omitempty"` } diff --git a/controllers/license/internal/controller/license_controller.go b/controllers/license/internal/controller/license_controller.go index 3554448e766..3f4e0fd2a88 100644 --- a/controllers/license/internal/controller/license_controller.go +++ b/controllers/license/internal/controller/license_controller.go @@ -39,6 +39,7 @@ type LicenseReconciler struct { finalizer *ctrlsdk.Finalizer validator *LicenseValidator + recorder *LicenseRecorder } // +kubebuilder:rbac:groups=license.sealos.io,resources=licenses,verbs=get;list;watch;create;update;patch;delete @@ -74,6 +75,42 @@ func (r *LicenseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct func (r *LicenseReconciler) reconcile(ctx context.Context, license *licensev1.License) (ctrl.Result, error) { r.Logger.V(1).Info("reconcile for license", "license", license.Namespace+"/"+license.Name) + // TODO fix logic and make it more readable + + validate, err := r.validator.Validate(*license) + if err != nil { + return ctrl.Result{}, err + } + + _, found, err := r.recorder.Get(*license) + if err != nil { + return ctrl.Result{}, err + } + + if !validate && !found { + r.Logger.V(1).Info("license is invalid", "license", license.Namespace+"/"+license.Name) + + // Update license status to failed + license.Status.Phase = licensev1.LicenseStatusPhaseFailed + _ = r.Status().Update(ctx, license) + } else { + r.Logger.V(1).Info("license is valid", "license", license.Namespace+"/"+license.Name) + // TODO do something after license validated and license is active + + // charge account or update cluster license based on license type + switch license.Spec.Type { + case licensev1.AccountLicenseType: + // TODO charge account + case licensev1.ClusterLicenseType: + // TODO update cluster license + } + + // record license token and key to database to prevent reuse + + // update license status to active + license.Status.Phase = licensev1.LicenseStatusPhaseActive + _ = r.Status().Update(ctx, license) + } return ctrl.Result{}, nil } @@ -88,6 +125,11 @@ func (r *LicenseReconciler) SetupWithManager(mgr ctrl.Manager) error { Client: r.Client, } + // TODO fix this + r.recorder = &LicenseRecorder{ + Client: r.Client, + } + // reconcile on generation change return ctrl.NewControllerManagedBy(mgr). For(&licensev1.License{}, builder.WithPredicates(predicate.And(predicate.GenerationChangedPredicate{}))). diff --git a/controllers/license/internal/controller/license_recorder.go b/controllers/license/internal/controller/license_recorder.go new file mode 100644 index 00000000000..b522d794c12 --- /dev/null +++ b/controllers/license/internal/controller/license_recorder.go @@ -0,0 +1,23 @@ +package controller + +import ( + licensev1 "github.com/labring/sealos/controllers/license/api/v1" + "github.com/labring/sealos/controllers/license/internal/util" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type LicenseRecorder struct { + // maybe you need more or less information to record license, add/delete if you need + client.Client + db *util.DataBase +} + +// TODO fix this + +func (r *LicenseRecorder) Store(license licensev1.License) error { + return nil +} + +func (r *LicenseRecorder) Get(license licensev1.License) (licensev1.License, bool, error) { + return licensev1.License{}, false, nil +} diff --git a/controllers/license/internal/controller/license_validator.go b/controllers/license/internal/controller/license_validator.go index 9c3ee5e0dc9..e1c6ea3d40c 100644 --- a/controllers/license/internal/controller/license_validator.go +++ b/controllers/license/internal/controller/license_validator.go @@ -17,6 +17,5 @@ func (v *LicenseValidator) Validate(license licensev1.License) (bool, error) { // TODO validate license // step1: check if license type matches license mode (P2) // step2: check if license token and key is valid (P1) - // step3: check if license token and key already been used (P1) return true, nil } From d02dc1335cc3a9e327844fc336ef1d110cb4c118 Mon Sep 17 00:00:00 2001 From: yy Date: Thu, 12 Oct 2023 19:40:59 +0800 Subject: [PATCH 5/5] fix api --- controllers/license/api/v1/license_types.go | 3 ++- .../license/config/crd/bases/license.sealos.io_licenses.yaml | 5 +++++ controllers/license/deploy/manifests/deploy.yaml | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/controllers/license/api/v1/license_types.go b/controllers/license/api/v1/license_types.go index f9258c4abf5..7fb17dca3af 100644 --- a/controllers/license/api/v1/license_types.go +++ b/controllers/license/api/v1/license_types.go @@ -45,7 +45,8 @@ const ( // LicenseStatus defines the observed state of License type LicenseStatus struct { - // +kubebuilder:validation:Enum=Pending;Failed;Active:default=Pending + //+kubebuilder:validation:Enum=Pending;Failed;Active + //+kubebuilder:default=Pending Phase LicenseStatusPhase `json:"phase,omitempty"` } diff --git a/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml index ceca7c93b46..34457287eff 100644 --- a/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml +++ b/controllers/license/config/crd/bases/license.sealos.io_licenses.yaml @@ -49,6 +49,11 @@ spec: description: LicenseStatus defines the observed state of License properties: phase: + default: Pending + enum: + - Pending + - Failed + - Active type: string type: object type: object diff --git a/controllers/license/deploy/manifests/deploy.yaml b/controllers/license/deploy/manifests/deploy.yaml index feb3d4823c4..22b5d40e585 100644 --- a/controllers/license/deploy/manifests/deploy.yaml +++ b/controllers/license/deploy/manifests/deploy.yaml @@ -61,6 +61,11 @@ spec: description: LicenseStatus defines the observed state of License properties: phase: + default: Pending + enum: + - Pending + - Failed + - Active type: string type: object type: object