From 3c70e5a9254b5932aefc8f441635d3dc7b839d41 Mon Sep 17 00:00:00 2001 From: Jian Qiu Date: Wed, 8 Jul 2020 11:31:24 +0800 Subject: [PATCH] Add appliedmanifestwork api --- deploy/klusterlet/cluster_role.yaml | 4 + .../klusterlet.clusterserviceversion.yaml | 12 ++ go.mod | 2 +- go.sum | 4 +- hack/copy-crds.sh | 7 +- hack/init.sh | 6 +- hack/verify-crds.sh | 7 +- ...uster-management.io_manifestworks.crd.yaml | 39 ---- ...anagement.io_appliedmanifestworks.crd.yaml | 105 ++++++++++ .../klusterlet-work-clusterrole.yaml | 10 + .../clustermanager/bindata/bindata.go | 39 ---- pkg/operators/klusterlet/bindata/bindata.go | 179 +++++++++++++++--- .../klusterlet_controller.go | 35 ++-- .../klusterlet_controller_test.go | 56 ++++-- pkg/operators/manager.go | 5 + test/e2e/common.go | 96 +++++----- test/e2e/e2e_suite_test.go | 3 +- test/e2e/klusterlet_test.go | 16 +- test/e2e/work_test.go | 43 ++--- .../typed/work/v1/appliedmanifestwork.go | 168 ++++++++++++++++ .../typed/work/v1/generated_expansion.go | 2 + .../versioned/typed/work/v1/work_client.go | 5 + ...uster-management.io_manifestworks.crd.yaml | 39 ---- ...anagement.io_appliedmanifestworks.crd.yaml | 105 ++++++++++ .../api/work/v1/register.go | 2 + .../api/work/v1/types.go | 71 ++++++- .../api/work/v1/zz_generated.deepcopy.go | 103 +++++++++- .../v1/zz_generated.swagger_doc_generated.go | 46 ++++- vendor/modules.txt | 2 +- 29 files changed, 930 insertions(+), 281 deletions(-) create mode 100644 manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml create mode 100644 vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/appliedmanifestwork.go create mode 100644 vendor/github.com/open-cluster-management/api/work/v1/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml diff --git a/deploy/klusterlet/cluster_role.yaml b/deploy/klusterlet/cluster_role.yaml index 9e759b304..31f6cb7e7 100644 --- a/deploy/klusterlet/cluster_role.yaml +++ b/deploy/klusterlet/cluster_role.yaml @@ -25,6 +25,10 @@ rules: - apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterroles", "roles"] verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"] +# Allow the registration-operator to create crds +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "get", "list", "update", "watch", "patch", "delete"] # Allow the registration-operator to manage klusterlet apis. - apiGroups: ["operator.open-cluster-management.io"] resources: ["klusterlets"] diff --git a/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml b/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml index f7b58ddfa..6b7d9c009 100644 --- a/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml +++ b/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml @@ -122,6 +122,18 @@ spec: - delete - escalate - bind + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create + - get + - list + - update + - watch + - patch + - delete - apiGroups: - operator.open-cluster-management.io resources: diff --git a/go.mod b/go.mod index a3b7648e5..93073bef7 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/go-bindata/go-bindata v3.1.2+incompatible github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 - github.com/open-cluster-management/api v0.0.0-20200629211334-8be047b65c52 + github.com/open-cluster-management/api v0.0.0-20200715201722-3c3c076bf062 github.com/openshift/api v0.0.0-20200521101457-60c476765272 github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc github.com/openshift/library-go v0.0.0-20200617154932-eaf8c138def4 diff --git a/go.sum b/go.sum index 9424135e2..f49a501db 100644 --- a/go.sum +++ b/go.sum @@ -310,8 +310,8 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/open-cluster-management/api v0.0.0-20200629211334-8be047b65c52 h1:8+Qh4L7ijoYK0wKM3Whjge53IVhL2fVWRbuUjy5kMUM= -github.com/open-cluster-management/api v0.0.0-20200629211334-8be047b65c52/go.mod h1:+vUECYB7WkfCb52r0J7rxgD1mseSGAqGi8rTLLRcbgw= +github.com/open-cluster-management/api v0.0.0-20200715201722-3c3c076bf062 h1:sYKu/XTeGrYCjO7x6/r6CfM/R8/Lr2kX7IG1DOC+wW0= +github.com/open-cluster-management/api v0.0.0-20200715201722-3c3c076bf062/go.mod h1:+vUECYB7WkfCb52r0J7rxgD1mseSGAqGi8rTLLRcbgw= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= diff --git a/hack/copy-crds.sh b/hack/copy-crds.sh index 3ee725999..c62439f9c 100755 --- a/hack/copy-crds.sh +++ b/hack/copy-crds.sh @@ -2,10 +2,15 @@ source "$(dirname "${BASH_SOURCE}")/init.sh" -for f in $CRD_FILES +for f in $HUB_CRD_FILES do cp $f ./manifests/cluster-manager/ done +for f in $SPOKE_CRD_FILES +do + cp $f ./manifests/klusterlet/ +done + cp $CLUSTER_MANAGER_CRD_FILE ./deploy/cluster-manager/crds/ cp $KLUSTERLET_CRD_FILE ./deploy/klusterlet/crds/ diff --git a/hack/init.sh b/hack/init.sh index f67fc6a2d..5aaa5086a 100644 --- a/hack/init.sh +++ b/hack/init.sh @@ -4,9 +4,11 @@ set -o errexit set -o nounset set -o pipefail -CRD_FILES="./vendor/github.com/open-cluster-management/api/cluster/v1/*.crd.yaml -./vendor/github.com/open-cluster-management/api/work/v1/*.crd.yaml +HUB_CRD_FILES="./vendor/github.com/open-cluster-management/api/cluster/v1/*.crd.yaml +./vendor/github.com/open-cluster-management/api/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml " +SPOKE_CRD_FILES="./vendor/github.com/open-cluster-management/api/work/v1/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml" + CLUSTER_MANAGER_CRD_FILE="./vendor/github.com/open-cluster-management/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml" KLUSTERLET_CRD_FILE="./vendor/github.com/open-cluster-management/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml" diff --git a/hack/verify-crds.sh b/hack/verify-crds.sh index c0008bf96..ca51207c2 100755 --- a/hack/verify-crds.sh +++ b/hack/verify-crds.sh @@ -2,11 +2,16 @@ source "$(dirname "${BASH_SOURCE}")/init.sh" -for f in $CRD_FILES +for f in $HUB_CRD_FILES do diff -N $f ./manifests/cluster-manager/$(basename $f) || ( echo 'crd content is incorrect' && false ) done +for f in $SPOKE_CRD_FILES +do + diff -N $f ./manifests/klusterlet/$(basename $f) || ( echo 'crd content is incorrect' && false ) +done + diff -N $CLUSTER_MANAGER_CRD_FILE ./deploy/cluster-manager/crds/$(basename $CLUSTER_MANAGER_CRD_FILE) || ( echo 'crd content is incorrect' && false ) diff -N $KLUSTERLET_CRD_FILE ./deploy/klusterlet/crds/$(basename $KLUSTERLET_CRD_FILE) || ( echo 'crd content is incorrect' && false ) diff --git a/manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml b/manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml index 06bbc7748..3f145b017 100644 --- a/manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml +++ b/manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml @@ -59,45 +59,6 @@ spec: description: Status represents the current status of work type: object properties: - appliedResources: - description: AppliedResources represents a list of resources defined - within the manifestwork that are applied. Only resources with valid - GroupVersionResource, namespace, and name are suitable. An item in - this slice is deleted when there is no mapped manifest in manifestwork.Spec - or by finalizer. The resource relating to the item will also be removed - from managed cluster. The deleted resource may still be present until - the finalizers for that resource are finished. However, the resource - will not be undeleted, so it can be removed from this list and eventual - consistency is preserved. - type: array - items: - description: AppliedManifestResourceMeta represents the gvr, name - and namespace of a resource. Since these resources have been created, - they must have valid group, version, resource, namespace, and name. - type: object - properties: - group: - description: Group is the API Group of the kubernetes resource - type: string - name: - description: Name is the name of the kubernetes resource - type: string - namespace: - description: Name is the namespace of the kubernetes resource, - empty string indicates it is a cluster scoped resource. - type: string - resource: - description: Resource is the resource name of the kubernetes resource - type: string - uid: - description: UID is set on successful deletion of the kubernetes - resource by controller. The resource might be still visible - on the managed cluster after this field is set. It is not directly - settable by a client. - type: string - version: - description: Version is the version of the kubernetes resource - type: string conditions: description: 'Conditions contains the different condition statuses for this work. Valid condition types are: 1. Applied represents workload diff --git a/manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml b/manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml new file mode 100644 index 000000000..ce47cb420 --- /dev/null +++ b/manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml @@ -0,0 +1,105 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: appliedmanifestworks.work.open-cluster-management.io +spec: + group: work.open-cluster-management.io + names: + kind: AppliedManifestWork + listKind: AppliedManifestWorkList + plural: appliedmanifestworks + singular: appliedmanifestwork + scope: "Cluster" + preserveUnknownFields: false + subresources: + status: {} + validation: + openAPIV3Schema: + description: AppliedManifestWork represents an applied manifestwork on managed + cluster. It is placed on managed cluster. An AppliedManifestWork links to + a manifestwork on a hub recording resources deployed in the managed cluster. + When the agent is removed from managed cluster, cluster-admin on managed cluster + can delete appliedmanifestwork to remove resources deployed by the agent. + The name of the appliedmanifestwork must be in the format of {hash of hub's + first kube-apiserver url}-{manifestwork name} + type: object + 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 desired configuration of AppliedManifestWork + type: object + properties: + hubHash: + description: HubHash represents the hash of the first hub kube apiserver + to identify which hub this AppliedManifestWork links to. + type: string + manifestWorkName: + description: ManifestWorkName represents the name of the related manifestwork + on hub. + type: string + status: + description: Status represents the current status of AppliedManifestWork + type: object + properties: + appliedResources: + description: AppliedResources represents a list of resources defined + within the manifestwork that are applied. Only resources with valid + GroupVersionResource, namespace, and name are suitable. An item in + this slice is deleted when there is no mapped manifest in manifestwork.Spec + or by finalizer. The resource relating to the item will also be removed + from managed cluster. The deleted resource may still be present until + the finalizers for that resource are finished. However, the resource + will not be undeleted, so it can be removed from this list and eventual + consistency is preserved. + type: array + items: + description: AppliedManifestResourceMeta represents the gvr, name + and namespace of a resource. Since these resources have been created, + they must have valid group, version, resource, namespace, and name. + type: object + properties: + group: + description: Group is the API Group of the kubernetes resource + type: string + name: + description: Name is the name of the kubernetes resource + type: string + namespace: + description: Name is the namespace of the kubernetes resource, + empty string indicates it is a cluster scoped resource. + type: string + resource: + description: Resource is the resource name of the kubernetes resource + type: string + uid: + description: UID is set on successful deletion of the kubernetes + resource by controller. The resource might be still visible + on the managed cluster after this field is set. It is not directly + settable by a client. + type: string + version: + description: Version is the version of the kubernetes resource + type: string + version: v1 + versions: + - name: v1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests/klusterlet/klusterlet-work-clusterrole.yaml b/manifests/klusterlet/klusterlet-work-clusterrole.yaml index 5bef927a3..451ecaa12 100644 --- a/manifests/klusterlet/klusterlet-work-clusterrole.yaml +++ b/manifests/klusterlet/klusterlet-work-clusterrole.yaml @@ -27,3 +27,13 @@ rules: - apiGroups: ["", "events.k8s.io"] resources: ["events"] verbs: ["create", "patch", "update"] +# Allow agent to managed appliedmanifestworks +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks/status"] + verbs: ["patch", "update"] +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks/finalizers"] + verbs: ["update"] diff --git a/pkg/operators/clustermanager/bindata/bindata.go b/pkg/operators/clustermanager/bindata/bindata.go index 1faef423b..28c2c6085 100644 --- a/pkg/operators/clustermanager/bindata/bindata.go +++ b/pkg/operators/clustermanager/bindata/bindata.go @@ -310,45 +310,6 @@ spec: description: Status represents the current status of work type: object properties: - appliedResources: - description: AppliedResources represents a list of resources defined - within the manifestwork that are applied. Only resources with valid - GroupVersionResource, namespace, and name are suitable. An item in - this slice is deleted when there is no mapped manifest in manifestwork.Spec - or by finalizer. The resource relating to the item will also be removed - from managed cluster. The deleted resource may still be present until - the finalizers for that resource are finished. However, the resource - will not be undeleted, so it can be removed from this list and eventual - consistency is preserved. - type: array - items: - description: AppliedManifestResourceMeta represents the gvr, name - and namespace of a resource. Since these resources have been created, - they must have valid group, version, resource, namespace, and name. - type: object - properties: - group: - description: Group is the API Group of the kubernetes resource - type: string - name: - description: Name is the name of the kubernetes resource - type: string - namespace: - description: Name is the namespace of the kubernetes resource, - empty string indicates it is a cluster scoped resource. - type: string - resource: - description: Resource is the resource name of the kubernetes resource - type: string - uid: - description: UID is set on successful deletion of the kubernetes - resource by controller. The resource might be still visible - on the managed cluster after this field is set. It is not directly - settable by a client. - type: string - version: - description: Version is the version of the kubernetes resource - type: string conditions: description: 'Conditions contains the different condition statuses for this work. Valid condition types are: 1. Applied represents workload diff --git a/pkg/operators/klusterlet/bindata/bindata.go b/pkg/operators/klusterlet/bindata/bindata.go index 21f47cc8a..462f6f283 100644 --- a/pkg/operators/klusterlet/bindata/bindata.go +++ b/pkg/operators/klusterlet/bindata/bindata.go @@ -1,5 +1,6 @@ // Code generated for package bindata by go-bindata DO NOT EDIT. (@generated) // sources: +// manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml // manifests/klusterlet/klusterlet-registration-clusterrole.yaml // manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml // manifests/klusterlet/klusterlet-registration-deployment.yaml @@ -64,6 +65,128 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } +var _manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: appliedmanifestworks.work.open-cluster-management.io +spec: + group: work.open-cluster-management.io + names: + kind: AppliedManifestWork + listKind: AppliedManifestWorkList + plural: appliedmanifestworks + singular: appliedmanifestwork + scope: "Cluster" + preserveUnknownFields: false + subresources: + status: {} + validation: + openAPIV3Schema: + description: AppliedManifestWork represents an applied manifestwork on managed + cluster. It is placed on managed cluster. An AppliedManifestWork links to + a manifestwork on a hub recording resources deployed in the managed cluster. + When the agent is removed from managed cluster, cluster-admin on managed cluster + can delete appliedmanifestwork to remove resources deployed by the agent. + The name of the appliedmanifestwork must be in the format of {hash of hub's + first kube-apiserver url}-{manifestwork name} + type: object + 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 desired configuration of AppliedManifestWork + type: object + properties: + hubHash: + description: HubHash represents the hash of the first hub kube apiserver + to identify which hub this AppliedManifestWork links to. + type: string + manifestWorkName: + description: ManifestWorkName represents the name of the related manifestwork + on hub. + type: string + status: + description: Status represents the current status of AppliedManifestWork + type: object + properties: + appliedResources: + description: AppliedResources represents a list of resources defined + within the manifestwork that are applied. Only resources with valid + GroupVersionResource, namespace, and name are suitable. An item in + this slice is deleted when there is no mapped manifest in manifestwork.Spec + or by finalizer. The resource relating to the item will also be removed + from managed cluster. The deleted resource may still be present until + the finalizers for that resource are finished. However, the resource + will not be undeleted, so it can be removed from this list and eventual + consistency is preserved. + type: array + items: + description: AppliedManifestResourceMeta represents the gvr, name + and namespace of a resource. Since these resources have been created, + they must have valid group, version, resource, namespace, and name. + type: object + properties: + group: + description: Group is the API Group of the kubernetes resource + type: string + name: + description: Name is the name of the kubernetes resource + type: string + namespace: + description: Name is the namespace of the kubernetes resource, + empty string indicates it is a cluster scoped resource. + type: string + resource: + description: Resource is the resource name of the kubernetes resource + type: string + uid: + description: UID is set on successful deletion of the kubernetes + resource by controller. The resource might be still visible + on the managed cluster after this field is set. It is not directly + settable by a client. + type: string + version: + description: Version is the version of the kubernetes resource + type: string + version: v1 + versions: + - name: v1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +`) + +func manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYamlBytes() ([]byte, error) { + return _manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYaml, nil +} + +func manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYaml() (*asset, error) { + bytes, err := manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _manifestsKlusterletKlusterletRegistrationClusterroleYaml = []byte(`# Clusterrole for work agent in addition to admin clusterrole. apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -335,6 +458,16 @@ rules: - apiGroups: ["", "events.k8s.io"] resources: ["events"] verbs: ["create", "patch", "update"] +# Allow agent to managed appliedmanifestworks +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks/status"] + verbs: ["patch", "update"] +- apiGroups: ["work.open-cluster-management.io"] + resources: ["appliedmanifestworks/finalizers"] + verbs: ["update"] `) func manifestsKlusterletKlusterletWorkClusterroleYamlBytes() ([]byte, error) { @@ -578,17 +711,18 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "manifests/klusterlet/klusterlet-registration-clusterrole.yaml": manifestsKlusterletKlusterletRegistrationClusterroleYaml, - "manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml": manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml, - "manifests/klusterlet/klusterlet-registration-deployment.yaml": manifestsKlusterletKlusterletRegistrationDeploymentYaml, - "manifests/klusterlet/klusterlet-registration-role.yaml": manifestsKlusterletKlusterletRegistrationRoleYaml, - "manifests/klusterlet/klusterlet-registration-rolebinding.yaml": manifestsKlusterletKlusterletRegistrationRolebindingYaml, - "manifests/klusterlet/klusterlet-registration-serviceaccount.yaml": manifestsKlusterletKlusterletRegistrationServiceaccountYaml, - "manifests/klusterlet/klusterlet-work-clusterrole.yaml": manifestsKlusterletKlusterletWorkClusterroleYaml, - "manifests/klusterlet/klusterlet-work-clusterrolebinding-addition.yaml": manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml, - "manifests/klusterlet/klusterlet-work-clusterrolebinding.yaml": manifestsKlusterletKlusterletWorkClusterrolebindingYaml, - "manifests/klusterlet/klusterlet-work-deployment.yaml": manifestsKlusterletKlusterletWorkDeploymentYaml, - "manifests/klusterlet/klusterlet-work-serviceaccount.yaml": manifestsKlusterletKlusterletWorkServiceaccountYaml, + "manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml": manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYaml, + "manifests/klusterlet/klusterlet-registration-clusterrole.yaml": manifestsKlusterletKlusterletRegistrationClusterroleYaml, + "manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml": manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml, + "manifests/klusterlet/klusterlet-registration-deployment.yaml": manifestsKlusterletKlusterletRegistrationDeploymentYaml, + "manifests/klusterlet/klusterlet-registration-role.yaml": manifestsKlusterletKlusterletRegistrationRoleYaml, + "manifests/klusterlet/klusterlet-registration-rolebinding.yaml": manifestsKlusterletKlusterletRegistrationRolebindingYaml, + "manifests/klusterlet/klusterlet-registration-serviceaccount.yaml": manifestsKlusterletKlusterletRegistrationServiceaccountYaml, + "manifests/klusterlet/klusterlet-work-clusterrole.yaml": manifestsKlusterletKlusterletWorkClusterroleYaml, + "manifests/klusterlet/klusterlet-work-clusterrolebinding-addition.yaml": manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml, + "manifests/klusterlet/klusterlet-work-clusterrolebinding.yaml": manifestsKlusterletKlusterletWorkClusterrolebindingYaml, + "manifests/klusterlet/klusterlet-work-deployment.yaml": manifestsKlusterletKlusterletWorkDeploymentYaml, + "manifests/klusterlet/klusterlet-work-serviceaccount.yaml": manifestsKlusterletKlusterletWorkServiceaccountYaml, } // AssetDir returns the file names below a certain @@ -634,17 +768,18 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "manifests": {nil, map[string]*bintree{ "klusterlet": {nil, map[string]*bintree{ - "klusterlet-registration-clusterrole.yaml": {manifestsKlusterletKlusterletRegistrationClusterroleYaml, map[string]*bintree{}}, - "klusterlet-registration-clusterrolebinding.yaml": {manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml, map[string]*bintree{}}, - "klusterlet-registration-deployment.yaml": {manifestsKlusterletKlusterletRegistrationDeploymentYaml, map[string]*bintree{}}, - "klusterlet-registration-role.yaml": {manifestsKlusterletKlusterletRegistrationRoleYaml, map[string]*bintree{}}, - "klusterlet-registration-rolebinding.yaml": {manifestsKlusterletKlusterletRegistrationRolebindingYaml, map[string]*bintree{}}, - "klusterlet-registration-serviceaccount.yaml": {manifestsKlusterletKlusterletRegistrationServiceaccountYaml, map[string]*bintree{}}, - "klusterlet-work-clusterrole.yaml": {manifestsKlusterletKlusterletWorkClusterroleYaml, map[string]*bintree{}}, - "klusterlet-work-clusterrolebinding-addition.yaml": {manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml, map[string]*bintree{}}, - "klusterlet-work-clusterrolebinding.yaml": {manifestsKlusterletKlusterletWorkClusterrolebindingYaml, map[string]*bintree{}}, - "klusterlet-work-deployment.yaml": {manifestsKlusterletKlusterletWorkDeploymentYaml, map[string]*bintree{}}, - "klusterlet-work-serviceaccount.yaml": {manifestsKlusterletKlusterletWorkServiceaccountYaml, map[string]*bintree{}}, + "0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml": {manifestsKlusterlet0000_01_workOpenClusterManagementIo_appliedmanifestworksCrdYaml, map[string]*bintree{}}, + "klusterlet-registration-clusterrole.yaml": {manifestsKlusterletKlusterletRegistrationClusterroleYaml, map[string]*bintree{}}, + "klusterlet-registration-clusterrolebinding.yaml": {manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml, map[string]*bintree{}}, + "klusterlet-registration-deployment.yaml": {manifestsKlusterletKlusterletRegistrationDeploymentYaml, map[string]*bintree{}}, + "klusterlet-registration-role.yaml": {manifestsKlusterletKlusterletRegistrationRoleYaml, map[string]*bintree{}}, + "klusterlet-registration-rolebinding.yaml": {manifestsKlusterletKlusterletRegistrationRolebindingYaml, map[string]*bintree{}}, + "klusterlet-registration-serviceaccount.yaml": {manifestsKlusterletKlusterletRegistrationServiceaccountYaml, map[string]*bintree{}}, + "klusterlet-work-clusterrole.yaml": {manifestsKlusterletKlusterletWorkClusterroleYaml, map[string]*bintree{}}, + "klusterlet-work-clusterrolebinding-addition.yaml": {manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml, map[string]*bintree{}}, + "klusterlet-work-clusterrolebinding.yaml": {manifestsKlusterletKlusterletWorkClusterrolebindingYaml, map[string]*bintree{}}, + "klusterlet-work-deployment.yaml": {manifestsKlusterletKlusterletWorkDeploymentYaml, map[string]*bintree{}}, + "klusterlet-work-serviceaccount.yaml": {manifestsKlusterletKlusterletWorkServiceaccountYaml, map[string]*bintree{}}, }}, }}, }} diff --git a/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go b/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go index 3425accd1..3c574726e 100644 --- a/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go +++ b/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go @@ -7,6 +7,7 @@ import ( "strings" corev1 "k8s.io/api/core/v1" + apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,6 +41,10 @@ const ( ) var ( + crdStaticFiles = []string{ + "manifests/klusterlet/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml", + } + staticResourceFiles = []string{ "manifests/klusterlet/klusterlet-registration-serviceaccount.yaml", "manifests/klusterlet/klusterlet-registration-clusterrole.yaml", @@ -59,16 +64,18 @@ var ( ) type klusterletController struct { - klusterletClient operatorv1client.KlusterletInterface - klusterletLister operatorlister.KlusterletLister - kubeClient kubernetes.Interface - kubeVersion *version.Version - operatorNamespace string + klusterletClient operatorv1client.KlusterletInterface + klusterletLister operatorlister.KlusterletLister + kubeClient kubernetes.Interface + apiExtensionClient apiextensionsclient.Interface + kubeVersion *version.Version + operatorNamespace string } // NewKlusterletController construct klusterlet controller func NewKlusterletController( kubeClient kubernetes.Interface, + apiExtensionClient apiextensionsclient.Interface, klusterletClient operatorv1client.KlusterletInterface, klusterletInformer operatorinformer.KlusterletInformer, secretInformer coreinformer.SecretInformer, @@ -77,11 +84,12 @@ func NewKlusterletController( operatorNamespace string, recorder events.Recorder) factory.Controller { controller := &klusterletController{ - kubeClient: kubeClient, - klusterletClient: klusterletClient, - klusterletLister: klusterletInformer.Lister(), - kubeVersion: kubeVersion, - operatorNamespace: operatorNamespace, + kubeClient: kubeClient, + apiExtensionClient: apiExtensionClient, + klusterletClient: klusterletClient, + klusterletLister: klusterletInformer.Lister(), + kubeVersion: kubeVersion, + operatorNamespace: operatorNamespace, } return factory.New().WithSync(controller.sync). @@ -223,13 +231,14 @@ func (n *klusterletController) sync(ctx context.Context, controllerContext facto } // Apply static files + appliedStaticFiles := append(crdStaticFiles, staticResourceFiles...) resourceResults := resourceapply.ApplyDirectly( - resourceapply.NewKubeClientHolder(n.kubeClient), + resourceapply.NewKubeClientHolder(n.kubeClient).WithAPIExtensionsClient(n.apiExtensionClient), controllerContext.Recorder(), func(name string) ([]byte, error) { return assets.MustCreateAssetFromTemplate(name, bindata.MustAsset(filepath.Join("", name)), config).Data, nil }, - staticResourceFiles..., + appliedStaticFiles..., ) for _, result := range resourceResults { @@ -358,7 +367,7 @@ func (n *klusterletController) cleanUp(ctx context.Context, controllerContext fa err := helpers.CleanUpStaticObject( ctx, n.kubeClient, - nil, + n.apiExtensionClient, nil, func(name string) ([]byte, error) { return assets.MustCreateAssetFromTemplate(name, bindata.MustAsset(filepath.Join("", name)), config).Data, nil diff --git a/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller_test.go b/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller_test.go index e46e33d70..168bb1d9f 100644 --- a/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller_test.go +++ b/pkg/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller_test.go @@ -13,6 +13,7 @@ import ( testinghelper "github.com/open-cluster-management/registration-operator/pkg/helpers/testing" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + fakeapiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,10 +25,11 @@ import ( ) type testController struct { - controller *klusterletController - kubeClient *fakekube.Clientset - operatorClient *fakeoperatorclient.Clientset - operatorStore cache.Store + controller *klusterletController + kubeClient *fakekube.Clientset + apiExtensionClient *fakeapiextensions.Clientset + operatorClient *fakeoperatorclient.Clientset + operatorStore cache.Store } func newSecret(name, namespace string) *corev1.Secret { @@ -86,26 +88,29 @@ func newNamespace(name string) *corev1.Namespace { func newTestController(klusterlet *opratorapiv1.Klusterlet, objects ...runtime.Object) *testController { fakeKubeClient := fakekube.NewSimpleClientset(objects...) + fakeAPIExtensionClient := fakeapiextensions.NewSimpleClientset() fakeOperatorClient := fakeoperatorclient.NewSimpleClientset(klusterlet) operatorInformers := operatorinformers.NewSharedInformerFactory(fakeOperatorClient, 5*time.Minute) kubeVersion, _ := version.ParseGeneric("v1.18.0") hubController := &klusterletController{ - klusterletClient: fakeOperatorClient.OperatorV1().Klusterlets(), - kubeClient: fakeKubeClient, - klusterletLister: operatorInformers.Operator().V1().Klusterlets().Lister(), - kubeVersion: kubeVersion, - operatorNamespace: "open-cluster-management", + klusterletClient: fakeOperatorClient.OperatorV1().Klusterlets(), + kubeClient: fakeKubeClient, + apiExtensionClient: fakeAPIExtensionClient, + klusterletLister: operatorInformers.Operator().V1().Klusterlets().Lister(), + kubeVersion: kubeVersion, + operatorNamespace: "open-cluster-management", } store := operatorInformers.Operator().V1().Klusterlets().Informer().GetStore() store.Add(klusterlet) return &testController{ - controller: hubController, - kubeClient: fakeKubeClient, - operatorClient: fakeOperatorClient, - operatorStore: store, + controller: hubController, + kubeClient: fakeKubeClient, + apiExtensionClient: fakeAPIExtensionClient, + operatorClient: fakeOperatorClient, + operatorStore: store, } } @@ -258,6 +263,18 @@ func TestSyncDeploy(t *testing.T) { ensureObject(t, object, klusterlet) } + apiExtenstionAction := controller.apiExtensionClient.Actions() + createCRDObjects := []runtime.Object{} + for _, action := range apiExtenstionAction { + if action.GetVerb() == "create" && action.GetResource().Resource == "customresourcedefinitions" { + object := action.(clienttesting.CreateActionImpl).Object + createCRDObjects = append(createCRDObjects, object) + } + } + if len(createCRDObjects) != 1 { + t.Errorf("Expect 1 objects created in the sync loop, actual %d", len(createCRDObjects)) + } + operatorAction := controller.operatorClient.Actions() if len(operatorAction) != 2 { t.Errorf("Expect 2 actions in the sync loop, actual %#v", operatorAction) @@ -296,6 +313,19 @@ func TestSyncDelete(t *testing.T) { if len(kubeActions) != 12 { t.Errorf("Expected 12 delete actions, but got %d", len(kubeActions)) } + + deleteCRDActions := []clienttesting.DeleteActionImpl{} + crdActions := controller.apiExtensionClient.Actions() + for _, action := range crdActions { + if action.GetVerb() == "delete" { + deleteAction := action.(clienttesting.DeleteActionImpl) + deleteActions = append(deleteCRDActions, deleteAction) + } + } + + if len(crdActions) != 0 { + t.Errorf("Expected 0 delete actions, but got %d", len(crdActions)) + } } // TestGetServersFromKlusterlet tests getServersFromKlusterlet func diff --git a/pkg/operators/manager.go b/pkg/operators/manager.go index 444217fe5..a58d99d73 100644 --- a/pkg/operators/manager.go +++ b/pkg/operators/manager.go @@ -80,6 +80,10 @@ func RunKlusterletOperator(ctx context.Context, controllerContext *controllercmd if err != nil { return err } + apiExtensionClient, err := apiextensionsclient.NewForConfig(controllerContext.KubeConfig) + if err != nil { + return err + } version, err := kubeClient.ServerVersion() if err != nil { return err @@ -107,6 +111,7 @@ func RunKlusterletOperator(ctx context.Context, controllerContext *controllercmd klusterletController := klusterletcontroller.NewKlusterletController( kubeClient, + apiExtensionClient, operatorClient.OperatorV1().Klusterlets(), operatorInformer.Operator().V1().Klusterlets(), kubeInformer.Core().V1().Secrets(), diff --git a/test/e2e/common.go b/test/e2e/common.go index 6f000b26f..0ee81a5fe 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -3,10 +3,13 @@ package e2e import ( "context" "fmt" - "k8s.io/klog" "os" "time" + "k8s.io/klog" + + "github.com/onsi/gomega" + clusterclient "github.com/open-cluster-management/api/client/cluster/clientset/versioned" operatorclient "github.com/open-cluster-management/api/client/operator/clientset/versioned" workv1client "github.com/open-cluster-management/api/client/work/clientset/versioned" @@ -24,7 +27,6 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/util/retry" ) type Tester struct { @@ -134,8 +136,8 @@ func (t *Tester) CreateKlusterlet(name, clusterName, agentNamespace string) (*op Name: name, }, Spec: operatorapiv1.KlusterletSpec{ - RegistrationImagePullSpec: "quay.io/open-cluster-management/registration", - WorkImagePullSpec: "quay.io/open-cluster-management/work", + RegistrationImagePullSpec: "quay.io/open-cluster-management/registration:latest", + WorkImagePullSpec: "quay.io/open-cluster-management/work:latest", ExternalServerURLs: []operatorapiv1.ServerURL{ { URL: "https://localhost", @@ -221,23 +223,20 @@ func (t *Tester) ApproveCSR(clusterName string) error { for i := range csrs.Items { csr := &csrs.Items[i] - err = retry.RetryOnConflict(retry.DefaultRetry, func() error { - if csr, err = csrClient.Get(context.TODO(), csr.Name, metav1.GetOptions{}); err != nil { - return err - } - - if isCSRInTerminalState(&csr.Status) { - return nil - } - - csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{ - Type: certificatesv1beta1.CertificateApproved, - Reason: "Approved by E2E", - Message: "Approved as part of e2e", - }) - _, err = csrClient.UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{}) + if csr, err = csrClient.Get(context.TODO(), csr.Name, metav1.GetOptions{}); err != nil { return err + } + + if isCSRInTerminalState(&csr.Status) { + return nil + } + + csr.Status.Conditions = append(csr.Status.Conditions, certificatesv1beta1.CertificateSigningRequestCondition{ + Type: certificatesv1beta1.CertificateApproved, + Reason: "Approved by E2E", + Message: "Approved as part of e2e", }) + _, err = csrClient.UpdateApproval(context.TODO(), csr, metav1.UpdateOptions{}) if err != nil { return err } @@ -258,19 +257,16 @@ func isCSRInTerminalState(status *certificatesv1beta1.CertificateSigningRequestS } func (t *Tester) AcceptsClient(clusterName string) error { - err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - managedCluster, err := t.ClusterClient.ClusterV1().ManagedClusters().Get(context.TODO(), - clusterName, metav1.GetOptions{}) - if err != nil { - return err - } - - managedCluster.Spec.HubAcceptsClient = true - managedCluster.Spec.LeaseDurationSeconds = 5 - managedCluster, err = t.ClusterClient.ClusterV1().ManagedClusters().Update(context.TODO(), - managedCluster, metav1.UpdateOptions{}) + managedCluster, err := t.ClusterClient.ClusterV1().ManagedClusters().Get(context.TODO(), + clusterName, metav1.GetOptions{}) + if err != nil { return err - }) + } + + managedCluster.Spec.HubAcceptsClient = true + managedCluster.Spec.LeaseDurationSeconds = 5 + _, err = t.ClusterClient.ClusterV1().ManagedClusters().Update(context.TODO(), + managedCluster, metav1.UpdateOptions{}) return err } @@ -332,41 +328,39 @@ func (t *Tester) CreateWorkOfConfigMap(name, clusterName, configMapName, configM Create(context.TODO(), manifestWork, metav1.CreateOptions{}) } -func (t *Tester) cleanKlusterletResources(klusterletName string) error { +func (t *Tester) cleanKlusterletResources(klusterletName, clusterName string) error { if klusterletName == "" { return fmt.Errorf("the klusterlet name should not be null") } - clusterName, err := t.GetClusterNameFromKlusterlet(klusterletName) - if err != nil { - return err - } - - // clean the manifest works - manifestWorks, err := t.WorkClient.WorkV1().ManifestWorks(clusterName). - List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return err - } - - for _, work := range manifestWorks.Items { - // ignore if failed to delete - _ = t.WorkClient.WorkV1().ManifestWorks(work.Namespace). - Delete(context.TODO(), work.Name, metav1.DeleteOptions{}) - } - // clean the klusterlets - err = t.OperatorClient.OperatorV1().Klusterlets().Delete(context.TODO(), klusterletName, metav1.DeleteOptions{}) + err := t.OperatorClient.OperatorV1().Klusterlets().Delete(context.TODO(), klusterletName, metav1.DeleteOptions{}) if err != nil { return err } + gomega.Eventually(func() bool { + _, err := t.OperatorClient.OperatorV1().Klusterlets().Get(context.TODO(), klusterletName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return true + } + return false + }, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(gomega.BeTrue()) + // clean the managed clusters err = t.ClusterClient.ClusterV1().ManagedClusters().Delete(context.TODO(), clusterName, metav1.DeleteOptions{}) if err != nil { return err } + gomega.Eventually(func() bool { + _, err := t.ClusterClient.ClusterV1().ManagedClusters().Get(context.TODO(), clusterName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return true + } + return false + }, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(gomega.BeTrue()) + return nil } diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 823709750..aeedeccfb 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -1,9 +1,10 @@ package e2e import ( + "testing" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "testing" ) func TestE2E(t *testing.T) { diff --git a/test/e2e/klusterlet_test.go b/test/e2e/klusterlet_test.go index befb4a93a..096e80b2d 100644 --- a/test/e2e/klusterlet_test.go +++ b/test/e2e/klusterlet_test.go @@ -9,20 +9,22 @@ import ( ) var _ = Describe("Create klusterlet CR", func() { - var klusterletName = "" + var klusterletName string + var clusterName string + var agentNamespace string + BeforeEach(func() { klusterletName = fmt.Sprintf("e2e-klusterlet-%s", rand.String(6)) + clusterName = fmt.Sprintf("e2e-managedcluster-%s", rand.String(6)) + agentNamespace = fmt.Sprintf("e2e-agent-%s", rand.String(6)) }) AfterEach(func() { By(fmt.Sprintf("clean klusterlet %v resources after the test case", klusterletName)) - t.cleanKlusterletResources(klusterletName) + t.cleanKlusterletResources(klusterletName, clusterName) }) It("Create klusterlet CR with managed cluster name", func() { - var clusterName = fmt.Sprintf("e2e-managedcluster-%s", rand.String(6)) - var agentNamespace = fmt.Sprintf("e2e-agent-%s", rand.String(6)) - By(fmt.Sprintf("create klusterlet %v with managed cluster name %v", klusterletName, clusterName)) _, err := t.CreateKlusterlet(klusterletName, clusterName, agentNamespace) Expect(err).ToNot(HaveOccurred()) @@ -50,8 +52,8 @@ var _ = Describe("Create klusterlet CR", func() { }) It("Created klusterlet without managed cluster name", func() { - var clusterName = "" - var agentNamespace = "" + clusterName = "" + agentNamespace = "" var err error By(fmt.Sprintf("create klusterlet %v without managed cluster name", klusterletName)) _, err = t.CreateKlusterlet(klusterletName, clusterName, agentNamespace) diff --git a/test/e2e/work_test.go b/test/e2e/work_test.go index 79b6af5d3..a2b16c1fd 100644 --- a/test/e2e/work_test.go +++ b/test/e2e/work_test.go @@ -3,8 +3,10 @@ package e2e import ( "context" "fmt" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/rand" ) @@ -19,7 +21,7 @@ var _ = Describe("Create klusterlet and then create a configmap by manifestwork" AfterEach(func() { By(fmt.Sprintf("clean klusterlet %v resources after the test case", klusterletName)) - t.cleanKlusterletResources(klusterletName) + t.cleanKlusterletResources(klusterletName, clusterName) }) It("Create configmap using manifestwork and then delete klusterlet", func() { @@ -61,36 +63,15 @@ var _ = Describe("Create klusterlet and then create a configmap by manifestwork" return err }, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(Succeed()) - // Manifest work and ns should not be deleted after delete klusterlet - By(fmt.Sprintf("delete klusterlet %v", klusterletName)) - err = t.OperatorClient.OperatorV1().Klusterlets().Delete(context.TODO(), klusterletName, metav1.DeleteOptions{}) - Expect(err).NotTo(HaveOccurred()) - - By(fmt.Sprintf("waiting for pods in agent namespace %v to be deleted", agentNamespace)) - Eventually(func() error { - pods, err := t.KubeClient.CoreV1().Pods(agentNamespace). - List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return err + By(fmt.Sprintf("delete manifestwork %v/%v", clusterName, workName)) + err = t.WorkClient.WorkV1().ManifestWorks(clusterName).Delete(context.Background(), workName, metav1.DeleteOptions{}) + Expect(err).ToNot(HaveOccurred()) + Eventually(func() bool { + _, err := t.WorkClient.WorkV1().ManifestWorks(clusterName).Get(context.Background(), workName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return true } - if len(pods.Items) != 0 { - return fmt.Errorf("the pods are not deleted in ns %v", agentNamespace) - } - return nil - }, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(Succeed()) - - By(fmt.Sprintf("check that managed cluster namespace %v should not be deleted", clusterName)) - Eventually(func() error { - _, err := t.KubeClient.CoreV1().Namespaces(). - Get(context.TODO(), clusterName, metav1.GetOptions{}) - return err - }, t.EventuallyTimeout, t.EventuallyInterval).Should(Succeed()) - - By(fmt.Sprintf("check that manifestwork %v/%v should not be deleted", clusterName, workName)) - Eventually(func() error { - _, err := t.WorkClient.WorkV1().ManifestWorks(clusterName). - Get(context.TODO(), workName, metav1.GetOptions{}) - return err - }, t.EventuallyTimeout, t.EventuallyInterval).Should(Succeed()) + return false + }, t.EventuallyTimeout*5, t.EventuallyInterval*5).Should(BeTrue()) }) }) diff --git a/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/appliedmanifestwork.go b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/appliedmanifestwork.go new file mode 100644 index 000000000..506203468 --- /dev/null +++ b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/appliedmanifestwork.go @@ -0,0 +1,168 @@ +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/open-cluster-management/api/client/work/clientset/versioned/scheme" + v1 "github.com/open-cluster-management/api/work/v1" + metav1 "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" +) + +// AppliedManifestWorksGetter has a method to return a AppliedManifestWorkInterface. +// A group's client should implement this interface. +type AppliedManifestWorksGetter interface { + AppliedManifestWorks() AppliedManifestWorkInterface +} + +// AppliedManifestWorkInterface has methods to work with AppliedManifestWork resources. +type AppliedManifestWorkInterface interface { + Create(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.CreateOptions) (*v1.AppliedManifestWork, error) + Update(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.UpdateOptions) (*v1.AppliedManifestWork, error) + UpdateStatus(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.UpdateOptions) (*v1.AppliedManifestWork, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.AppliedManifestWork, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.AppliedManifestWorkList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.AppliedManifestWork, err error) + AppliedManifestWorkExpansion +} + +// appliedManifestWorks implements AppliedManifestWorkInterface +type appliedManifestWorks struct { + client rest.Interface +} + +// newAppliedManifestWorks returns a AppliedManifestWorks +func newAppliedManifestWorks(c *WorkV1Client) *appliedManifestWorks { + return &appliedManifestWorks{ + client: c.RESTClient(), + } +} + +// Get takes name of the appliedManifestWork, and returns the corresponding appliedManifestWork object, and an error if there is any. +func (c *appliedManifestWorks) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.AppliedManifestWork, err error) { + result = &v1.AppliedManifestWork{} + err = c.client.Get(). + Resource("appliedmanifestworks"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of AppliedManifestWorks that match those selectors. +func (c *appliedManifestWorks) List(ctx context.Context, opts metav1.ListOptions) (result *v1.AppliedManifestWorkList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.AppliedManifestWorkList{} + err = c.client.Get(). + Resource("appliedmanifestworks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested appliedManifestWorks. +func (c *appliedManifestWorks) Watch(ctx context.Context, opts metav1.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("appliedmanifestworks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a appliedManifestWork and creates it. Returns the server's representation of the appliedManifestWork, and an error, if there is any. +func (c *appliedManifestWorks) Create(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.CreateOptions) (result *v1.AppliedManifestWork, err error) { + result = &v1.AppliedManifestWork{} + err = c.client.Post(). + Resource("appliedmanifestworks"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(appliedManifestWork). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a appliedManifestWork and updates it. Returns the server's representation of the appliedManifestWork, and an error, if there is any. +func (c *appliedManifestWorks) Update(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.UpdateOptions) (result *v1.AppliedManifestWork, err error) { + result = &v1.AppliedManifestWork{} + err = c.client.Put(). + Resource("appliedmanifestworks"). + Name(appliedManifestWork.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(appliedManifestWork). + 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 *appliedManifestWorks) UpdateStatus(ctx context.Context, appliedManifestWork *v1.AppliedManifestWork, opts metav1.UpdateOptions) (result *v1.AppliedManifestWork, err error) { + result = &v1.AppliedManifestWork{} + err = c.client.Put(). + Resource("appliedmanifestworks"). + Name(appliedManifestWork.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(appliedManifestWork). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the appliedManifestWork and deletes it. Returns an error if one occurs. +func (c *appliedManifestWorks) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("appliedmanifestworks"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *appliedManifestWorks) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("appliedmanifestworks"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched appliedManifestWork. +func (c *appliedManifestWorks) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.AppliedManifestWork, err error) { + result = &v1.AppliedManifestWork{} + err = c.client.Patch(pt). + Resource("appliedmanifestworks"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/generated_expansion.go b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/generated_expansion.go index 0783cb1f0..1d5e31253 100644 --- a/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/generated_expansion.go +++ b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/generated_expansion.go @@ -2,4 +2,6 @@ package v1 +type AppliedManifestWorkExpansion interface{} + type ManifestWorkExpansion interface{} diff --git a/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/work_client.go b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/work_client.go index cada6d640..8187ff0b7 100644 --- a/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/work_client.go +++ b/vendor/github.com/open-cluster-management/api/client/work/clientset/versioned/typed/work/v1/work_client.go @@ -10,6 +10,7 @@ import ( type WorkV1Interface interface { RESTClient() rest.Interface + AppliedManifestWorksGetter ManifestWorksGetter } @@ -18,6 +19,10 @@ type WorkV1Client struct { restClient rest.Interface } +func (c *WorkV1Client) AppliedManifestWorks() AppliedManifestWorkInterface { + return newAppliedManifestWorks(c) +} + func (c *WorkV1Client) ManifestWorks(namespace string) ManifestWorkInterface { return newManifestWorks(c, namespace) } diff --git a/vendor/github.com/open-cluster-management/api/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml b/vendor/github.com/open-cluster-management/api/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml index 06bbc7748..3f145b017 100644 --- a/vendor/github.com/open-cluster-management/api/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml +++ b/vendor/github.com/open-cluster-management/api/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml @@ -59,45 +59,6 @@ spec: description: Status represents the current status of work type: object properties: - appliedResources: - description: AppliedResources represents a list of resources defined - within the manifestwork that are applied. Only resources with valid - GroupVersionResource, namespace, and name are suitable. An item in - this slice is deleted when there is no mapped manifest in manifestwork.Spec - or by finalizer. The resource relating to the item will also be removed - from managed cluster. The deleted resource may still be present until - the finalizers for that resource are finished. However, the resource - will not be undeleted, so it can be removed from this list and eventual - consistency is preserved. - type: array - items: - description: AppliedManifestResourceMeta represents the gvr, name - and namespace of a resource. Since these resources have been created, - they must have valid group, version, resource, namespace, and name. - type: object - properties: - group: - description: Group is the API Group of the kubernetes resource - type: string - name: - description: Name is the name of the kubernetes resource - type: string - namespace: - description: Name is the namespace of the kubernetes resource, - empty string indicates it is a cluster scoped resource. - type: string - resource: - description: Resource is the resource name of the kubernetes resource - type: string - uid: - description: UID is set on successful deletion of the kubernetes - resource by controller. The resource might be still visible - on the managed cluster after this field is set. It is not directly - settable by a client. - type: string - version: - description: Version is the version of the kubernetes resource - type: string conditions: description: 'Conditions contains the different condition statuses for this work. Valid condition types are: 1. Applied represents workload diff --git a/vendor/github.com/open-cluster-management/api/work/v1/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml b/vendor/github.com/open-cluster-management/api/work/v1/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml new file mode 100644 index 000000000..ce47cb420 --- /dev/null +++ b/vendor/github.com/open-cluster-management/api/work/v1/0000_01_work.open-cluster-management.io_appliedmanifestworks.crd.yaml @@ -0,0 +1,105 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: appliedmanifestworks.work.open-cluster-management.io +spec: + group: work.open-cluster-management.io + names: + kind: AppliedManifestWork + listKind: AppliedManifestWorkList + plural: appliedmanifestworks + singular: appliedmanifestwork + scope: "Cluster" + preserveUnknownFields: false + subresources: + status: {} + validation: + openAPIV3Schema: + description: AppliedManifestWork represents an applied manifestwork on managed + cluster. It is placed on managed cluster. An AppliedManifestWork links to + a manifestwork on a hub recording resources deployed in the managed cluster. + When the agent is removed from managed cluster, cluster-admin on managed cluster + can delete appliedmanifestwork to remove resources deployed by the agent. + The name of the appliedmanifestwork must be in the format of {hash of hub's + first kube-apiserver url}-{manifestwork name} + type: object + 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 desired configuration of AppliedManifestWork + type: object + properties: + hubHash: + description: HubHash represents the hash of the first hub kube apiserver + to identify which hub this AppliedManifestWork links to. + type: string + manifestWorkName: + description: ManifestWorkName represents the name of the related manifestwork + on hub. + type: string + status: + description: Status represents the current status of AppliedManifestWork + type: object + properties: + appliedResources: + description: AppliedResources represents a list of resources defined + within the manifestwork that are applied. Only resources with valid + GroupVersionResource, namespace, and name are suitable. An item in + this slice is deleted when there is no mapped manifest in manifestwork.Spec + or by finalizer. The resource relating to the item will also be removed + from managed cluster. The deleted resource may still be present until + the finalizers for that resource are finished. However, the resource + will not be undeleted, so it can be removed from this list and eventual + consistency is preserved. + type: array + items: + description: AppliedManifestResourceMeta represents the gvr, name + and namespace of a resource. Since these resources have been created, + they must have valid group, version, resource, namespace, and name. + type: object + properties: + group: + description: Group is the API Group of the kubernetes resource + type: string + name: + description: Name is the name of the kubernetes resource + type: string + namespace: + description: Name is the namespace of the kubernetes resource, + empty string indicates it is a cluster scoped resource. + type: string + resource: + description: Resource is the resource name of the kubernetes resource + type: string + uid: + description: UID is set on successful deletion of the kubernetes + resource by controller. The resource might be still visible + on the managed cluster after this field is set. It is not directly + settable by a client. + type: string + version: + description: Version is the version of the kubernetes resource + type: string + version: v1 + versions: + - name: v1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/vendor/github.com/open-cluster-management/api/work/v1/register.go b/vendor/github.com/open-cluster-management/api/work/v1/register.go index 563d9bf21..a65001402 100644 --- a/vendor/github.com/open-cluster-management/api/work/v1/register.go +++ b/vendor/github.com/open-cluster-management/api/work/v1/register.go @@ -32,6 +32,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(GroupVersion, &ManifestWork{}, &ManifestWorkList{}, + &AppliedManifestWork{}, + &AppliedManifestWorkList{}, ) metav1.AddToGroupVersion(scheme, GroupVersion) return nil diff --git a/vendor/github.com/open-cluster-management/api/work/v1/types.go b/vendor/github.com/open-cluster-management/api/work/v1/types.go index 13bebcc81..de22af61a 100644 --- a/vendor/github.com/open-cluster-management/api/work/v1/types.go +++ b/vendor/github.com/open-cluster-management/api/work/v1/types.go @@ -146,15 +146,6 @@ type ManifestWorkStatus struct { // managed cluster. The Klusterlet agent on managed cluster syncs the condition from managed to the hub. // +optional ResourceStatus ManifestResourceStatus `json:"resourceStatus,omitempty"` - - // AppliedResources represents a list of resources defined within the manifestwork that are applied. - // Only resources with valid GroupVersionResource, namespace, and name are suitable. - // An item in this slice is deleted when there is no mapped manifest in manifestwork.Spec or by finalizer. - // The resource relating to the item will also be removed from managed cluster. - // The deleted resource may still be present until the finalizers for that resource are finished. - // However, the resource will not be undeleted, so it can be removed from this list and eventual consistency is preserved. - // +optional - AppliedResources []AppliedManifestResourceMeta `json:"appliedResources,omitempty"` } // ManifestResourceStatus represents the status of each resource in manifest work deployed on @@ -231,3 +222,65 @@ type ManifestWorkList struct { // Items is a list of manifestworks. Items []ManifestWork `json:"items"` } + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:subresource:status +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AppliedManifestWork represents an applied manifestwork on managed cluster. It is placed +// on managed cluster. An AppliedManifestWork links to a manifestwork on a hub recording resources +// deployed in the managed cluster. +// When the agent is removed from managed cluster, cluster-admin on managed cluster +// can delete appliedmanifestwork to remove resources deployed by the agent. +// The name of the appliedmanifestwork must be in the format of +// {hash of hub's first kube-apiserver url}-{manifestwork name} +type AppliedManifestWork struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec represents the desired configuration of AppliedManifestWork + Spec AppliedManifestWorkSpec `json:"spec,omitempty"` + + // Status represents the current status of AppliedManifestWork + // +optional + Status AppliedManifestWorkStatus `json:"status,omitempty"` +} + +// AppliedManifestWorkSpec represents the desired configuration of AppliedManifestWork +type AppliedManifestWorkSpec struct { + // HubHash represents the hash of the first hub kube apiserver to identify which hub + // this AppliedManifestWork links to. + // +required + HubHash string `json:"hubHash"` + + // ManifestWorkName represents the name of the related manifestwork on hub. + // +required + ManifestWorkName string `json:"manifestWorkName"` +} + +// AppliedManifestWorkStatus represents the current status of AppliedManifestWork +type AppliedManifestWorkStatus struct { + // AppliedResources represents a list of resources defined within the manifestwork that are applied. + // Only resources with valid GroupVersionResource, namespace, and name are suitable. + // An item in this slice is deleted when there is no mapped manifest in manifestwork.Spec or by finalizer. + // The resource relating to the item will also be removed from managed cluster. + // The deleted resource may still be present until the finalizers for that resource are finished. + // However, the resource will not be undeleted, so it can be removed from this list and eventual consistency is preserved. + // +optional + AppliedResources []AppliedManifestResourceMeta `json:"appliedResources,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AppliedManifestWorkList is a collection of appliedmanifestworks. +type AppliedManifestWorkList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + // Items is a list of appliedmanifestworks. + Items []AppliedManifestWork `json:"items"` +} diff --git a/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.deepcopy.go b/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.deepcopy.go index 1307ab6eb..86a50a280 100644 --- a/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.deepcopy.go @@ -24,6 +24,104 @@ func (in *AppliedManifestResourceMeta) DeepCopy() *AppliedManifestResourceMeta { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppliedManifestWork) DeepCopyInto(out *AppliedManifestWork) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedManifestWork. +func (in *AppliedManifestWork) DeepCopy() *AppliedManifestWork { + if in == nil { + return nil + } + out := new(AppliedManifestWork) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppliedManifestWork) 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 *AppliedManifestWorkList) DeepCopyInto(out *AppliedManifestWorkList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AppliedManifestWork, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedManifestWorkList. +func (in *AppliedManifestWorkList) DeepCopy() *AppliedManifestWorkList { + if in == nil { + return nil + } + out := new(AppliedManifestWorkList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppliedManifestWorkList) 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 *AppliedManifestWorkSpec) DeepCopyInto(out *AppliedManifestWorkSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedManifestWorkSpec. +func (in *AppliedManifestWorkSpec) DeepCopy() *AppliedManifestWorkSpec { + if in == nil { + return nil + } + out := new(AppliedManifestWorkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppliedManifestWorkStatus) DeepCopyInto(out *AppliedManifestWorkStatus) { + *out = *in + if in.AppliedResources != nil { + in, out := &in.AppliedResources, &out.AppliedResources + *out = make([]AppliedManifestResourceMeta, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedManifestWorkStatus. +func (in *AppliedManifestWorkStatus) DeepCopy() *AppliedManifestWorkStatus { + if in == nil { + return nil + } + out := new(AppliedManifestWorkStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Manifest) DeepCopyInto(out *Manifest) { *out = *in @@ -193,11 +291,6 @@ func (in *ManifestWorkStatus) DeepCopyInto(out *ManifestWorkStatus) { } } in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) - if in.AppliedResources != nil { - in, out := &in.AppliedResources, &out.AppliedResources - *out = make([]AppliedManifestResourceMeta, len(*in)) - copy(*out, *in) - } return } diff --git a/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.swagger_doc_generated.go index 5baf7f6b9..35bee8b2c 100644 --- a/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/open-cluster-management/api/work/v1/zz_generated.swagger_doc_generated.go @@ -25,6 +25,45 @@ func (AppliedManifestResourceMeta) SwaggerDoc() map[string]string { return map_AppliedManifestResourceMeta } +var map_AppliedManifestWork = map[string]string{ + "": "AppliedManifestWork represents an applied manifestwork on managed cluster. It is placed on managed cluster. An AppliedManifestWork links to a manifestwork on a hub recording resources deployed in the managed cluster. When the agent is removed from managed cluster, cluster-admin on managed cluster can delete appliedmanifestwork to remove resources deployed by the agent. The name of the appliedmanifestwork must be in the format of {hash of hub's first kube-apiserver url}-{manifestwork name}", + "spec": "Spec represents the desired configuration of AppliedManifestWork", + "status": "Status represents the current status of AppliedManifestWork", +} + +func (AppliedManifestWork) SwaggerDoc() map[string]string { + return map_AppliedManifestWork +} + +var map_AppliedManifestWorkList = map[string]string{ + "": "AppliedManifestWorkList is a collection of appliedmanifestworks.", + "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", + "items": "Items is a list of appliedmanifestworks.", +} + +func (AppliedManifestWorkList) SwaggerDoc() map[string]string { + return map_AppliedManifestWorkList +} + +var map_AppliedManifestWorkSpec = map[string]string{ + "": "AppliedManifestWorkSpec represents the desired configuration of AppliedManifestWork", + "hubHash": "HubHash represents the hash of the first hub kube apiserver to identify which hub this AppliedManifestWork links to.", + "manifestWorkName": "ManifestWorkName represents the name of the related manifestwork on hub.", +} + +func (AppliedManifestWorkSpec) SwaggerDoc() map[string]string { + return map_AppliedManifestWorkSpec +} + +var map_AppliedManifestWorkStatus = map[string]string{ + "": "AppliedManifestWorkStatus represents the current status of AppliedManifestWork", + "appliedResources": "AppliedResources represents a list of resources defined within the manifestwork that are applied. Only resources with valid GroupVersionResource, namespace, and name are suitable. An item in this slice is deleted when there is no mapped manifest in manifestwork.Spec or by finalizer. The resource relating to the item will also be removed from managed cluster. The deleted resource may still be present until the finalizers for that resource are finished. However, the resource will not be undeleted, so it can be removed from this list and eventual consistency is preserved.", +} + +func (AppliedManifestWorkStatus) SwaggerDoc() map[string]string { + return map_AppliedManifestWorkStatus +} + var map_Manifest = map[string]string{ "": "Manifest represents a resource to be deployed on managed cluster", } @@ -97,10 +136,9 @@ func (ManifestWorkSpec) SwaggerDoc() map[string]string { } var map_ManifestWorkStatus = map[string]string{ - "": "ManifestWorkStatus represents the current status of managed cluster ManifestWork", - "conditions": "Conditions contains the different condition statuses for this work. Valid condition types are: 1. Applied represents workload in ManifestWork is applied successfully on managed cluster. 2. Progressing represents workload in ManifestWork is being applied on managed cluster. 3. Available represents workload in ManifestWork exists on the managed cluster. 4. Degraded represents the current state of workload does not match the desired state for a certain period.", - "resourceStatus": "ResourceStatus represents the status of each resource in manifestwork deployed on managed cluster. The Klusterlet agent on managed cluster syncs the condition from managed to the hub.", - "appliedResources": "AppliedResources represents a list of resources defined within the manifestwork that are applied. Only resources with valid GroupVersionResource, namespace, and name are suitable. An item in this slice is deleted when there is no mapped manifest in manifestwork.Spec or by finalizer. The resource relating to the item will also be removed from managed cluster. The deleted resource may still be present until the finalizers for that resource are finished. However, the resource will not be undeleted, so it can be removed from this list and eventual consistency is preserved.", + "": "ManifestWorkStatus represents the current status of managed cluster ManifestWork", + "conditions": "Conditions contains the different condition statuses for this work. Valid condition types are: 1. Applied represents workload in ManifestWork is applied successfully on managed cluster. 2. Progressing represents workload in ManifestWork is being applied on managed cluster. 3. Available represents workload in ManifestWork exists on the managed cluster. 4. Degraded represents the current state of workload does not match the desired state for a certain period.", + "resourceStatus": "ResourceStatus represents the status of each resource in manifestwork deployed on managed cluster. The Klusterlet agent on managed cluster syncs the condition from managed to the hub.", } func (ManifestWorkStatus) SwaggerDoc() map[string]string { diff --git a/vendor/modules.txt b/vendor/modules.txt index 97fa35256..1bd61bbb5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -133,7 +133,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/open-cluster-management/api v0.0.0-20200629211334-8be047b65c52 +# github.com/open-cluster-management/api v0.0.0-20200715201722-3c3c076bf062 github.com/open-cluster-management/api/client/cluster/clientset/versioned github.com/open-cluster-management/api/client/cluster/clientset/versioned/scheme github.com/open-cluster-management/api/client/cluster/clientset/versioned/typed/cluster/v1