From c600991f36f524e394ad21b09cceefe1fa163589 Mon Sep 17 00:00:00 2001 From: chaosi-zju Date: Sat, 20 Apr 2024 21:12:28 +0800 Subject: [PATCH] Introduce a new API named WorkloadRebalancer to support rescheduling. Signed-off-by: chaosi-zju --- api/openapi-spec/swagger.json | 1013 +++++++++++++++++ .../apps.karmada.io_workloadrebalancers.yaml | 118 ++ charts/karmada/_crds/kustomization.yaml | 1 + charts/karmada/templates/post-delete-job.yaml | 3 + .../karmada/templates/post-install-job.yaml | 5 + charts/karmada/templates/pre-install-job.yaml | 22 +- .../app/controllermanager.go | 14 + hack/.import-aliases | 1 + hack/tools/swagger/generateswagger.go | 6 + hack/update-codegen.sh | 17 +- hack/update-crdgen.sh | 1 + pkg/apis/apps/v1alpha1/doc.go | 21 + .../apps/v1alpha1/workloadrebalancer_types.go | 133 +++ .../apps/v1alpha1/zz_generated.deepcopy.go | 162 +++ .../apps/v1alpha1/zz_generated.register.go | 67 ++ .../workloadrebalancer_controller.go | 200 ++++ .../clientset/versioned/clientset.go | 13 + pkg/generated/clientset/versioned/doc.go | 4 - .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../typed/apps/v1alpha1/apps_client.go | 107 ++ .../versioned/typed/apps/v1alpha1/doc.go | 20 + .../versioned/typed/apps/v1alpha1/fake/doc.go | 20 + .../apps/v1alpha1/fake/fake_apps_client.go | 40 + .../v1alpha1/fake/fake_workloadrebalancer.go | 132 +++ .../apps/v1alpha1/generated_expansion.go | 21 + .../typed/apps/v1alpha1/workloadrebalancer.go | 184 +++ .../externalversions/apps/interface.go | 46 + .../apps/v1alpha1/interface.go | 45 + .../apps/v1alpha1/workloadrebalancer.go | 89 ++ .../informers/externalversions/factory.go | 6 + .../informers/externalversions/generic.go | 13 +- .../apps/v1alpha1/expansion_generated.go | 23 + .../apps/v1alpha1/workloadrebalancer.go | 68 ++ pkg/generated/openapi/zz_generated.openapi.go | 247 ++++ pkg/util/apigroup.go | 2 + pkg/util/gclient/gclient.go | 4 +- 38 files changed, 2866 insertions(+), 13 deletions(-) create mode 100644 charts/karmada/_crds/bases/apps/apps.karmada.io_workloadrebalancers.yaml create mode 100644 pkg/apis/apps/v1alpha1/doc.go create mode 100644 pkg/apis/apps/v1alpha1/workloadrebalancer_types.go create mode 100644 pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go create mode 100644 pkg/apis/apps/v1alpha1/zz_generated.register.go create mode 100644 pkg/controllers/workloadrebalancer/workloadrebalancer_controller.go delete mode 100644 pkg/generated/clientset/versioned/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/apps_client.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_workloadrebalancer.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go create mode 100644 pkg/generated/clientset/versioned/typed/apps/v1alpha1/workloadrebalancer.go create mode 100644 pkg/generated/informers/externalversions/apps/interface.go create mode 100644 pkg/generated/informers/externalversions/apps/v1alpha1/interface.go create mode 100644 pkg/generated/informers/externalversions/apps/v1alpha1/workloadrebalancer.go create mode 100644 pkg/generated/listers/apps/v1alpha1/expansion_generated.go create mode 100644 pkg/generated/listers/apps/v1alpha1/workloadrebalancer.go mode change 100755 => 100644 pkg/generated/openapi/zz_generated.openapi.go diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index c89b825101bb..b9895932d7ad 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -40,6 +40,852 @@ } } }, + "/apis/apps.karmada.io/": { + "get": { + "description": "get information of a group", + "consumes": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo" + ], + "operationId": "getAppsKarmadaIoAPIGroup", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup" + } + } + } + } + }, + "/apis/apps.karmada.io/v1alpha1/": { + "get": { + "description": "get available resources", + "consumes": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "getAppsKarmadaIoV1alpha1APIResources", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" + } + } + } + } + }, + "/apis/apps.karmada.io/v1alpha1/watch/workloadrebalancers": { + "get": { + "description": "watch individual changes to a list of WorkloadRebalancer. deprecated: use the 'watch' parameter with a list operation instead.", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "watchAppsKarmadaIoV1alpha1WorkloadRebalancerList", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "x-kubernetes-action": "watchlist", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/pretty-nN7o5FEq" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/apps.karmada.io/v1alpha1/watch/workloadrebalancers/{name}": { + "get": { + "description": "watch changes to an object of kind WorkloadRebalancer. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "watchAppsKarmadaIoV1alpha1WorkloadRebalancer", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" + } + } + }, + "x-kubernetes-action": "watch", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "uniqueItems": true, + "type": "string", + "description": "name of the WorkloadRebalancer", + "name": "name", + "in": "path", + "required": true + }, + { + "$ref": "#/parameters/pretty-nN7o5FEq" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ] + }, + "/apis/apps.karmada.io/v1alpha1/workloadrebalancers": { + "get": { + "description": "list or watch objects of kind WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf", + "application/json;stream=watch", + "application/vnd.kubernetes.protobuf;stream=watch" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "listAppsKarmadaIoV1alpha1WorkloadRebalancer", + "parameters": [ + { + "$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + }, + { + "$ref": "#/parameters/watch-XNNPZGbK" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerList" + } + } + }, + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "post": { + "description": "create a WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "createAppsKarmadaIoV1alpha1WorkloadRebalancer", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "uniqueItems": true, + "type": "string", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "name": "fieldValidation", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "delete": { + "description": "delete collection of WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "deleteAppsKarmadaIoV1alpha1CollectionWorkloadRebalancer", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "$ref": "#/parameters/continue-QfD61s0i" + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldSelector-xIcQKXFG" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/labelSelector-5Zw57w4C" + }, + { + "$ref": "#/parameters/limit-1NfNmdNH" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + }, + { + "$ref": "#/parameters/resourceVersion-5WAnf1kx" + }, + { + "$ref": "#/parameters/resourceVersionMatch-t8XhRHeC" + }, + { + "$ref": "#/parameters/sendInitialEvents-rLXlEK_k" + }, + { + "$ref": "#/parameters/timeoutSeconds-yvYezaOC" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "parameters": [ + { + "$ref": "#/parameters/pretty-nN7o5FEq" + } + ] + }, + "/apis/apps.karmada.io/v1alpha1/workloadrebalancers/{name}": { + "get": { + "description": "read the specified WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "readAppsKarmadaIoV1alpha1WorkloadRebalancer", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "put": { + "description": "replace the specified WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "replaceAppsKarmadaIoV1alpha1WorkloadRebalancer", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "uniqueItems": true, + "type": "string", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "name": "fieldValidation", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "delete": { + "description": "delete a WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "deleteAppsKarmadaIoV1alpha1WorkloadRebalancer", + "parameters": [ + { + "$ref": "#/parameters/body-2Y1dVQaQ" + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" + }, + { + "$ref": "#/parameters/orphanDependents-uRB25kX5" + }, + { + "$ref": "#/parameters/propagationPolicy-6jk3prlO" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "patch": { + "description": "partially update the specified WorkloadRebalancer", + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "patchAppsKarmadaIoV1alpha1WorkloadRebalancer", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "uniqueItems": true, + "type": "string", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "name": "fieldValidation", + "in": "query" + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "parameters": [ + { + "uniqueItems": true, + "type": "string", + "description": "name of the WorkloadRebalancer", + "name": "name", + "in": "path", + "required": true + }, + { + "$ref": "#/parameters/pretty-nN7o5FEq" + } + ] + }, + "/apis/apps.karmada.io/v1alpha1/workloadrebalancers/{name}/status": { + "get": { + "description": "read status of the specified WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "readAppsKarmadaIoV1alpha1WorkloadRebalancerStatus", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "put": { + "description": "replace status of the specified WorkloadRebalancer", + "consumes": [ + "*/*" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "replaceAppsKarmadaIoV1alpha1WorkloadRebalancerStatus", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldManager-Qy4HdaTW" + }, + { + "uniqueItems": true, + "type": "string", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "name": "fieldValidation", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "patch": { + "description": "partially update status of the specified WorkloadRebalancer", + "consumes": [ + "application/json-patch+json", + "application/merge-patch+json", + "application/strategic-merge-patch+json", + "application/apply-patch+yaml" + ], + "produces": [ + "application/json", + "application/yaml", + "application/vnd.kubernetes.protobuf" + ], + "schemes": [ + "https" + ], + "tags": [ + "appsKarmadaIo_v1alpha1" + ], + "operationId": "patchAppsKarmadaIoV1alpha1WorkloadRebalancerStatus", + "parameters": [ + { + "$ref": "#/parameters/body-78PwaGsr" + }, + { + "uniqueItems": true, + "type": "string", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "name": "dryRun", + "in": "query" + }, + { + "$ref": "#/parameters/fieldManager-7c6nTn1T" + }, + { + "uniqueItems": true, + "type": "string", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "name": "fieldValidation", + "in": "query" + }, + { + "$ref": "#/parameters/force-tOGGb0Yi" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + } + }, + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "apps.karmada.io", + "version": "v1alpha1", + "kind": "WorkloadRebalancer" + } + }, + "parameters": [ + { + "uniqueItems": true, + "type": "string", + "description": "name of the WorkloadRebalancer", + "name": "name", + "in": "path", + "required": true + }, + { + "$ref": "#/parameters/pretty-nN7o5FEq" + } + ] + }, "/apis/autoscaling.karmada.io/": { "get": { "description": "get information of a group", @@ -15780,6 +16626,163 @@ } }, "definitions": { + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.ObjectReference": { + "description": "ObjectReference the expected resource.", + "type": "object", + "required": [ + "apiVersion", + "kind", + "name" + ], + "properties": { + "apiVersion": { + "description": "APIVersion represents the API version of the target resource.", + "type": "string", + "default": "" + }, + "kind": { + "description": "Kind represents the Kind of the target resource.", + "type": "string", + "default": "" + }, + "name": { + "description": "Name of the target resource.", + "type": "string", + "default": "" + }, + "namespace": { + "description": "Namespace of the target resource. Default is empty, which means it is a non-namespacescoped resource.", + "type": "string" + } + } + }, + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.ObservedWorkload": { + "description": "ObservedWorkload the observed resource.", + "type": "object", + "required": [ + "workload" + ], + "properties": { + "reason": { + "description": "Reason represents a machine-readable description of why this resource rebalanced failed.", + "type": "string" + }, + "result": { + "description": "Result the observed rebalance result of resource.", + "type": "string" + }, + "workload": { + "description": "Workload the observed resource.", + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.ObjectReference" + } + } + }, + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer": { + "description": "WorkloadRebalancer represents the desired behavior and status of a job which can enforces a resource rebalance.", + "type": "object", + "required": [ + "spec" + ], + "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": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "description": "Spec represents the specification of the desired behavior of WorkloadRebalancer.", + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerSpec" + }, + "status": { + "description": "Status represents the status of WorkloadRebalancer.", + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerStatus" + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "apps.karmada.io", + "kind": "WorkloadRebalancer", + "version": "v1alpha1" + } + ] + }, + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerList": { + "description": "WorkloadRebalancerList contains a list of WorkloadRebalancer", + "type": "object", + "required": [ + "items" + ], + "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" + }, + "items": { + "description": "Items holds a list of WorkloadRebalancer.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancer" + } + }, + "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": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "apps.karmada.io", + "kind": "WorkloadRebalancerList", + "version": "v1alpha1" + } + ] + }, + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerSpec": { + "description": "WorkloadRebalancerSpec represents the specification of the desired behavior of Reschedule.", + "type": "object", + "required": [ + "workloads" + ], + "properties": { + "workloads": { + "description": "Workloads used to specify the list of expected resource. Nil or empty list is not allowed.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.ObjectReference" + } + } + } + }, + "com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.WorkloadRebalancerStatus": { + "description": "WorkloadRebalancerStatus contains information about the current status of a WorkloadRebalancer updated periodically by schedule trigger controller.", + "type": "object", + "properties": { + "observedWorkloads": { + "description": "ObservedWorkloads contains information about the execution states and messages of target resources.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.karmada-io.karmada.pkg.apis.apps.v1alpha1.ObservedWorkload" + } + } + } + }, "com.github.karmada-io.karmada.pkg.apis.autoscaling.v1alpha1.CronFederatedHPA": { "description": "CronFederatedHPA represents a collection of repeating schedule to scale replica number of a specific workload. It can scale any resource implementing the scale subresource as well as FederatedHPA.", "type": "object", @@ -20600,6 +21603,11 @@ "kind": "DeleteOptions", "version": "v1beta2" }, + { + "group": "apps.karmada.io", + "kind": "DeleteOptions", + "version": "v1alpha1" + }, { "group": "authentication.k8s.io", "kind": "DeleteOptions", @@ -21344,6 +22352,11 @@ "kind": "WatchEvent", "version": "v1beta2" }, + { + "group": "apps.karmada.io", + "kind": "WatchEvent", + "version": "v1alpha1" + }, { "group": "authentication.k8s.io", "kind": "WatchEvent", diff --git a/charts/karmada/_crds/bases/apps/apps.karmada.io_workloadrebalancers.yaml b/charts/karmada/_crds/bases/apps/apps.karmada.io_workloadrebalancers.yaml new file mode 100644 index 000000000000..511924d4539d --- /dev/null +++ b/charts/karmada/_crds/bases/apps/apps.karmada.io_workloadrebalancers.yaml @@ -0,0 +1,118 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: workloadrebalancers.apps.karmada.io +spec: + group: apps.karmada.io + names: + kind: WorkloadRebalancer + listKind: WorkloadRebalancerList + plural: workloadrebalancers + singular: workloadrebalancer + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: WorkloadRebalancer represents the desired behavior and status + of a job which can enforces a resource rebalance. + 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: Spec represents the specification of the desired behavior + of WorkloadRebalancer. + properties: + workloads: + description: Workloads used to specify the list of expected resource. + Nil or empty list is not allowed. + items: + description: ObjectReference the expected resource. + properties: + apiVersion: + description: APIVersion represents the API version of the target + resource. + type: string + kind: + description: Kind represents the Kind of the target resource. + type: string + name: + description: Name of the target resource. + type: string + namespace: + description: Namespace of the target resource. Default is empty, + which means it is a non-namespacescoped resource. + type: string + required: + - apiVersion + - kind + - name + type: object + minItems: 1 + type: array + required: + - workloads + type: object + status: + description: Status represents the status of WorkloadRebalancer. + properties: + observedWorkloads: + description: ObservedWorkloads contains information about the execution + states and messages of target resources. + items: + description: ObservedWorkload the observed resource. + properties: + reason: + description: Reason represents a machine-readable description + of why this resource rebalanced failed. + type: string + result: + description: Result the observed rebalance result of resource. + type: string + workload: + description: Workload the observed resource. + properties: + apiVersion: + description: APIVersion represents the API version of the + target resource. + type: string + kind: + description: Kind represents the Kind of the target resource. + type: string + name: + description: Name of the target resource. + type: string + namespace: + description: Namespace of the target resource. Default is + empty, which means it is a non-namespacescoped resource. + type: string + required: + - apiVersion + - kind + - name + type: object + required: + - workload + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/karmada/_crds/kustomization.yaml b/charts/karmada/_crds/kustomization.yaml index 9275edc84014..3ca202a6a989 100644 --- a/charts/karmada/_crds/kustomization.yaml +++ b/charts/karmada/_crds/kustomization.yaml @@ -16,6 +16,7 @@ resources: - bases/autoscaling/autoscaling.karmada.io_federatedhpas.yaml - bases/autoscaling/autoscaling.karmada.io_cronfederatedhpas.yaml - bases/remedy/remedy.karmada.io_remedies.yaml +- bases/apps/apps.karmada.io_workloadrebalancers.yaml patchesStrategicMerge: - patches/webhook_in_resourcebindings.yaml diff --git a/charts/karmada/templates/post-delete-job.yaml b/charts/karmada/templates/post-delete-job.yaml index e4d5f13e4eae..699c38ac66b2 100644 --- a/charts/karmada/templates/post-delete-job.yaml +++ b/charts/karmada/templates/post-delete-job.yaml @@ -97,4 +97,7 @@ spec: - name: crds-work-base configMap: name: {{ $name }}-crds-work-bases-config + - name: crds-apps-base + configMap: + name: {{ $name }}-crds-apps-bases-config {{- end }} diff --git a/charts/karmada/templates/post-install-job.yaml b/charts/karmada/templates/post-install-job.yaml index 3627127165bc..c14a43079fa7 100644 --- a/charts/karmada/templates/post-install-job.yaml +++ b/charts/karmada/templates/post-install-job.yaml @@ -71,6 +71,8 @@ spec: mountPath: /crds/bases/remedy - name: {{ $name }}-crds-work-bases mountPath: /crds/bases/work + - name: {{ $name }}-crds-apps-bases + mountPath: /crds/bases/apps - name: {{ $name }}-static-resources mountPath: /static-resources {{ include "karmada.kubeconfig.volumeMount" . | nindent 10 }} @@ -102,6 +104,9 @@ spec: - name: {{ $name }}-crds-work-bases configMap: name: {{ $name }}-crds-work-bases + - name: {{ $name }}-crds-apps-bases + configMap: + name: {{ $name }}-crds-apps-bases - name: {{ $name }}-static-resources configMap: name: {{ $name }}-static-resources diff --git a/charts/karmada/templates/pre-install-job.yaml b/charts/karmada/templates/pre-install-job.yaml index d1f182d62f02..fad895ea1854 100644 --- a/charts/karmada/templates/pre-install-job.yaml +++ b/charts/karmada/templates/pre-install-job.yaml @@ -161,7 +161,27 @@ data: {{- (printf "%s: " $name) | nindent 6 }} |- {{- $.Files.Get $path | nindent 8 }} {{ end }} - + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $name }}-crds-apps-bases + namespace: {{ $namespace }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-weight": "2" + {{- if "karmada.preInstallJob.labels" }} + labels: + {{- include "karmada.preInstallJob.labels" . | nindent 4 }} + {{- end }} +data: + {{ range $path, $bytes := .Files.Glob (printf "_crds/bases/apps/**")}} + {{ $name := base $path }} + {{- (printf "%s: " $name) | nindent 6 }} |- + {{- $.Files.Get $path | nindent 8 }} + {{ end }} + {{- if eq .Values.certs.mode "custom" }} --- apiVersion: v1 diff --git a/cmd/controller-manager/app/controllermanager.go b/cmd/controller-manager/app/controllermanager.go index f4d40727e8d3..12498841d4f6 100644 --- a/cmd/controller-manager/app/controllermanager.go +++ b/cmd/controller-manager/app/controllermanager.go @@ -69,6 +69,7 @@ import ( "github.com/karmada-io/karmada/pkg/controllers/remediation" "github.com/karmada-io/karmada/pkg/controllers/status" "github.com/karmada-io/karmada/pkg/controllers/unifiedauth" + "github.com/karmada-io/karmada/pkg/controllers/workloadrebalancer" "github.com/karmada-io/karmada/pkg/dependenciesdistributor" "github.com/karmada-io/karmada/pkg/detector" "github.com/karmada-io/karmada/pkg/features" @@ -232,6 +233,7 @@ func init() { controllers["endpointsliceCollect"] = startEndpointSliceCollectController controllers["endpointsliceDispatch"] = startEndpointSliceDispatchController controllers["remedy"] = startRemedyController + controllers["workloadRebalancer"] = startWorkloadRebalancerController } func startClusterController(ctx controllerscontext.Context) (enabled bool, err error) { @@ -707,6 +709,18 @@ func startRemedyController(ctx controllerscontext.Context) (enabled bool, err er return true, nil } +func startWorkloadRebalancerController(ctx controllerscontext.Context) (enabled bool, err error) { + workloadRebalancer := workloadrebalancer.RebalancerController{ + Client: ctx.Mgr.GetClient(), + } + err = workloadRebalancer.SetupWithManager(ctx.Mgr) + if err != nil { + return false, err + } + + return true, nil +} + // setupControllers initialize controllers and setup one by one. func setupControllers(mgr controllerruntime.Manager, opts *options.Options, stopChan <-chan struct{}) { restConfig := mgr.GetConfig() diff --git a/hack/.import-aliases b/hack/.import-aliases index a73df6e40ada..b99344a4b13d 100644 --- a/hack/.import-aliases +++ b/hack/.import-aliases @@ -60,5 +60,6 @@ "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1": "workv1alpha1", "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2": "workv1alpha2", "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1": "autoscalingv1alpha1", + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1": "appsv1alpha1", "github.com/karmada-io/karmada/operator/pkg/apis/operator/v1alpha1": "operatorv1alpha1" } diff --git a/hack/tools/swagger/generateswagger.go b/hack/tools/swagger/generateswagger.go index 243ddee2ae8d..d83d7e589348 100644 --- a/hack/tools/swagger/generateswagger.go +++ b/hack/tools/swagger/generateswagger.go @@ -26,6 +26,7 @@ import ( "k8s.io/kube-openapi/pkg/validation/spec" "github.com/karmada-io/karmada/hack/tools/swagger/lib" + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" @@ -112,6 +113,10 @@ func main() { remedyv1alpha1.SchemeGroupVersion.WithResource(remedyv1alpha1.ResourcePluralRemedy), remedyv1alpha1.SchemeGroupVersion.WithResource(remedyv1alpha1.ResourceSingularRemedy), meta.RESTScopeRoot) + mapper.AddSpecific(appsv1alpha1.SchemeGroupVersion.WithKind(appsv1alpha1.ResourceKindWorkloadRebalancer), + appsv1alpha1.SchemeGroupVersion.WithResource(appsv1alpha1.ResourcePluralWorkloadRebalancer), + appsv1alpha1.SchemeGroupVersion.WithResource(appsv1alpha1.ResourceSingularWorkloadRebalancer), meta.RESTScopeRoot) + spec, err := lib.RenderOpenAPISpec(lib.Config{ Info: spec.InfoProps{ Title: "Karmada OpenAPI", @@ -145,6 +150,7 @@ func main() { {GVR: autoscalingv1alpha1.SchemeGroupVersion.WithResource(autoscalingv1alpha1.ResourcePluralFederatedHPA), NamespaceScoped: autoscalingv1alpha1.ResourceNamespaceScopedFederatedHPA}, {GVR: autoscalingv1alpha1.SchemeGroupVersion.WithResource(autoscalingv1alpha1.ResourcePluralCronFederatedHPA), NamespaceScoped: autoscalingv1alpha1.ResourceNamespaceScopedCronFederatedHPA}, {GVR: remedyv1alpha1.SchemeGroupVersion.WithResource(remedyv1alpha1.ResourcePluralRemedy), NamespaceScoped: remedyv1alpha1.ResourceNamespaceScopedRemedy}, + {GVR: appsv1alpha1.SchemeGroupVersion.WithResource(appsv1alpha1.ResourcePluralWorkloadRebalancer), NamespaceScoped: appsv1alpha1.ResourceNamespaceScopedWorkloadRebalancer}, }, Mapper: mapper, }) diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 490fb7e39251..9fb316ff56e6 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -110,6 +110,11 @@ deepcopy-gen \ --input-dirs=github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ --output-package=github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ --output-file-base=zz_generated.deepcopy +deepcopy-gen \ + --go-header-file hack/boilerplate/boilerplate.go.txt \ + --input-dirs=github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ + --output-package=github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ + --output-file-base=zz_generated.deepcopy echo "Generating with register-gen" register-gen \ @@ -167,6 +172,11 @@ register-gen \ --input-dirs=github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ --output-package=github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ --output-file-base=zz_generated.register +register-gen \ + --go-header-file hack/boilerplate/boilerplate.go.txt \ + --input-dirs=github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ + --output-package=github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ + --output-file-base=zz_generated.register echo "Generating with conversion-gen" conversion-gen \ @@ -184,7 +194,7 @@ echo "Generating with client-gen" client-gen \ --go-header-file hack/boilerplate/boilerplate.go.txt \ --input-base="" \ - --input=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ + --input=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ --output-package=github.com/karmada-io/karmada/pkg/generated/clientset \ --clientset-name=versioned client-gen \ @@ -197,7 +207,7 @@ client-gen \ echo "Generating with lister-gen" lister-gen \ --go-header-file hack/boilerplate/boilerplate.go.txt \ - --input-dirs=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ + --input-dirs=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ --output-package=github.com/karmada-io/karmada/pkg/generated/listers lister-gen \ --go-header-file hack/boilerplate/boilerplate.go.txt \ @@ -207,7 +217,7 @@ lister-gen \ echo "Generating with informer-gen" informer-gen \ --go-header-file hack/boilerplate/boilerplate.go.txt \ - --input-dirs=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1 \ + --input-dirs=github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1,github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha1,github.com/karmada-io/karmada/pkg/apis/work/v1alpha2,github.com/karmada-io/karmada/pkg/apis/config/v1alpha1,github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1,github.com/karmada-io/karmada/pkg/apis/search/v1alpha1,github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1,github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1,github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1 \ --versioned-clientset-package=github.com/karmada-io/karmada/pkg/generated/clientset/versioned \ --listers-package=github.com/karmada-io/karmada/pkg/generated/listers \ --output-package=github.com/karmada-io/karmada/pkg/generated/informers @@ -229,6 +239,7 @@ openapi-gen \ --input-dirs "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" \ --input-dirs "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" \ --input-dirs "github.com/karmada-io/karmada/pkg/apis/remedy/v1alpha1" \ + --input-dirs "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" \ --input-dirs "k8s.io/api/core/v1,k8s.io/apimachinery/pkg/api/resource" \ --input-dirs "k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/runtime,k8s.io/apimachinery/pkg/version" \ --input-dirs "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,k8s.io/api/admissionregistration/v1,k8s.io/api/networking/v1" \ diff --git a/hack/update-crdgen.sh b/hack/update-crdgen.sh index 984d4b0b1087..1b396a3adb20 100755 --- a/hack/update-crdgen.sh +++ b/hack/update-crdgen.sh @@ -33,6 +33,7 @@ controller-gen crd paths=./pkg/apis/networking/... output:crd:dir=./charts/karma controller-gen crd paths=./pkg/apis/policy/... output:crd:dir=./charts/karmada/_crds/bases/policy controller-gen crd paths=./pkg/apis/remedy/... output:crd:dir=./charts/karmada/_crds/bases/remedy controller-gen crd paths=./pkg/apis/work/... output:crd:dir=./charts/karmada/_crds/bases/work +controller-gen crd paths=./pkg/apis/apps/... output:crd:dir=./charts/karmada/_crds/bases/apps controller-gen crd:generateEmbeddedObjectMeta=true paths=./examples/customresourceinterpreter/apis/... output:crd:dir=./examples/customresourceinterpreter/apis/ controller-gen crd:generateEmbeddedObjectMeta=true paths=./operator/pkg/apis/operator/... output:crd:dir=./charts/karmada-operator/crds controller-gen crd:generateEmbeddedObjectMeta=true paths=./operator/pkg/apis/operator/... output:crd:dir=./operator/config/crds diff --git a/pkg/apis/apps/v1alpha1/doc.go b/pkg/apis/apps/v1alpha1/doc.go new file mode 100644 index 000000000000..0232db603b14 --- /dev/null +++ b/pkg/apis/apps/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 The Karmada Authors. + +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 v1alpha1 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package,register +// +k8s:openapi-gen=true +// +groupName=apps.karmada.io +package v1alpha1 diff --git a/pkg/apis/apps/v1alpha1/workloadrebalancer_types.go b/pkg/apis/apps/v1alpha1/workloadrebalancer_types.go new file mode 100644 index 000000000000..42554865f9b6 --- /dev/null +++ b/pkg/apis/apps/v1alpha1/workloadrebalancer_types.go @@ -0,0 +1,133 @@ +/* +Copyright 2024 The Karmada Authors. + +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 v1alpha1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +const ( + // ResourceKindWorkloadRebalancer is kind name of WorkloadRebalancer. + ResourceKindWorkloadRebalancer = "WorkloadRebalancer" + // ResourceSingularWorkloadRebalancer is singular name of WorkloadRebalancer. + ResourceSingularWorkloadRebalancer = "workloadrebalancer" + // ResourcePluralWorkloadRebalancer is kind plural name of WorkloadRebalancer. + ResourcePluralWorkloadRebalancer = "workloadrebalancers" + // ResourceNamespaceScopedWorkloadRebalancer indicates if WorkloadRebalancer is NamespaceScoped. + ResourceNamespaceScopedWorkloadRebalancer = false +) + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:resource:path=workloadrebalancers,scope="Cluster" +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkloadRebalancer represents the desired behavior and status of a job which can enforces a resource rebalance. +type WorkloadRebalancer struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec represents the specification of the desired behavior of WorkloadRebalancer. + // +required + Spec WorkloadRebalancerSpec `json:"spec"` + + // Status represents the status of WorkloadRebalancer. + // +optional + Status WorkloadRebalancerStatus `json:"status,omitempty"` +} + +// WorkloadRebalancerSpec represents the specification of the desired behavior of Reschedule. +type WorkloadRebalancerSpec struct { + // Workloads used to specify the list of expected resource. + // Nil or empty list is not allowed. + // +kubebuilder:validation:MinItems=1 + // +required + Workloads []ObjectReference `json:"workloads"` +} + +// ObjectReference the expected resource. +type ObjectReference struct { + // APIVersion represents the API version of the target resource. + // +required + APIVersion string `json:"apiVersion"` + + // Kind represents the Kind of the target resource. + // +required + Kind string `json:"kind"` + + // Name of the target resource. + // +required + Name string `json:"name"` + + // Namespace of the target resource. + // Default is empty, which means it is a non-namespacescoped resource. + // +optional + Namespace string `json:"namespace,omitempty"` +} + +// WorkloadRebalancerStatus contains information about the current status of a WorkloadRebalancer +// updated periodically by schedule trigger controller. +type WorkloadRebalancerStatus struct { + // ObservedWorkloads contains information about the execution states and messages of target resources. + // +optional + ObservedWorkloads []ObservedWorkload `json:"observedWorkloads,omitempty"` +} + +// ObservedWorkload the observed resource. +type ObservedWorkload struct { + // Workload the observed resource. + // +required + Workload ObjectReference `json:"workload"` + + // Result the observed rebalance result of resource. + // +optional + Result RebalanceResult `json:"result,omitempty"` + + // Reason represents a machine-readable description of why this resource rebalanced failed. + // +optional + Reason RebalanceFailedReason `json:"reason,omitempty"` +} + +// RebalanceResult the specific extent to which the resource has been rebalanced +type RebalanceResult string + +const ( + // RebalanceFailed the resource has been rebalance failed. + RebalanceFailed RebalanceResult = "Failed" + // RebalanceSuccessful the resource has been successfully rebalanced. + RebalanceSuccessful RebalanceResult = "Successful" +) + +// RebalanceFailedReason represents a machine-readable description of why this resource rebalanced failed. +type RebalanceFailedReason string + +const ( + // RebalanceObjectNotFound the resource referenced binding not found. + RebalanceObjectNotFound RebalanceFailedReason = "NotFound" +) + +// +kubebuilder:resource:scope="Cluster" +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkloadRebalancerList contains a list of WorkloadRebalancer +type WorkloadRebalancerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + // Items holds a list of WorkloadRebalancer. + Items []WorkloadRebalancer `json:"items"` +} diff --git a/pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000000..04953a1cf84c --- /dev/null +++ b/pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,162 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +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 *ObjectReference) DeepCopyInto(out *ObjectReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectReference. +func (in *ObjectReference) DeepCopy() *ObjectReference { + if in == nil { + return nil + } + out := new(ObjectReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObservedWorkload) DeepCopyInto(out *ObservedWorkload) { + *out = *in + out.Workload = in.Workload + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObservedWorkload. +func (in *ObservedWorkload) DeepCopy() *ObservedWorkload { + if in == nil { + return nil + } + out := new(ObservedWorkload) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadRebalancer) DeepCopyInto(out *WorkloadRebalancer) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadRebalancer. +func (in *WorkloadRebalancer) DeepCopy() *WorkloadRebalancer { + if in == nil { + return nil + } + out := new(WorkloadRebalancer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkloadRebalancer) 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 *WorkloadRebalancerList) DeepCopyInto(out *WorkloadRebalancerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]WorkloadRebalancer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadRebalancerList. +func (in *WorkloadRebalancerList) DeepCopy() *WorkloadRebalancerList { + if in == nil { + return nil + } + out := new(WorkloadRebalancerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkloadRebalancerList) 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 *WorkloadRebalancerSpec) DeepCopyInto(out *WorkloadRebalancerSpec) { + *out = *in + if in.Workloads != nil { + in, out := &in.Workloads, &out.Workloads + *out = make([]ObjectReference, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadRebalancerSpec. +func (in *WorkloadRebalancerSpec) DeepCopy() *WorkloadRebalancerSpec { + if in == nil { + return nil + } + out := new(WorkloadRebalancerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadRebalancerStatus) DeepCopyInto(out *WorkloadRebalancerStatus) { + *out = *in + if in.ObservedWorkloads != nil { + in, out := &in.ObservedWorkloads, &out.ObservedWorkloads + *out = make([]ObservedWorkload, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadRebalancerStatus. +func (in *WorkloadRebalancerStatus) DeepCopy() *WorkloadRebalancerStatus { + if in == nil { + return nil + } + out := new(WorkloadRebalancerStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/apps/v1alpha1/zz_generated.register.go b/pkg/apis/apps/v1alpha1/zz_generated.register.go new file mode 100644 index 000000000000..a97f75390e21 --- /dev/null +++ b/pkg/apis/apps/v1alpha1/zz_generated.register.go @@ -0,0 +1,67 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by register-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName specifies the group name used to register the objects. +const GroupName = "apps.karmada.io" + +// GroupVersion specifies the group and the version used to register the objects. +var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// SchemeGroupVersion is group version used to register these objects +// Deprecated: use GroupVersion instead. +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + // Depreciated: use Install instead + AddToScheme = localSchemeBuilder.AddToScheme + Install = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &WorkloadRebalancer{}, + &WorkloadRebalancerList{}, + ) + // AddToGroupVersion allows the serialization of client types like ListOptions. + v1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/controllers/workloadrebalancer/workloadrebalancer_controller.go b/pkg/controllers/workloadrebalancer/workloadrebalancer_controller.go new file mode 100644 index 000000000000..1f33c6edd28d --- /dev/null +++ b/pkg/controllers/workloadrebalancer/workloadrebalancer_controller.go @@ -0,0 +1,200 @@ +/* +Copyright 2024 The Karmada Authors. + +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 workloadrebalancer + +import ( + "context" + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" + "k8s.io/klog/v2" + controllerruntime "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" + + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2" + "github.com/karmada-io/karmada/pkg/util/names" +) + +const ( + // ControllerName is the controller name that will be used when reporting events. + ControllerName = "workload-rebalancer" +) + +// RebalancerController is to handle a rebalance to workloads selected by WorkloadRebalancer object. +type RebalancerController struct { + Client client.Client +} + +// SetupWithManager creates a controller and register to controller manager. +func (c *RebalancerController) SetupWithManager(mgr controllerruntime.Manager) error { + var predicateFunc = predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { return true }, + UpdateFunc: func(e event.UpdateEvent) bool { return false }, + DeleteFunc: func(event.DeleteEvent) bool { return false }, + GenericFunc: func(event.GenericEvent) bool { return false }, + } + + return controllerruntime.NewControllerManagedBy(mgr). + Named(ControllerName). + For(&appsv1alpha1.WorkloadRebalancer{}, builder.WithPredicates(predicateFunc)). + Complete(c) +} + +// Reconcile performs a full reconciliation for the object referred to by the Request. +// The Controller will requeue the Request to be processed again if an error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (c *RebalancerController) Reconcile(ctx context.Context, req controllerruntime.Request) (controllerruntime.Result, error) { + klog.V(4).Infof("Reconciling for WorkloadRebalancer %s", req.Name) + + // 1. get latest WorkloadRebalancer + rebalancer := &appsv1alpha1.WorkloadRebalancer{} + if err := c.Client.Get(ctx, req.NamespacedName, rebalancer); err != nil { + if apierrors.IsNotFound(err) { + klog.Infof("no need to reconcile WorkloadRebalancer for it not found") + return controllerruntime.Result{}, nil + } + return controllerruntime.Result{}, err + } + + // 2. get and update referenced binding to trigger a rescheduling + newStatus, successNum, retryNum := c.doWorkloadRebalance(ctx, rebalancer) + + // 3. update status of WorkloadRebalancer + if err := c.updateWorkloadRebalancerStatus(rebalancer, newStatus); err != nil { + return controllerruntime.Result{}, err + } + klog.Infof("Finish handling WorkloadRebalancer (%s), %d/%d resource success in all, while %d resource need retry", + rebalancer.Name, successNum, len(newStatus.ObservedWorkloads), retryNum) + + if retryNum > 0 { + return controllerruntime.Result{}, fmt.Errorf("%d resource reschedule triggered failed and need retry", retryNum) + } + return controllerruntime.Result{}, nil +} + +func (c *RebalancerController) buildWorkloadRebalancerStatus(rebalancer *appsv1alpha1.WorkloadRebalancer) appsv1alpha1.WorkloadRebalancerStatus { + resourceList := make([]appsv1alpha1.ObservedWorkload, 0) + for _, resource := range rebalancer.Spec.Workloads { + resourceList = append(resourceList, appsv1alpha1.ObservedWorkload{ + Workload: resource, + }) + } + return appsv1alpha1.WorkloadRebalancerStatus{ + ObservedWorkloads: resourceList, + } +} + +func (c *RebalancerController) doWorkloadRebalance(ctx context.Context, rebalancer *appsv1alpha1.WorkloadRebalancer) ( + newStatus appsv1alpha1.WorkloadRebalancerStatus, successNum int64, retryNum int64) { + // get previous status and update basing on it + newStatus = rebalancer.Status + if len(newStatus.ObservedWorkloads) == 0 { + newStatus = c.buildWorkloadRebalancerStatus(rebalancer) + } + + successNum, retryNum = int64(0), int64(0) + for i, resource := range newStatus.ObservedWorkloads { + if resource.Result == appsv1alpha1.RebalanceSuccessful { + successNum++ + continue + } + if resource.Result == appsv1alpha1.RebalanceFailed && resource.Reason == appsv1alpha1.RebalanceObjectNotFound { + continue + } + + bindingName := names.GenerateBindingName(resource.Workload.Kind, resource.Workload.Name) + // resource with empty namespace represents it is a cluster wide resource. + if resource.Workload.Namespace != "" { + binding := &workv1alpha2.ResourceBinding{} + if err := c.Client.Get(ctx, client.ObjectKey{Namespace: resource.Workload.Namespace, Name: bindingName}, binding); err != nil { + klog.Errorf("get binding failed: %+v", err) + c.recordWorkloadRebalanceFailed(&newStatus.ObservedWorkloads[i], &retryNum, err) + continue + } + // update spec.rescheduleTriggeredAt of referenced fetchTargetRefBindings to trigger a rescheduling + if c.needTriggerReschedule(rebalancer.CreationTimestamp, binding.Spec.RescheduleTriggeredAt) { + binding.Spec.RescheduleTriggeredAt = &rebalancer.CreationTimestamp + + if err := c.Client.Update(ctx, binding); err != nil { + klog.Errorf("update binding failed: %+v", err) + c.recordWorkloadRebalanceFailed(&newStatus.ObservedWorkloads[i], &retryNum, err) + continue + } + } + c.recordWorkloadRebalanceSuccess(&newStatus.ObservedWorkloads[i], &successNum) + } else { + clusterbinding := &workv1alpha2.ClusterResourceBinding{} + if err := c.Client.Get(ctx, client.ObjectKey{Name: bindingName}, clusterbinding); err != nil { + klog.Errorf("get cluster binding failed: %+v", err) + c.recordWorkloadRebalanceFailed(&newStatus.ObservedWorkloads[i], &retryNum, err) + continue + } + // update spec.rescheduleTriggeredAt of referenced clusterbinding to trigger a rescheduling + if c.needTriggerReschedule(rebalancer.CreationTimestamp, clusterbinding.Spec.RescheduleTriggeredAt) { + clusterbinding.Spec.RescheduleTriggeredAt = &rebalancer.CreationTimestamp + + if err := c.Client.Update(ctx, clusterbinding); err != nil { + klog.Errorf("update cluster binding failed: %+v", err) + c.recordWorkloadRebalanceFailed(&newStatus.ObservedWorkloads[i], &retryNum, err) + continue + } + } + c.recordWorkloadRebalanceSuccess(&newStatus.ObservedWorkloads[i], &successNum) + } + } + return +} + +func (c *RebalancerController) needTriggerReschedule(creationTimestamp metav1.Time, rescheduleTriggeredAt *metav1.Time) bool { + return rescheduleTriggeredAt == nil || creationTimestamp.After(rescheduleTriggeredAt.Time) +} + +func (c *RebalancerController) recordWorkloadRebalanceSuccess(resource *appsv1alpha1.ObservedWorkload, successNum *int64) { + resource.Result = appsv1alpha1.RebalanceSuccessful + *successNum++ +} + +func (c *RebalancerController) recordWorkloadRebalanceFailed(resource *appsv1alpha1.ObservedWorkload, retryNum *int64, err error) { + resource.Result = appsv1alpha1.RebalanceFailed + reason := apierrors.ReasonForError(err) + if reason == metav1.StatusReasonNotFound { + resource.Reason = appsv1alpha1.RebalanceObjectNotFound + } else { + *retryNum++ + } +} + +func (c *RebalancerController) updateWorkloadRebalancerStatus(rebalancer *appsv1alpha1.WorkloadRebalancer, newStatus appsv1alpha1.WorkloadRebalancerStatus) error { + rebalancerPatch := client.MergeFrom(rebalancer) + rebalancerCopy := rebalancer.DeepCopy() + rebalancerCopy.Status = newStatus + + return retry.RetryOnConflict(retry.DefaultRetry, func() (err error) { + klog.V(4).Infof("Start to patch WorkloadRebalancer(%s) status", rebalancer.Name) + if err := c.Client.Status().Patch(context.TODO(), rebalancerCopy, rebalancerPatch); err != nil { + klog.Errorf("Failed to patch WorkloadRebalancer (%s) status, err: %+v", rebalancer.Name, err) + return err + } + return nil + }) +} diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index 4b8ac2dfad6d..8bb42accc5c7 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -22,6 +22,7 @@ import ( "fmt" "net/http" + appsv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/config/v1alpha1" @@ -38,6 +39,7 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface + AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface AutoscalingV1alpha1() autoscalingv1alpha1.AutoscalingV1alpha1Interface ClusterV1alpha1() clusterv1alpha1.ClusterV1alpha1Interface ConfigV1alpha1() configv1alpha1.ConfigV1alpha1Interface @@ -52,6 +54,7 @@ type Interface interface { // Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient + appsV1alpha1 *appsv1alpha1.AppsV1alpha1Client autoscalingV1alpha1 *autoscalingv1alpha1.AutoscalingV1alpha1Client clusterV1alpha1 *clusterv1alpha1.ClusterV1alpha1Client configV1alpha1 *configv1alpha1.ConfigV1alpha1Client @@ -63,6 +66,11 @@ type Clientset struct { workV1alpha2 *workv1alpha2.WorkV1alpha2Client } +// AppsV1alpha1 retrieves the AppsV1alpha1Client +func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface { + return c.appsV1alpha1 +} + // AutoscalingV1alpha1 retrieves the AutoscalingV1alpha1Client func (c *Clientset) AutoscalingV1alpha1() autoscalingv1alpha1.AutoscalingV1alpha1Interface { return c.autoscalingV1alpha1 @@ -152,6 +160,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, var cs Clientset var err error + cs.appsV1alpha1, err = appsv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.autoscalingV1alpha1, err = autoscalingv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -209,6 +221,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { // New creates a new Clientset for the given RESTClient. func New(c rest.Interface) *Clientset { var cs Clientset + cs.appsV1alpha1 = appsv1alpha1.New(c) cs.autoscalingV1alpha1 = autoscalingv1alpha1.New(c) cs.clusterV1alpha1 = clusterv1alpha1.New(c) cs.configV1alpha1 = configv1alpha1.New(c) diff --git a/pkg/generated/clientset/versioned/doc.go b/pkg/generated/clientset/versioned/doc.go deleted file mode 100644 index 0e0c2a8900e2..000000000000 --- a/pkg/generated/clientset/versioned/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. -package versioned diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go index 615977b708fa..daa063578783 100644 --- a/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -20,6 +20,8 @@ package fake import ( clientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" + appsv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/apps/v1alpha1" + fakeappsv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/autoscaling/v1alpha1" fakeautoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/autoscaling/v1alpha1/fake" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/cluster/v1alpha1" @@ -95,6 +97,11 @@ var ( _ testing.FakeClient = &Clientset{} ) +// AppsV1alpha1 retrieves the AppsV1alpha1Client +func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface { + return &fakeappsv1alpha1.FakeAppsV1alpha1{Fake: &c.Fake} +} + // AutoscalingV1alpha1 retrieves the AutoscalingV1alpha1Client func (c *Clientset) AutoscalingV1alpha1() autoscalingv1alpha1.AutoscalingV1alpha1Interface { return &fakeautoscalingv1alpha1.FakeAutoscalingV1alpha1{Fake: &c.Fake} diff --git a/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go index a89c6fe3c2da..4ea5a3e6bd9b 100644 --- a/pkg/generated/clientset/versioned/fake/register.go +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -19,6 +19,7 @@ limitations under the License. package fake import ( + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" @@ -39,6 +40,7 @@ var scheme = runtime.NewScheme() var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + appsv1alpha1.AddToScheme, autoscalingv1alpha1.AddToScheme, clusterv1alpha1.AddToScheme, configv1alpha1.AddToScheme, diff --git a/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go index e5d3cae1b722..042742612852 100644 --- a/pkg/generated/clientset/versioned/scheme/register.go +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -19,6 +19,7 @@ limitations under the License. package scheme import ( + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" @@ -39,6 +40,7 @@ var Scheme = runtime.NewScheme() var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + appsv1alpha1.AddToScheme, autoscalingv1alpha1.AddToScheme, clusterv1alpha1.AddToScheme, configv1alpha1.AddToScheme, diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/apps_client.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/apps_client.go new file mode 100644 index 000000000000..7a1e9e50eefa --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/apps_client.go @@ -0,0 +1,107 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type AppsV1alpha1Interface interface { + RESTClient() rest.Interface + WorkloadRebalancersGetter +} + +// AppsV1alpha1Client is used to interact with features provided by the apps.karmada.io group. +type AppsV1alpha1Client struct { + restClient rest.Interface +} + +func (c *AppsV1alpha1Client) WorkloadRebalancers() WorkloadRebalancerInterface { + return newWorkloadRebalancers(c) +} + +// NewForConfig creates a new AppsV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*AppsV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new AppsV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AppsV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &AppsV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new AppsV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AppsV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AppsV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *AppsV1alpha1Client { + return &AppsV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AppsV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/doc.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/doc.go new file mode 100644 index 000000000000..d7702a120bf6 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/doc.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/doc.go new file mode 100644 index 000000000000..3a0e6b07dfb0 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go new file mode 100644 index 000000000000..5fd59b7b4909 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_apps_client.go @@ -0,0 +1,40 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/typed/apps/v1alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeAppsV1alpha1 struct { + *testing.Fake +} + +func (c *FakeAppsV1alpha1) WorkloadRebalancers() v1alpha1.WorkloadRebalancerInterface { + return &FakeWorkloadRebalancers{c} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeAppsV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_workloadrebalancer.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_workloadrebalancer.go new file mode 100644 index 000000000000..21c94b19d343 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/fake/fake_workloadrebalancer.go @@ -0,0 +1,132 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeWorkloadRebalancers implements WorkloadRebalancerInterface +type FakeWorkloadRebalancers struct { + Fake *FakeAppsV1alpha1 +} + +var workloadrebalancersResource = v1alpha1.SchemeGroupVersion.WithResource("workloadrebalancers") + +var workloadrebalancersKind = v1alpha1.SchemeGroupVersion.WithKind("WorkloadRebalancer") + +// Get takes name of the workloadRebalancer, and returns the corresponding workloadRebalancer object, and an error if there is any. +func (c *FakeWorkloadRebalancers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(workloadrebalancersResource, name), &v1alpha1.WorkloadRebalancer{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.WorkloadRebalancer), err +} + +// List takes label and field selectors, and returns the list of WorkloadRebalancers that match those selectors. +func (c *FakeWorkloadRebalancers) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.WorkloadRebalancerList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(workloadrebalancersResource, workloadrebalancersKind, opts), &v1alpha1.WorkloadRebalancerList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.WorkloadRebalancerList{ListMeta: obj.(*v1alpha1.WorkloadRebalancerList).ListMeta} + for _, item := range obj.(*v1alpha1.WorkloadRebalancerList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested workloadRebalancers. +func (c *FakeWorkloadRebalancers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(workloadrebalancersResource, opts)) +} + +// Create takes the representation of a workloadRebalancer and creates it. Returns the server's representation of the workloadRebalancer, and an error, if there is any. +func (c *FakeWorkloadRebalancers) Create(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.CreateOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(workloadrebalancersResource, workloadRebalancer), &v1alpha1.WorkloadRebalancer{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.WorkloadRebalancer), err +} + +// Update takes the representation of a workloadRebalancer and updates it. Returns the server's representation of the workloadRebalancer, and an error, if there is any. +func (c *FakeWorkloadRebalancers) Update(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(workloadrebalancersResource, workloadRebalancer), &v1alpha1.WorkloadRebalancer{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.WorkloadRebalancer), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeWorkloadRebalancers) UpdateStatus(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (*v1alpha1.WorkloadRebalancer, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(workloadrebalancersResource, "status", workloadRebalancer), &v1alpha1.WorkloadRebalancer{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.WorkloadRebalancer), err +} + +// Delete takes name of the workloadRebalancer and deletes it. Returns an error if one occurs. +func (c *FakeWorkloadRebalancers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(workloadrebalancersResource, name, opts), &v1alpha1.WorkloadRebalancer{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeWorkloadRebalancers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(workloadrebalancersResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.WorkloadRebalancerList{}) + return err +} + +// Patch applies the patch and returns the patched workloadRebalancer. +func (c *FakeWorkloadRebalancers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WorkloadRebalancer, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(workloadrebalancersResource, name, pt, data, subresources...), &v1alpha1.WorkloadRebalancer{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.WorkloadRebalancer), err +} diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go new file mode 100644 index 000000000000..6a18fc43f2cd --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type WorkloadRebalancerExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/apps/v1alpha1/workloadrebalancer.go b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/workloadrebalancer.go new file mode 100644 index 000000000000..b0a317f965c8 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/apps/v1alpha1/workloadrebalancer.go @@ -0,0 +1,184 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + scheme "github.com/karmada-io/karmada/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// WorkloadRebalancersGetter has a method to return a WorkloadRebalancerInterface. +// A group's client should implement this interface. +type WorkloadRebalancersGetter interface { + WorkloadRebalancers() WorkloadRebalancerInterface +} + +// WorkloadRebalancerInterface has methods to work with WorkloadRebalancer resources. +type WorkloadRebalancerInterface interface { + Create(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.CreateOptions) (*v1alpha1.WorkloadRebalancer, error) + Update(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (*v1alpha1.WorkloadRebalancer, error) + UpdateStatus(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (*v1alpha1.WorkloadRebalancer, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.WorkloadRebalancer, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.WorkloadRebalancerList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WorkloadRebalancer, err error) + WorkloadRebalancerExpansion +} + +// workloadRebalancers implements WorkloadRebalancerInterface +type workloadRebalancers struct { + client rest.Interface +} + +// newWorkloadRebalancers returns a WorkloadRebalancers +func newWorkloadRebalancers(c *AppsV1alpha1Client) *workloadRebalancers { + return &workloadRebalancers{ + client: c.RESTClient(), + } +} + +// Get takes name of the workloadRebalancer, and returns the corresponding workloadRebalancer object, and an error if there is any. +func (c *workloadRebalancers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + result = &v1alpha1.WorkloadRebalancer{} + err = c.client.Get(). + Resource("workloadrebalancers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of WorkloadRebalancers that match those selectors. +func (c *workloadRebalancers) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.WorkloadRebalancerList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.WorkloadRebalancerList{} + err = c.client.Get(). + Resource("workloadrebalancers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested workloadRebalancers. +func (c *workloadRebalancers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("workloadrebalancers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a workloadRebalancer and creates it. Returns the server's representation of the workloadRebalancer, and an error, if there is any. +func (c *workloadRebalancers) Create(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.CreateOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + result = &v1alpha1.WorkloadRebalancer{} + err = c.client.Post(). + Resource("workloadrebalancers"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(workloadRebalancer). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a workloadRebalancer and updates it. Returns the server's representation of the workloadRebalancer, and an error, if there is any. +func (c *workloadRebalancers) Update(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + result = &v1alpha1.WorkloadRebalancer{} + err = c.client.Put(). + Resource("workloadrebalancers"). + Name(workloadRebalancer.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(workloadRebalancer). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *workloadRebalancers) UpdateStatus(ctx context.Context, workloadRebalancer *v1alpha1.WorkloadRebalancer, opts v1.UpdateOptions) (result *v1alpha1.WorkloadRebalancer, err error) { + result = &v1alpha1.WorkloadRebalancer{} + err = c.client.Put(). + Resource("workloadrebalancers"). + Name(workloadRebalancer.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(workloadRebalancer). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the workloadRebalancer and deletes it. Returns an error if one occurs. +func (c *workloadRebalancers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("workloadrebalancers"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *workloadRebalancers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("workloadrebalancers"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched workloadRebalancer. +func (c *workloadRebalancers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.WorkloadRebalancer, err error) { + result = &v1alpha1.WorkloadRebalancer{} + err = c.client.Patch(pt). + Resource("workloadrebalancers"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/informers/externalversions/apps/interface.go b/pkg/generated/informers/externalversions/apps/interface.go new file mode 100644 index 000000000000..d04cd8301f67 --- /dev/null +++ b/pkg/generated/informers/externalversions/apps/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package apps + +import ( + v1alpha1 "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/apps/v1alpha1" + internalinterfaces "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/generated/informers/externalversions/apps/v1alpha1/interface.go b/pkg/generated/informers/externalversions/apps/v1alpha1/interface.go new file mode 100644 index 000000000000..6869b7cafa78 --- /dev/null +++ b/pkg/generated/informers/externalversions/apps/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // WorkloadRebalancers returns a WorkloadRebalancerInformer. + WorkloadRebalancers() WorkloadRebalancerInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// WorkloadRebalancers returns a WorkloadRebalancerInformer. +func (v *version) WorkloadRebalancers() WorkloadRebalancerInformer { + return &workloadRebalancerInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/informers/externalversions/apps/v1alpha1/workloadrebalancer.go b/pkg/generated/informers/externalversions/apps/v1alpha1/workloadrebalancer.go new file mode 100644 index 000000000000..7128df60fa1e --- /dev/null +++ b/pkg/generated/informers/externalversions/apps/v1alpha1/workloadrebalancer.go @@ -0,0 +1,89 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + versioned "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" + internalinterfaces "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/karmada-io/karmada/pkg/generated/listers/apps/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// WorkloadRebalancerInformer provides access to a shared informer and lister for +// WorkloadRebalancers. +type WorkloadRebalancerInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.WorkloadRebalancerLister +} + +type workloadRebalancerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewWorkloadRebalancerInformer constructs a new informer for WorkloadRebalancer type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewWorkloadRebalancerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredWorkloadRebalancerInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredWorkloadRebalancerInformer constructs a new informer for WorkloadRebalancer type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredWorkloadRebalancerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1alpha1().WorkloadRebalancers().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1alpha1().WorkloadRebalancers().Watch(context.TODO(), options) + }, + }, + &appsv1alpha1.WorkloadRebalancer{}, + resyncPeriod, + indexers, + ) +} + +func (f *workloadRebalancerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredWorkloadRebalancerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *workloadRebalancerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1alpha1.WorkloadRebalancer{}, f.defaultInformer) +} + +func (f *workloadRebalancerInformer) Lister() v1alpha1.WorkloadRebalancerLister { + return v1alpha1.NewWorkloadRebalancerLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/factory.go b/pkg/generated/informers/externalversions/factory.go index fb3feb1f23bc..f656f030fcdc 100644 --- a/pkg/generated/informers/externalversions/factory.go +++ b/pkg/generated/informers/externalversions/factory.go @@ -24,6 +24,7 @@ import ( time "time" versioned "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" + apps "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/apps" autoscaling "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/autoscaling" cluster "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/cluster" config "github.com/karmada-io/karmada/pkg/generated/informers/externalversions/config" @@ -250,6 +251,7 @@ type SharedInformerFactory interface { // client. InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Apps() apps.Interface Autoscaling() autoscaling.Interface Cluster() cluster.Interface Config() config.Interface @@ -260,6 +262,10 @@ type SharedInformerFactory interface { Work() work.Interface } +func (f *sharedInformerFactory) Apps() apps.Interface { + return apps.New(f, f.namespace, f.tweakListOptions) +} + func (f *sharedInformerFactory) Autoscaling() autoscaling.Interface { return autoscaling.New(f, f.namespace, f.tweakListOptions) } diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index db1d70ed164c..0793b637e0b3 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -21,7 +21,8 @@ package externalversions import ( "fmt" - v1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" networkingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/networking/v1alpha1" @@ -60,10 +61,14 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=autoscaling.karmada.io, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("cronfederatedhpas"): + // Group=apps.karmada.io, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("workloadrebalancers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1alpha1().WorkloadRebalancers().Informer()}, nil + + // Group=autoscaling.karmada.io, Version=v1alpha1 + case autoscalingv1alpha1.SchemeGroupVersion.WithResource("cronfederatedhpas"): return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V1alpha1().CronFederatedHPAs().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("federatedhpas"): + case autoscalingv1alpha1.SchemeGroupVersion.WithResource("federatedhpas"): return &genericInformer{resource: resource.GroupResource(), informer: f.Autoscaling().V1alpha1().FederatedHPAs().Informer()}, nil // Group=cluster.karmada.io, Version=v1alpha1 diff --git a/pkg/generated/listers/apps/v1alpha1/expansion_generated.go b/pkg/generated/listers/apps/v1alpha1/expansion_generated.go new file mode 100644 index 000000000000..9b7a454a4341 --- /dev/null +++ b/pkg/generated/listers/apps/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// WorkloadRebalancerListerExpansion allows custom methods to be added to +// WorkloadRebalancerLister. +type WorkloadRebalancerListerExpansion interface{} diff --git a/pkg/generated/listers/apps/v1alpha1/workloadrebalancer.go b/pkg/generated/listers/apps/v1alpha1/workloadrebalancer.go new file mode 100644 index 000000000000..b75ec7773347 --- /dev/null +++ b/pkg/generated/listers/apps/v1alpha1/workloadrebalancer.go @@ -0,0 +1,68 @@ +/* +Copyright The Karmada Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// WorkloadRebalancerLister helps list WorkloadRebalancers. +// All objects returned here must be treated as read-only. +type WorkloadRebalancerLister interface { + // List lists all WorkloadRebalancers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.WorkloadRebalancer, err error) + // Get retrieves the WorkloadRebalancer from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.WorkloadRebalancer, error) + WorkloadRebalancerListerExpansion +} + +// workloadRebalancerLister implements the WorkloadRebalancerLister interface. +type workloadRebalancerLister struct { + indexer cache.Indexer +} + +// NewWorkloadRebalancerLister returns a new WorkloadRebalancerLister. +func NewWorkloadRebalancerLister(indexer cache.Indexer) WorkloadRebalancerLister { + return &workloadRebalancerLister{indexer: indexer} +} + +// List lists all WorkloadRebalancers in the indexer. +func (s *workloadRebalancerLister) List(selector labels.Selector) (ret []*v1alpha1.WorkloadRebalancer, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.WorkloadRebalancer)) + }) + return ret, err +} + +// Get retrieves the WorkloadRebalancer from the index for a given name. +func (s *workloadRebalancerLister) Get(name string) (*v1alpha1.WorkloadRebalancer, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("workloadrebalancer"), name) + } + return obj.(*v1alpha1.WorkloadRebalancer), nil +} diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go old mode 100755 new mode 100644 index 51675cb8213b..a1489750712b --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -33,6 +33,12 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObjectReference": schema_pkg_apis_apps_v1alpha1_ObjectReference(ref), + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObservedWorkload": schema_pkg_apis_apps_v1alpha1_ObservedWorkload(ref), + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancer": schema_pkg_apis_apps_v1alpha1_WorkloadRebalancer(ref), + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerList": schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerList(ref), + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerSpec": schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerSpec(ref), + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerStatus": schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerStatus(ref), "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1.CronFederatedHPA": schema_pkg_apis_autoscaling_v1alpha1_CronFederatedHPA(ref), "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1.CronFederatedHPAList": schema_pkg_apis_autoscaling_v1alpha1_CronFederatedHPAList(ref), "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1.CronFederatedHPARule": schema_pkg_apis_autoscaling_v1alpha1_CronFederatedHPARule(ref), @@ -546,6 +552,247 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA } } +func schema_pkg_apis_apps_v1alpha1_ObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ObjectReference the expected resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion represents the API version of the target resource.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind represents the Kind of the target resource.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the target resource.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Description: "Namespace of the target resource. Default is empty, which means it is a non-namespacescoped resource.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"apiVersion", "kind", "name"}, + }, + }, + } +} + +func schema_pkg_apis_apps_v1alpha1_ObservedWorkload(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ObservedWorkload the observed resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "workload": { + SchemaProps: spec.SchemaProps{ + Description: "Workload the observed resource.", + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObjectReference"), + }, + }, + "result": { + SchemaProps: spec.SchemaProps{ + Description: "Result the observed rebalance result of resource.", + Type: []string{"string"}, + Format: "", + }, + }, + "reason": { + SchemaProps: spec.SchemaProps{ + Description: "Reason represents a machine-readable description of why this resource rebalanced failed.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"workload"}, + }, + }, + Dependencies: []string{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObjectReference"}, + } +} + +func schema_pkg_apis_apps_v1alpha1_WorkloadRebalancer(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "WorkloadRebalancer represents the desired behavior and status of a job which can enforces a resource rebalance.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "Spec represents the specification of the desired behavior of WorkloadRebalancer.", + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "Status represents the status of WorkloadRebalancer.", + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerStatus"), + }, + }, + }, + Required: []string{"spec"}, + }, + }, + Dependencies: []string{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerSpec", "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancerStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "WorkloadRebalancerList contains a list of WorkloadRebalancer", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "Items holds a list of WorkloadRebalancer.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancer"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.WorkloadRebalancer", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "WorkloadRebalancerSpec represents the specification of the desired behavior of Reschedule.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "workloads": { + SchemaProps: spec.SchemaProps{ + Description: "Workloads used to specify the list of expected resource. Nil or empty list is not allowed.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObjectReference"), + }, + }, + }, + }, + }, + }, + Required: []string{"workloads"}, + }, + }, + Dependencies: []string{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObjectReference"}, + } +} + +func schema_pkg_apis_apps_v1alpha1_WorkloadRebalancerStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "WorkloadRebalancerStatus contains information about the current status of a WorkloadRebalancer updated periodically by schedule trigger controller.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "observedWorkloads": { + SchemaProps: spec.SchemaProps{ + Description: "ObservedWorkloads contains information about the execution states and messages of target resources.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObservedWorkload"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1.ObservedWorkload"}, + } +} + func schema_pkg_apis_autoscaling_v1alpha1_CronFederatedHPA(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/util/apigroup.go b/pkg/util/apigroup.go index c7d4ac259c56..ef002e9cb27c 100644 --- a/pkg/util/apigroup.go +++ b/pkg/util/apigroup.go @@ -24,6 +24,7 @@ import ( eventsv1 "k8s.io/api/events/v1" "k8s.io/apimachinery/pkg/runtime/schema" + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" @@ -64,6 +65,7 @@ func NewSkippedResourceConfig() *SkippedResourceConfig { r.DisableGroup(networkingv1alpha1.GroupVersion.Group) r.DisableGroup(autoscalingv1alpha1.GroupVersion.Group) r.DisableGroup(remedyv1alpha1.GroupVersion.Group) + r.DisableGroup(appsv1alpha1.GroupVersion.Group) // disable event by default r.DisableGroup(eventsv1.GroupName) r.DisableGroupVersionKind(corev1EventGVK) diff --git a/pkg/util/gclient/gclient.go b/pkg/util/gclient/gclient.go index c089136a0c58..6e7a99a18764 100644 --- a/pkg/util/gclient/gclient.go +++ b/pkg/util/gclient/gclient.go @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" mcsv1alpha1 "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + appsv1alpha1 "github.com/karmada-io/karmada/pkg/apis/apps/v1alpha1" autoscalingv1alpha1 "github.com/karmada-io/karmada/pkg/apis/autoscaling/v1alpha1" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" @@ -51,7 +52,8 @@ func init() { utilruntime.Must(mcsv1alpha1.AddToScheme(aggregatedScheme)) // add mcs-api schemes utilruntime.Must(clusterapiv1beta1.AddToScheme(aggregatedScheme)) // add cluster-api v1beta1 schemes utilruntime.Must(autoscalingv1alpha1.AddToScheme(aggregatedScheme)) // add autoscaling v1alpha1 schemes - utilruntime.Must(remedyv1alpha1.AddToScheme(aggregatedScheme)) // add autoscaling v1alpha1 schemes + utilruntime.Must(remedyv1alpha1.AddToScheme(aggregatedScheme)) // add remedy v1alpha1 schemes + utilruntime.Must(appsv1alpha1.AddToScheme(aggregatedScheme)) // add apps v1alpha1 schemes } // NewSchema returns a singleton schema set which aggregated Kubernetes's schemes and extended schemes.