mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-05-22 00:54:00 +00:00
Merge pull request #24 from qiujian16/mdelder-adopt-api-1
adopt new operator api
This commit is contained in:
46
Makefile
46
Makefile
@@ -40,13 +40,13 @@ ifeq ($(GOHOSTOS),darwin)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(call add-bindata,hub,./manifests/hub/...,bindata,bindata,./pkg/operators/hub/bindata/bindata.go)
|
||||
$(call add-bindata,spoke,./manifests/spoke/...,bindata,bindata,./pkg/operators/spoke/bindata/bindata.go)
|
||||
$(call add-bindata,cluster-manager,./manifests/cluster-manager/...,bindata,bindata,./pkg/operators/clustermanager/bindata/bindata.go)
|
||||
$(call add-bindata,klusterlet,./manifests/klusterlet/...,bindata,bindata,./pkg/operators/klusterlet/bindata/bindata.go)
|
||||
|
||||
copy-crd:
|
||||
bash -x hack/copy-crds.sh
|
||||
|
||||
update-all: copy-crd update-bindata-hub update-bindata-spoke update-csv
|
||||
update-all: copy-crd update-bindata-cluster-manager update-bindata-klusterlet update-csv
|
||||
|
||||
verify-crds:
|
||||
bash -x hack/verify-crds.sh
|
||||
@@ -54,22 +54,22 @@ verify-crds:
|
||||
verify: verify-crds
|
||||
|
||||
update-csv: ensure-operator-sdk
|
||||
$(OPERATOR_SDK) generate csv --crd-dir=deploy/nucleus-hub/crds --deploy-dir=deploy/nucleus-hub --output-dir=deploy/nucleus-hub/olm-catalog/nucleus-hub --operator-name=nucleus-hub --csv-version=0.1.0
|
||||
$(OPERATOR_SDK) generate csv --crd-dir=deploy/nucleus-spoke/crds --deploy-dir=deploy/nucleus-spoke --output-dir=deploy/nucleus-spoke/olm-catalog/nucleus-spoke --operator-name=nucleus-spoke --csv-version=0.1.0
|
||||
$(OPERATOR_SDK) generate csv --crd-dir=deploy/cluster-manager/crds --deploy-dir=deploy/cluster-manager --output-dir=deploy/cluster-manager/olm-catalog/cluster-manager --operator-name=cluster-manager --csv-version=0.1.0
|
||||
$(OPERATOR_SDK) generate csv --crd-dir=deploy/klusterlet/crds --deploy-dir=deploy/klusterlet --output-dir=deploy/klusterlet/olm-catalog/klusterlet --operator-name=klusterlet --csv-version=0.1.0
|
||||
|
||||
munge-hub-csv:
|
||||
mkdir -p munge-csv
|
||||
cp deploy/nucleus-hub/olm-catalog/nucleus-hub/manifests/nucleus-hub.clusterserviceversion.yaml munge-csv/nucleus-hub.clusterserviceversion.yaml.unmunged
|
||||
sed -e "s,quay.io/open-cluster-management/nucleus:latest,$(IMAGE_NAME)," -i deploy/nucleus-hub/olm-catalog/nucleus-hub/manifests/nucleus-hub.clusterserviceversion.yaml
|
||||
cp deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml munge-csv/cluster-manager.clusterserviceversion.yaml.unmunged
|
||||
sed -e "s,quay.io/open-cluster-management/nucleus:latest,$(IMAGE_NAME)," -i deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml
|
||||
|
||||
munge-spoke-csv:
|
||||
mkdir -p munge-csv
|
||||
cp deploy/nucleus-spoke/olm-catalog/nucleus-spoke/manifests/nucleus-spoke.clusterserviceversion.yaml munge-csv/nucleus-spoke.clusterserviceversion.yaml.unmunged
|
||||
sed -e "s,quay.io/open-cluster-management/nucleus:latest,$(IMAGE_NAME)," -i deploy/nucleus-spoke/olm-catalog/nucleus-spoke/manifests/nucleus-spoke.clusterserviceversion.yaml
|
||||
cp deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml munge-csv/klusterlet.clusterserviceversion.yaml.unmunged
|
||||
sed -e "s,quay.io/open-cluster-management/nucleus:latest,$(IMAGE_NAME)," -i deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml
|
||||
|
||||
unmunge-csv:
|
||||
mv munge-csv/nucleus-hub.clusterserviceversion.yaml.unmunged deploy/nucleus-hub/olm-catalog/nucleus-hub/manifests/nucleus-hub.clusterserviceversion.yaml
|
||||
mv munge-csv/nucleus-spoke.clusterserviceversion.yaml.unmunged deploy/nucleus-spoke/olm-catalog/nucleus-spoke/manifests/nucleus-spoke.clusterserviceversion.yaml
|
||||
mv munge-csv/cluster-manager.clusterserviceversion.yaml.unmunged deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml
|
||||
mv munge-csv/klusterlet.clusterserviceversion.yaml.unmunged deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml
|
||||
|
||||
deploy: install-olm deploy-hub deploy-spoke unmunge-csv
|
||||
|
||||
@@ -80,22 +80,22 @@ install-olm: ensure-operator-sdk
|
||||
$(KUBECTL) get ns open-cluster-management ; if [ $$? -ne 0 ] ; then $(KUBECTL) create ns open-cluster-management ; fi
|
||||
|
||||
deploy-hub: install-olm munge-hub-csv
|
||||
$(OPERATOR_SDK) run --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/nucleus-hub/olm-catalog/nucleus-hub --olm-namespace $(OLM_NAMESPACE)
|
||||
sed -e "s,quay.io/open-cluster-management/registration,$(REGISTRATION_IMAGE)," deploy/nucleus-hub/crds/nucleus_open-cluster-management_hubcores.cr.yaml | $(KUBECTL) apply -f -
|
||||
$(OPERATOR_SDK) run --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/cluster-manager/olm-catalog/cluster-manager --olm-namespace $(OLM_NAMESPACE) --timeout 10m
|
||||
sed -e "s,quay.io/open-cluster-management/registration,$(REGISTRATION_IMAGE)," deploy/cluster-manager/crds/operator_open-cluster-management_clustermanagers.cr.yaml | $(KUBECTL) apply -f -
|
||||
|
||||
clean-hub: ensure-operator-sdk
|
||||
$(KUBECTL) delete -f deploy/nucleus-hub/crds/nucleus_open-cluster-management_hubcores.cr.yaml --ignore-not-found
|
||||
$(OPERATOR_SDK) cleanup --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/nucleus-hub/olm-catalog/nucleus-hub --olm-namespace $(OLM_NAMESPACE)
|
||||
$(KUBECTL) delete -f deploy/cluster-manager/crds/operator_open-cluster-management_clustermanagers.cr.yaml --ignore-not-found
|
||||
$(OPERATOR_SDK) cleanup --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/cluster-manager/olm-catalog/cluster-manager --olm-namespace $(OLM_NAMESPACE) --timeout 10m
|
||||
|
||||
cluster-ip:
|
||||
cluster-ip:
|
||||
CLUSTER_IP?=$(shell $(KUBECTL) get svc kubernetes -n default -o jsonpath="{.spec.clusterIP}")
|
||||
|
||||
bootstrap-secret: cluster-ip
|
||||
$(KUBECTL) get ns open-cluster-management-spoke ; if [ $$? -ne 0 ] ; then $(KUBECTL) create ns open-cluster-management-spoke ; fi
|
||||
$(KUBECTL) get ns open-cluster-management-agent ; if [ $$? -ne 0 ] ; then $(KUBECTL) create ns open-cluster-management-agent ; fi
|
||||
cp $(KUBECONFIG) dev-kubeconfig
|
||||
$(KUBECTL) config set clusters.kind-kind.server https://$(CLUSTER_IP) --kubeconfig dev-kubeconfig
|
||||
$(KUBECTL) delete secret bootstrap-hub-kubeconfig -n open-cluster-management-spoke --ignore-not-found
|
||||
$(KUBECTL) create secret generic bootstrap-hub-kubeconfig --from-file=kubeconfig=dev-kubeconfig -n open-cluster-management-spoke
|
||||
$(KUBECTL) delete secret bootstrap-hub-kubeconfig -n open-cluster-management-agent --ignore-not-found
|
||||
$(KUBECTL) create secret generic bootstrap-hub-kubeconfig --from-file=kubeconfig=dev-kubeconfig -n open-cluster-management-agent
|
||||
|
||||
# Registration e2e expects to read bootstrap secret from open-cluster-management/e2e-bootstrap-secret
|
||||
# TODO: think about how to factor this
|
||||
@@ -106,12 +106,12 @@ e2e-bootstrap-secret: cluster-ip
|
||||
$(KUBECTL) create secret generic e2e-bootstrap-secret --from-file=kubeconfig=e2e-kubeconfig -n open-cluster-management
|
||||
|
||||
deploy-spoke: install-olm munge-spoke-csv bootstrap-secret
|
||||
$(OPERATOR_SDK) run --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/nucleus-spoke/olm-catalog/nucleus-spoke --olm-namespace $(OLM_NAMESPACE)
|
||||
sed -e "s,quay.io/open-cluster-management/registration,$(REGISTRATION_IMAGE)," -e "s,quay.io/open-cluster-management/work,$(WORK_IMAGE)," deploy/nucleus-spoke/crds/nucleus_open-cluster-management_spokecores.cr.yaml | $(KUBECTL) apply -f -
|
||||
$(OPERATOR_SDK) run --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/klusterlet/olm-catalog/klusterlet --olm-namespace $(OLM_NAMESPACE) --timeout 10m
|
||||
sed -e "s,quay.io/open-cluster-management/registration,$(REGISTRATION_IMAGE)," -e "s,quay.io/open-cluster-management/work,$(WORK_IMAGE)," deploy/klusterlet/crds/operator_open-cluster-management_klusterlets.cr.yaml | $(KUBECTL) apply -f -
|
||||
|
||||
clean-spoke: ensure-operator-sdk
|
||||
$(KUBECTL) delete -f deploy/nucleus-spoke/crds/nucleus_open-cluster-management_spokecores.cr.yaml --ignore-not-found
|
||||
$(OPERATOR_SDK) cleanup --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/nucleus-spoke/olm-catalog/nucleus-spoke --olm-namespace $(OLM_NAMESPACE)
|
||||
$(KUBECTL) delete -f deploy/klusterlet/crds/operator_open-cluster-management_klusterlets.cr.yaml --ignore-not-found
|
||||
$(OPERATOR_SDK) cleanup --olm --operator-namespace open-cluster-management --operator-version 0.1.0 --manifests deploy/klusterlet/olm-catalog/klusterlet --olm-namespace $(OLM_NAMESPACE) --timeout 10m
|
||||
|
||||
ensure-operator-sdk:
|
||||
ifeq "" "$(wildcard $(OPERATOR_SDK))"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: nucleus-hub
|
||||
name: cluster-manager
|
||||
rules:
|
||||
# Allow nucleus to create workload
|
||||
# Allow the nucleus to create workload
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "namespaces", "serviceaccounts", "services", "secrets"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
@@ -22,22 +22,22 @@ rules:
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"]
|
||||
# Allow nucleus to create crds
|
||||
# Allow the nucleus to create crds
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
# Allow nucleus to create apiservice
|
||||
# Allow the nucleus to create apiservice
|
||||
- apiGroups: ["apiregistration.k8s.io"]
|
||||
resources: ["apiservices"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
# Allow nucleus to create validatingwebhookconfigurration
|
||||
# Allow the nucleus to create validatingwebhookconfigurration
|
||||
- apiGroups: ["admissionregistration.k8s.io"]
|
||||
resources: ["validatingwebhookconfigurations"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
# Allow nuclues to manage nucleus apis.
|
||||
- apiGroups: ["nucleus.open-cluster-management.io"]
|
||||
resources: ["hubcores"]
|
||||
# Allow the nuclues to manage clustermanager apis.
|
||||
- apiGroups: ["operator.open-cluster-management.io"]
|
||||
resources: ["clustermanagers"]
|
||||
verbs: ["get", "list", "watch", "update", "delete"]
|
||||
- apiGroups: ["nucleus.open-cluster-management.io"]
|
||||
resources: ["hubcores/status"]
|
||||
- apiGroups: ["operator.open-cluster-management.io"]
|
||||
resources: ["clustermanagers/status"]
|
||||
verbs: ["update", "patch"]
|
||||
@@ -1,12 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: nucleus-spoke
|
||||
name: cluster-manager
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: nucleus-spoke
|
||||
name: cluster-manager
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nucleus-spoke
|
||||
name: cluster-manager
|
||||
namespace: open-cluster-management
|
||||
@@ -2,21 +2,22 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: hubcores.nucleus.open-cluster-management.io
|
||||
name: clustermanagers.operator.open-cluster-management.io
|
||||
spec:
|
||||
group: nucleus.open-cluster-management.io
|
||||
group: operator.open-cluster-management.io
|
||||
names:
|
||||
kind: HubCore
|
||||
listKind: HubCoreList
|
||||
plural: hubcores
|
||||
singular: hubcore
|
||||
kind: ClusterManager
|
||||
listKind: ClusterManagerList
|
||||
plural: clustermanagers
|
||||
singular: clustermanager
|
||||
scope: Cluster
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: HubCore represents a deployment of nucleus hub core component.
|
||||
HubCore will be only deployed in open-cluster-management namespace.
|
||||
description: ClusterManager configures the controllers on the hub that govern
|
||||
registration and work distribution for attached klusterlets. ClusterManager
|
||||
will be only deployed in open-cluster-management-hub namespace.
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -32,8 +33,8 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec represents a desired deployment configuration of nucleus
|
||||
hub
|
||||
description: Spec represents a desired deployment configuration of controllers
|
||||
that govern registration and work distribution for attached klusterlets.
|
||||
type: object
|
||||
properties:
|
||||
registrationImagePullSpec:
|
||||
@@ -41,15 +42,16 @@ spec:
|
||||
of registration controller installed on hub.
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of nucleus hub
|
||||
description: Status represents the current status of controllers that govern
|
||||
the lifecycle of managed clusters.
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
description: 'Conditions contain the different condition statuses for
|
||||
this hubcore. Valid condition types are: Applied: components in hub
|
||||
is applied. Available: components in hub are available and ready to
|
||||
serve. Progressing: components in hub are in a transitioning state.
|
||||
Degraded: components in hub do not match the desired configuration
|
||||
this ClusterManager. Valid condition types are: Applied: components
|
||||
in hub are applied. Available: components in hub are available and
|
||||
ready to serve. Progressing: components in hub are in a transitioning
|
||||
state. Degraded: components in hub do not match the desired configuration
|
||||
and only provide degraded service.'
|
||||
type: array
|
||||
items:
|
||||
@@ -81,6 +83,7 @@ spec:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
preserveUnknownFields: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: operator.open-cluster-management.io/v1
|
||||
kind: ClusterManager
|
||||
metadata:
|
||||
name: cluster-manager
|
||||
spec:
|
||||
registrationImagePullSpec: quay.io/open-cluster-management/registration
|
||||
@@ -2,21 +2,22 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: hubcores.nucleus.open-cluster-management.io
|
||||
name: clustermanagers.operator.open-cluster-management.io
|
||||
spec:
|
||||
group: nucleus.open-cluster-management.io
|
||||
group: operator.open-cluster-management.io
|
||||
names:
|
||||
kind: HubCore
|
||||
listKind: HubCoreList
|
||||
plural: hubcores
|
||||
singular: hubcore
|
||||
kind: ClusterManager
|
||||
listKind: ClusterManagerList
|
||||
plural: clustermanagers
|
||||
singular: clustermanager
|
||||
scope: Cluster
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: HubCore represents a deployment of nucleus hub core component.
|
||||
HubCore will be only deployed in open-cluster-management namespace.
|
||||
description: ClusterManager configures the controllers on the hub that govern
|
||||
registration and work distribution for attached klusterlets. ClusterManager
|
||||
will be only deployed in open-cluster-management-hub namespace.
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -32,8 +33,8 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec represents a desired deployment configuration of nucleus
|
||||
hub
|
||||
description: Spec represents a desired deployment configuration of controllers
|
||||
that govern registration and work distribution for attached klusterlets.
|
||||
type: object
|
||||
properties:
|
||||
registrationImagePullSpec:
|
||||
@@ -41,15 +42,16 @@ spec:
|
||||
of registration controller installed on hub.
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of nucleus hub
|
||||
description: Status represents the current status of controllers that govern
|
||||
the lifecycle of managed clusters.
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
description: 'Conditions contain the different condition statuses for
|
||||
this hubcore. Valid condition types are: Applied: components in hub
|
||||
is applied. Available: components in hub are available and ready to
|
||||
serve. Progressing: components in hub are in a transitioning state.
|
||||
Degraded: components in hub do not match the desired configuration
|
||||
this ClusterManager. Valid condition types are: Applied: components
|
||||
in hub are applied. Available: components in hub are available and
|
||||
ready to serve. Progressing: components in hub are in a transitioning
|
||||
state. Degraded: components in hub do not match the desired configuration
|
||||
and only provide degraded service.'
|
||||
type: array
|
||||
items:
|
||||
@@ -81,6 +83,7 @@ spec:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
preserveUnknownFields: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
@@ -5,10 +5,10 @@ metadata:
|
||||
alm-examples: |-
|
||||
[
|
||||
{
|
||||
"apiVersion": "nucleus.open-cluster-management.io/v1",
|
||||
"kind": "HubCore",
|
||||
"apiVersion": "operator.open-cluster-management.io/v1",
|
||||
"kind": "ClusterManager",
|
||||
"metadata": {
|
||||
"name": "hub"
|
||||
"name": "cluster-manager"
|
||||
},
|
||||
"spec": {
|
||||
"registrationImagePullSpec": "quay.io/open-cluster-management/registration"
|
||||
@@ -16,16 +16,16 @@ metadata:
|
||||
}
|
||||
]
|
||||
capabilities: Basic Install
|
||||
name: nucleus-hub.v0.1.0
|
||||
name: cluster-manager.v0.1.0
|
||||
namespace: placeholder
|
||||
spec:
|
||||
apiservicedefinitions: {}
|
||||
customresourcedefinitions:
|
||||
owned:
|
||||
- kind: HubCore
|
||||
name: hubcores.nucleus.open-cluster-management.io
|
||||
- kind: ClusterManager
|
||||
name: clustermanagers.operator.open-cluster-management.io
|
||||
version: v1
|
||||
displayName: Nucleus Hub
|
||||
displayName: Cluster Manager
|
||||
icon:
|
||||
- base64data: ""
|
||||
mediatype: ""
|
||||
@@ -141,9 +141,9 @@ spec:
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- nucleus.open-cluster-management.io
|
||||
- operator.open-cluster-management.io
|
||||
resources:
|
||||
- hubcores
|
||||
- clustermanagers
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
@@ -151,25 +151,25 @@ spec:
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- nucleus.open-cluster-management.io
|
||||
- operator.open-cluster-management.io
|
||||
resources:
|
||||
- hubcores/status
|
||||
- clustermanagers/status
|
||||
verbs:
|
||||
- update
|
||||
- patch
|
||||
serviceAccountName: nucleus-hub
|
||||
serviceAccountName: cluster-manager
|
||||
deployments:
|
||||
- name: nucleus-hub
|
||||
- name: cluster-manager
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleus-hub
|
||||
app: cluster-manager
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleus-hub
|
||||
app: cluster-manager
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
@@ -192,7 +192,7 @@ spec:
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 2
|
||||
resources: {}
|
||||
serviceAccountName: nucleus-hub
|
||||
serviceAccountName: cluster-manager
|
||||
strategy: deployment
|
||||
installModes:
|
||||
- supported: true
|
||||
@@ -0,0 +1,7 @@
|
||||
annotations:
|
||||
operators.operatorframework.io.bundle.channel.default.v1: stable
|
||||
operators.operatorframework.io.bundle.channels.v1: stable
|
||||
operators.operatorframework.io.bundle.manifests.v1: manifests/
|
||||
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
|
||||
operators.operatorframework.io.bundle.metadata.v1: metadata/
|
||||
operators.operatorframework.io.bundle.package.v1: cluster-manager
|
||||
@@ -1,21 +1,21 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: nucleus-hub
|
||||
name: cluster-manager
|
||||
namespace: open-cluster-management
|
||||
labels:
|
||||
app: nucleus-hub
|
||||
app: cluster-manager
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleus-hub
|
||||
app: cluster-manager
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleus-hub
|
||||
app: cluster-manager
|
||||
spec:
|
||||
serviceAccountName: nucleus-hub
|
||||
serviceAccountName: cluster-manager
|
||||
containers:
|
||||
- name: nucleus-operator
|
||||
image: quay.io/open-cluster-management/nucleus:latest
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: nucleus-spoke
|
||||
name: cluster-manager
|
||||
namespace: open-cluster-management
|
||||
@@ -1,9 +1,9 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: nucleus-spoke
|
||||
name: klusterlet
|
||||
rules:
|
||||
# Allow nucleus to create workload
|
||||
# Allow the nucleus to create workload
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets", "configmaps", "serviceaccounts"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
|
||||
@@ -25,10 +25,10 @@ rules:
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "escalate", "bind"]
|
||||
# Allow nucleus to manage nucleus apis.
|
||||
- apiGroups: ["nucleus.open-cluster-management.io"]
|
||||
resources: ["spokecores"]
|
||||
# Allow the nucleus to manage klusterlet apis.
|
||||
- apiGroups: ["operator.open-cluster-management.io"]
|
||||
resources: ["klusterlets"]
|
||||
verbs: ["get", "list", "watch", "update", "patch", "delete"]
|
||||
- apiGroups: ["nucleus.open-cluster-management.io"]
|
||||
resources: ["spokecores/status"]
|
||||
- apiGroups: ["operator.open-cluster-management.io"]
|
||||
resources: ["klusterlets/status"]
|
||||
verbs: ["update", "patch"]
|
||||
@@ -1,12 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: nucleus-hub
|
||||
name: klusterlet
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: nucleus-hub
|
||||
name: klusterlet
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: nucleus-hub
|
||||
name: klusterlet
|
||||
namespace: open-cluster-management
|
||||
@@ -2,23 +2,23 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: spokecores.nucleus.open-cluster-management.io
|
||||
name: klusterlets.operator.open-cluster-management.io
|
||||
spec:
|
||||
group: nucleus.open-cluster-management.io
|
||||
group: operator.open-cluster-management.io
|
||||
names:
|
||||
kind: SpokeCore
|
||||
listKind: SpokeCoreList
|
||||
plural: spokecores
|
||||
singular: spokecore
|
||||
kind: Klusterlet
|
||||
listKind: KlusterletList
|
||||
plural: klusterlets
|
||||
singular: klusterlet
|
||||
scope: Cluster
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: SpokeCore represents a deployment of nucleus core agent on spoke
|
||||
cluster. When the deployment of spoke core agent is deployed, it will requires
|
||||
a secret with the name of bootstrap-hub-kubeconfig in the namespace defined
|
||||
in the spec.
|
||||
description: Klusterlet represents controllers on the managed cluster. When
|
||||
configured, the Klusterlet requires a secret named of bootstrap-hub-kubeconfig
|
||||
in the same namespace to allow API requests to the hub for the registration
|
||||
protocol.
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -34,7 +34,7 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec represents the desired deployment configuratioin of nucleus
|
||||
description: Spec represents the desired deployment configuration of klusterlet
|
||||
agent.
|
||||
type: object
|
||||
properties:
|
||||
@@ -65,7 +65,7 @@ spec:
|
||||
namespace:
|
||||
description: Namespace is the namespace to deploy the agent. The namespace
|
||||
must have a prefix of "open-cluster-management-", and if it is not
|
||||
set, the namespace of "open-cluster-management" is used to deploy
|
||||
set, the namespace of "open-cluster-management-spoke" is used to deploy
|
||||
agent.
|
||||
type: string
|
||||
registrationImagePullSpec:
|
||||
@@ -77,7 +77,7 @@ spec:
|
||||
of work agent.
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of nucleus agent.
|
||||
description: Status represents the current status of klusterlet agent.
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
@@ -117,6 +117,7 @@ spec:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
preserveUnknownFields: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
@@ -1,11 +1,11 @@
|
||||
apiVersion: nucleus.open-cluster-management.io/v1
|
||||
kind: SpokeCore
|
||||
apiVersion: operator.open-cluster-management.io/v1
|
||||
kind: Klusterlet
|
||||
metadata:
|
||||
name: spoke
|
||||
name: klusterlet
|
||||
spec:
|
||||
registrationImagePullSpec: quay.io/open-cluster-management/registration
|
||||
workImagePullSpec: quay.io/open-cluster-management/work
|
||||
clusterName: cluster1
|
||||
namespace: open-cluster-management-spoke
|
||||
namespace: open-cluster-management-agent
|
||||
externalServerURLs:
|
||||
- url: https://localhost
|
||||
- url: https://localhost
|
||||
@@ -2,23 +2,23 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: spokecores.nucleus.open-cluster-management.io
|
||||
name: klusterlets.operator.open-cluster-management.io
|
||||
spec:
|
||||
group: nucleus.open-cluster-management.io
|
||||
group: operator.open-cluster-management.io
|
||||
names:
|
||||
kind: SpokeCore
|
||||
listKind: SpokeCoreList
|
||||
plural: spokecores
|
||||
singular: spokecore
|
||||
kind: Klusterlet
|
||||
listKind: KlusterletList
|
||||
plural: klusterlets
|
||||
singular: klusterlet
|
||||
scope: Cluster
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: SpokeCore represents a deployment of nucleus core agent on spoke
|
||||
cluster. When the deployment of spoke core agent is deployed, it will requires
|
||||
a secret with the name of bootstrap-hub-kubeconfig in the namespace defined
|
||||
in the spec.
|
||||
description: Klusterlet represents controllers on the managed cluster. When
|
||||
configured, the Klusterlet requires a secret named of bootstrap-hub-kubeconfig
|
||||
in the same namespace to allow API requests to the hub for the registration
|
||||
protocol.
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -34,7 +34,7 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: Spec represents the desired deployment configuratioin of nucleus
|
||||
description: Spec represents the desired deployment configuration of klusterlet
|
||||
agent.
|
||||
type: object
|
||||
properties:
|
||||
@@ -65,7 +65,7 @@ spec:
|
||||
namespace:
|
||||
description: Namespace is the namespace to deploy the agent. The namespace
|
||||
must have a prefix of "open-cluster-management-", and if it is not
|
||||
set, the namespace of "open-cluster-management" is used to deploy
|
||||
set, the namespace of "open-cluster-management-spoke" is used to deploy
|
||||
agent.
|
||||
type: string
|
||||
registrationImagePullSpec:
|
||||
@@ -77,7 +77,7 @@ spec:
|
||||
of work agent.
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of nucleus agent.
|
||||
description: Status represents the current status of klusterlet agent.
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
@@ -117,6 +117,7 @@ spec:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
preserveUnknownFields: false
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
@@ -5,10 +5,10 @@ metadata:
|
||||
alm-examples: |-
|
||||
[
|
||||
{
|
||||
"apiVersion": "nucleus.open-cluster-management.io/v1",
|
||||
"kind": "SpokeCore",
|
||||
"apiVersion": "operator.open-cluster-management.io/v1",
|
||||
"kind": "Klusterlet",
|
||||
"metadata": {
|
||||
"name": "spoke"
|
||||
"name": "klusterlet"
|
||||
},
|
||||
"spec": {
|
||||
"clusterName": "cluster1",
|
||||
@@ -17,23 +17,23 @@ metadata:
|
||||
"url": "https://localhost"
|
||||
}
|
||||
],
|
||||
"namespace": "open-cluster-management-spoke",
|
||||
"namespace": "open-cluster-management-agent",
|
||||
"registrationImagePullSpec": "quay.io/open-cluster-management/registration",
|
||||
"workImagePullSpec": "quay.io/open-cluster-management/work"
|
||||
}
|
||||
}
|
||||
]
|
||||
capabilities: Basic Install
|
||||
name: nucleus-spoke.v0.1.0
|
||||
name: klusterlet.v0.1.0
|
||||
namespace: placeholder
|
||||
spec:
|
||||
apiservicedefinitions: {}
|
||||
customresourcedefinitions:
|
||||
owned:
|
||||
- kind: SpokeCore
|
||||
name: spokecores.nucleus.open-cluster-management.io
|
||||
- kind: Klusterlet
|
||||
name: klusterlets.operator.open-cluster-management.io
|
||||
version: v1
|
||||
displayName: Nucleus Spoke
|
||||
displayName: Klusterlet
|
||||
icon:
|
||||
- base64data: ""
|
||||
mediatype: ""
|
||||
@@ -120,9 +120,9 @@ spec:
|
||||
- escalate
|
||||
- bind
|
||||
- apiGroups:
|
||||
- nucleus.open-cluster-management.io
|
||||
- operator.open-cluster-management.io
|
||||
resources:
|
||||
- spokecores
|
||||
- klusterlets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
@@ -131,25 +131,25 @@ spec:
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- nucleus.open-cluster-management.io
|
||||
- operator.open-cluster-management.io
|
||||
resources:
|
||||
- spokecores/status
|
||||
- klusterlets/status
|
||||
verbs:
|
||||
- update
|
||||
- patch
|
||||
serviceAccountName: nucleus-spoke
|
||||
serviceAccountName: klusterlet
|
||||
deployments:
|
||||
- name: nucleus-spoke
|
||||
- name: klusterlet
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleus-spoke
|
||||
app: klusterlet
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleus-spoke
|
||||
app: klusterlet
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
@@ -164,7 +164,7 @@ spec:
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
name: nucleus-spoke
|
||||
name: klusterlet
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
@@ -172,7 +172,7 @@ spec:
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 2
|
||||
resources: {}
|
||||
serviceAccountName: nucleus-spoke
|
||||
serviceAccountName: klusterlet
|
||||
strategy: deployment
|
||||
installModes:
|
||||
- supported: true
|
||||
@@ -188,6 +188,5 @@ spec:
|
||||
maintainers:
|
||||
- {}
|
||||
maturity: alpha
|
||||
provider:
|
||||
name: open-cluster-management
|
||||
provider: {}
|
||||
version: 0.1.0
|
||||
@@ -0,0 +1,7 @@
|
||||
annotations:
|
||||
operators.operatorframework.io.bundle.channel.default.v1: stable
|
||||
operators.operatorframework.io.bundle.channels.v1: stable
|
||||
operators.operatorframework.io.bundle.manifests.v1: manifests/
|
||||
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
|
||||
operators.operatorframework.io.bundle.metadata.v1: metadata/
|
||||
operators.operatorframework.io.bundle.package.v1: klusterlet
|
||||
@@ -1,23 +1,23 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: nucleus-spoke
|
||||
name: klusterlet
|
||||
namespace: open-cluster-management
|
||||
labels:
|
||||
app: nucleus-spoke
|
||||
app: klusterlet
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleus-spoke
|
||||
app: klusterlet
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleus-spoke
|
||||
app: klusterlet
|
||||
spec:
|
||||
serviceAccountName: nucleus-spoke
|
||||
serviceAccountName: klusterlet
|
||||
containers:
|
||||
- name: nucleus-spoke
|
||||
- name: klusterlet
|
||||
image: quay.io/open-cluster-management/nucleus:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: nucleus-hub
|
||||
name: klusterlet
|
||||
namespace: open-cluster-management
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: nucleus.open-cluster-management.io/v1
|
||||
kind: HubCore
|
||||
metadata:
|
||||
name: hub
|
||||
spec:
|
||||
registrationImagePullSpec: quay.io/open-cluster-management/registration
|
||||
@@ -1,7 +0,0 @@
|
||||
annotations:
|
||||
operators.operatorframework.io.bundle.channel.default.v1: stable
|
||||
operators.operatorframework.io.bundle.channels.v1: stable
|
||||
operators.operatorframework.io.bundle.manifests.v1: manifests/
|
||||
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
|
||||
operators.operatorframework.io.bundle.metadata.v1: metadata/
|
||||
operators.operatorframework.io.bundle.package.v1: nucleus-hub
|
||||
@@ -1,7 +0,0 @@
|
||||
annotations:
|
||||
operators.operatorframework.io.bundle.channel.default.v1: stable
|
||||
operators.operatorframework.io.bundle.channels.v1: stable
|
||||
operators.operatorframework.io.bundle.manifests.v1: manifests/
|
||||
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
|
||||
operators.operatorframework.io.bundle.metadata.v1: metadata/
|
||||
operators.operatorframework.io.bundle.package.v1: nucleus-spoke
|
||||
12
go.mod
12
go.mod
@@ -4,19 +4,19 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/jteeuwen/go-bindata v3.0.8-0.20151023091102-a0ff2567cfb7+incompatible
|
||||
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-20200512175145-bed9ce79e17e
|
||||
github.com/open-cluster-management/api v0.0.0-20200601153054-56b58ce890e1
|
||||
github.com/openshift/api v0.0.0-20200326160804-ecb9283fe820
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc
|
||||
github.com/openshift/library-go v0.0.0-20200414135834-ccc4bb27d032
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
k8s.io/api v0.18.2
|
||||
k8s.io/api v0.18.3
|
||||
k8s.io/apiextensions-apiserver v0.18.2
|
||||
k8s.io/apimachinery v0.18.2
|
||||
k8s.io/client-go v0.18.2
|
||||
k8s.io/apimachinery v0.18.3
|
||||
k8s.io/client-go v0.18.3
|
||||
k8s.io/component-base v0.18.2
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/kube-aggregator v0.18.0
|
||||
|
||||
53
go.sum
53
go.sum
@@ -2,6 +2,7 @@ bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
@@ -12,6 +13,7 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
@@ -44,6 +46,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw=
|
||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
@@ -70,12 +73,17 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/distribution v0.0.0-20180920194744-16128bbac47f h1:hYf+mPizfvpH6VgIxdntnOmQHd1F1mQUc1oG+j3Ol2g=
|
||||
github.com/docker/distribution v0.0.0-20180920194744-16128bbac47f/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
|
||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libnetwork v0.0.0-20190731215715-7f13a5c99f4b h1:rACxqwRsHD075Vb7qTimAgMSKWoM5zER0Dhws/SgCVo=
|
||||
github.com/docker/libnetwork v0.0.0-20190731215715-7f13a5c99f4b/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
||||
@@ -96,6 +104,7 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsouza/go-dockerclient v0.0.0-20171004212419-da3951ba2e9e h1:B94x7idrPK5yFSMWliAvakUQlTDLgO7iJyHtpbYxGGM=
|
||||
github.com/fsouza/go-dockerclient v0.0.0-20171004212419-da3951ba2e9e/go.mod h1:KpcjM623fQYE9MZiTGzKhjfxXAV9wbyX2C1cyRHfhl0=
|
||||
github.com/getsentry/raven-go v0.0.0-20190513200303-c977f96e1095 h1:F2m41rgyxoveZKD+Z6xwyAbtdNeVvhpi9BpQLvt5oRU=
|
||||
github.com/getsentry/raven-go v0.0.0-20190513200303-c977f96e1095/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
@@ -104,6 +113,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE=
|
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
@@ -175,6 +186,13 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
|
||||
github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
|
||||
github.com/gonum/graph v0.0.0-20170401004347-50b27dea7ebb/go.mod h1:ye018NnX1zrbOLqwBvs2HqyyTouQgnL8C+qzYk1snPY=
|
||||
@@ -188,6 +206,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -234,6 +254,8 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jteeuwen/go-bindata v3.0.8-0.20151023091102-a0ff2567cfb7+incompatible h1:KTM14h3AKWWcPf5IWS/pcFTZosRmoqdIYzqi0mMG7es=
|
||||
github.com/jteeuwen/go-bindata v3.0.8-0.20151023091102-a0ff2567cfb7+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs=
|
||||
@@ -272,6 +294,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
@@ -289,16 +312,20 @@ 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-20200512175145-bed9ce79e17e h1:WIzt0Bs7g0PIrVAVSobXAbDqvC2P5VjEwFTpjB4777I=
|
||||
github.com/open-cluster-management/api v0.0.0-20200512175145-bed9ce79e17e/go.mod h1:RgKeB8PJ7upe2QXy/MpCejU/xm2G6/i0Y+/itWuPugs=
|
||||
github.com/open-cluster-management/api v0.0.0-20200601153054-56b58ce890e1 h1:MCq109q/vwW/5YdliL++J17d/6orA6MDmt2WQOaIpWw=
|
||||
github.com/open-cluster-management/api v0.0.0-20200601153054-56b58ce890e1/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=
|
||||
github.com/opencontainers/runc v0.0.0-20191031171055-b133feaeeb2e h1:NKMVwQeEqNOp8DVM4J1HjpZHRcQO7MAVfZwFxs+Bqec=
|
||||
github.com/opencontainers/runc v0.0.0-20191031171055-b133feaeeb2e/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/openshift/api v0.0.0-20200326152221-912866ddb162/go.mod h1:RKMJ5CBnljLfnej+BJ/xnOWc3kZDvJUaIAEq2oKSPtE=
|
||||
github.com/openshift/api v0.0.0-20200326160804-ecb9283fe820 h1:pEmlKM0gcAPwPEOUt0JOMBd+3bDEOaSZLdvPTm2eU6E=
|
||||
github.com/openshift/api v0.0.0-20200326160804-ecb9283fe820/go.mod h1:RKMJ5CBnljLfnej+BJ/xnOWc3kZDvJUaIAEq2oKSPtE=
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160 h1:V4E6yt4XWiBEPKnJbs/E8pgUq9AjZqzQfsL3eeT84Qs=
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc=
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc h1:Bu1p7+ItPqhJhmMve7sVluKCYV+o+x1Ede0WY2/BI8Q=
|
||||
github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc=
|
||||
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4LClRO+fg5MF/P6QxjMCb1C9f7Oh4RKepftDnEJE=
|
||||
github.com/openshift/library-go v0.0.0-20200414135834-ccc4bb27d032 h1:DFlzobaf+Sy22sUz5oCoFcpzv4pLcjUgUEPLDSitnX0=
|
||||
github.com/openshift/library-go v0.0.0-20200414135834-ccc4bb27d032/go.mod h1:CfydoH0B+RYs22uQZQ36A1mz5m5zhucpMGh8t5s71v4=
|
||||
@@ -435,6 +462,8 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd h1:QPwSajcTUrFriMF1nJ3XzgoqakqQEsnZf9LdXdi2nkI=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -464,6 +493,8 @@ golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -491,6 +522,8 @@ golang.org/x/tools v0.0.0-20200115044656-831fdb1e1868/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
@@ -509,6 +542,13 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -540,20 +580,27 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
|
||||
k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
|
||||
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
|
||||
k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0=
|
||||
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
|
||||
k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo=
|
||||
k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8=
|
||||
k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
|
||||
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
|
||||
k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA=
|
||||
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
|
||||
k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw=
|
||||
k8s.io/apiserver v0.18.2 h1:fwKxdTWwwYhxvtjo0UUfX+/fsitsNtfErPNegH2x9ic=
|
||||
k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
|
||||
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
|
||||
k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE=
|
||||
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
|
||||
k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k=
|
||||
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
|
||||
k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
|
||||
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
|
||||
k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
|
||||
k8s.io/component-base v0.18.2 h1:SJweNZAGcUvsypLGNPNGeJ9UgPZQ6+bW+gEHe8uyh/Y=
|
||||
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
|
||||
@@ -567,6 +614,8 @@ k8s.io/kube-aggregator v0.18.0 h1:J+wa9FDQ3SbgyA8wQBNg2m2FMSm+mMQfs2A58500hs0=
|
||||
k8s.io/kube-aggregator v0.18.0/go.mod h1:ateewQ5QbjMZF/dihEFXwaEwoA4v/mayRvzfmvb6eqI=
|
||||
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM=
|
||||
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200327001022-6496210b90e8 h1:6JFbaLjRyBz8K2Jvt+pcT+N3vvwMZfg8MfVENwe9aag=
|
||||
k8s.io/utils v0.0.0-20200327001022-6496210b90e8/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
|
||||
@@ -4,8 +4,8 @@ source "$(dirname "${BASH_SOURCE}")/init.sh"
|
||||
|
||||
for f in $CRD_FILES
|
||||
do
|
||||
cp $f ./manifests/hub/
|
||||
cp $f ./manifests/cluster-manager/
|
||||
done
|
||||
|
||||
cp $NUCLEUS_HUB_CRD_FILE ./deploy/nucleus-hub/crds/
|
||||
cp $NUCLEUS_SPOKE_CRD_FILE ./deploy/nucleus-spoke/crds/
|
||||
cp $CLUSTER_MANAGER_CRD_FILE ./deploy/cluster-manager/crds/
|
||||
cp $KLUSTERLET_CRD_FILE ./deploy/klusterlet/crds/
|
||||
|
||||
@@ -8,5 +8,5 @@ CRD_FILES="./vendor/github.com/open-cluster-management/api/cluster/v1/*.crd.yaml
|
||||
./vendor/github.com/open-cluster-management/api/work/v1/*.crd.yaml
|
||||
"
|
||||
|
||||
NUCLEUS_HUB_CRD_FILE="./vendor/github.com/open-cluster-management/api/nucleus/v1/0000_01_nucleus.open-cluster-management.io_hubcores.crd.yaml"
|
||||
NUCLEUS_SPOKE_CRD_FILE="./vendor/github.com/open-cluster-management/api/nucleus/v1/0000_00_nucleus.open-cluster-management.io_agentcores.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"
|
||||
|
||||
@@ -4,9 +4,9 @@ source "$(dirname "${BASH_SOURCE}")/init.sh"
|
||||
|
||||
for f in $CRD_FILES
|
||||
do
|
||||
diff -N $f ./manifests/hub/$(basename $f) || ( echo 'crd content is incorrect' && false )
|
||||
diff -N $f ./manifests/cluster-manager/$(basename $f) || ( echo 'crd content is incorrect' && false )
|
||||
done
|
||||
|
||||
diff -N $NUCLEUS_HUB_CRD_FILE ./deploy/nucleus-hub/crds/$(basename $NUCLEUS_HUB_CRD_FILES) || ( echo 'crd content is incorrect' && false )
|
||||
diff -N $NUCLEUS_SPOKE_CRD_FILE ./deploy/nucleus-spoke/crds/$(basename $NUCLEUS_SPOKE_CRD_FILES) || ( echo 'crd content is incorrect' && false )
|
||||
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 )
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ spec:
|
||||
to grant the permision of access from agent on spoke. When the value
|
||||
is set false, the namespace representing the spoke cluster is deleted.
|
||||
type: boolean
|
||||
leaseDurationSeconds:
|
||||
description: LeaseDurationSeconds is used to coordinate the lease update
|
||||
time of spoke agents. If its value is zero, the spoke agent will update
|
||||
its lease per 60s by default
|
||||
type: integer
|
||||
format: int32
|
||||
spokeClientConfigs:
|
||||
description: SpokeClientConfigs represents a list of the apiserver address
|
||||
of the spoke cluster. If it is empty, spoke cluster has no accessible
|
||||
@@ -59,6 +59,39 @@ 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 spoke 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
|
||||
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
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
name: {{ .ClusterManagerName }}-sa
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerNamespace }}
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
rules:
|
||||
# Allow hub to monitor and update status of csr
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
@@ -1,21 +1,21 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-controller
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-controller
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
labels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-controller
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-registration-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-registration-controller
|
||||
spec:
|
||||
serviceAccountName: {{ .HubCoreName }}-registration-controller-sa
|
||||
serviceAccountName: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
containers:
|
||||
- name: hub-registration-controller
|
||||
image: {{ .RegistrationImage }}
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
@@ -6,8 +6,8 @@ spec:
|
||||
group: admission.cluster.open-cluster-management.io
|
||||
version: v1
|
||||
service:
|
||||
name: {{ .HubCoreWebhookRegistrationService }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerWebhookRegistrationService }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
caBundle: {{ .RegistrationAPIServiceCABundle }}
|
||||
groupPriorityMinimum: 10000
|
||||
versionPriority: 20
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-webhook
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
rules:
|
||||
# Allow spokecluster admission to get/list/watch configmaps
|
||||
- apiGroups: [""]
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
@@ -1,23 +1,23 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-webhook
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-webhook
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
labels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
spec:
|
||||
serviceAccountName: {{ .HubCoreName }}-registration-webhook-sa
|
||||
serviceAccountName: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
containers:
|
||||
- name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
- name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
image: {{ .RegistrationImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
@@ -46,5 +46,5 @@ spec:
|
||||
volumes:
|
||||
- name: webhook-secret
|
||||
secret:
|
||||
secretName: {{ .HubCoreWebhookSecret }}
|
||||
secretName: {{ .ClusterManagerWebhookSecret }}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .HubCoreWebhookSecret }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerWebhookSecret }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
data:
|
||||
tls.crt: {{ .RegistrationServingCert }}
|
||||
tls.key: {{ .RegistrationServingKey }}
|
||||
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .ClusterManagerWebhookRegistrationService }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
spec:
|
||||
selector:
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 6443
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .HubCoreName }}-registration-controller-sa
|
||||
@@ -1,5 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-controller-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-webhook
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ .HubCoreName }}-registration-webhook
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
@@ -1,11 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .HubCoreWebhookRegistrationService }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
spec:
|
||||
selector:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 6443
|
||||
@@ -1,5 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
@@ -2,7 +2,7 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch nodes.
|
||||
- apiGroups: [""]
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -1,21 +1,21 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
name: {{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
labels:
|
||||
app: spoke-registration-agent
|
||||
app: klusterlet-registration-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: spoke-registration-agent
|
||||
app: klusterlet-registration-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: spoke-registration-agent
|
||||
app: klusterlet-registration-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .SpokeCoreName }}-registration-sa
|
||||
serviceAccountName: {{ .KlusterletName }}-registration-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .RegistrationImage }}
|
||||
@@ -2,8 +2,8 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "secrets"]
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -2,7 +2,7 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch/create/delete crds.
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent-addition
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -1,14 +1,14 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
# We deploy a controller that could work with permission lower than cluster-admin, the tradeoff is
|
||||
# We deploy a controller that could work with permission lower than cluster-admin, the tradeoff is
|
||||
# responsivity because list/watch cannot be maintained over too many namespaces.
|
||||
name: admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -1,21 +1,21 @@
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-work-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
name: {{ .KlusterletName }}-work-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
labels:
|
||||
app: spoke-work-agent
|
||||
app: klusterlet-manifestwork-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: spoke-work-agent
|
||||
app: klusterlet-manifestwork-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: spoke-work-agent
|
||||
app: klusterlet-manifestwork-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .SpokeCoreName }}-work-sa
|
||||
serviceAccountName: {{ .KlusterletName }}-work-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .WorkImage }}
|
||||
5
manifests/klusterlet/klusterlet-work-serviceaccount.yaml
Normal file
5
manifests/klusterlet/klusterlet-work-serviceaccount.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
@@ -1,13 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
@@ -1,5 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
@@ -1,12 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent-addition
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
@@ -1,5 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
// NewHubOperatorCmd generatee a command to start hub operator
|
||||
func NewHubOperatorCmd() *cobra.Command {
|
||||
cmd := controllercmd.
|
||||
NewControllerCommandConfig("nucleus-hub", version.Get(), operators.RunNucleusHubOperator).
|
||||
NewControllerCommandConfig("clustermanager", version.Get(), operators.RunClusterManagerOperator).
|
||||
NewCommand()
|
||||
cmd.Use = "hub"
|
||||
cmd.Short = "Start the nucleus hub operator"
|
||||
cmd.Short = "Start the cluster manager operator"
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
// NewSpokeOperatorCmd generatee a command to start spoke operator
|
||||
func NewSpokeOperatorCmd() *cobra.Command {
|
||||
cmd := controllercmd.
|
||||
NewControllerCommandConfig("nucleus-spoke", version.Get(), operators.RunNucleusSpokeOperator).
|
||||
NewControllerCommandConfig("klusterlet", version.Get(), operators.RunKlusterletOperator).
|
||||
NewCommand()
|
||||
cmd.Use = "spoke"
|
||||
cmd.Short = "Start the nucleus hub operator"
|
||||
cmd.Short = "Start the klusterlet operator"
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
package dependencymagnet
|
||||
|
||||
import (
|
||||
_ "github.com/jteeuwen/go-bindata/go-bindata"
|
||||
_ "github.com/go-bindata/go-bindata/go-bindata"
|
||||
_ "github.com/open-cluster-management/api/cluster/v1"
|
||||
_ "github.com/open-cluster-management/api/work/v1"
|
||||
_ "github.com/openshift/build-machinery-go"
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
nucleusv1client "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/typed/nucleus/v1"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
operatorv1client "github.com/open-cluster-management/api/client/operator/clientset/versioned/typed/operator/v1"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
admissionv1 "k8s.io/api/admissionregistration/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -45,14 +45,14 @@ func init() {
|
||||
utilruntime.Must(admissionv1.AddToScheme(genericScheme))
|
||||
}
|
||||
|
||||
func IsConditionTrue(condition *nucleusapiv1.StatusCondition) bool {
|
||||
func IsConditionTrue(condition *operatorapiv1.StatusCondition) bool {
|
||||
if condition == nil {
|
||||
return false
|
||||
}
|
||||
return condition.Status == metav1.ConditionTrue
|
||||
}
|
||||
|
||||
func FindNucleusCondition(conditions []nucleusapiv1.StatusCondition, conditionType string) *nucleusapiv1.StatusCondition {
|
||||
func FindOperatorCondition(conditions []operatorapiv1.StatusCondition, conditionType string) *operatorapiv1.StatusCondition {
|
||||
for i := range conditions {
|
||||
if conditions[i].Type == conditionType {
|
||||
return &conditions[i]
|
||||
@@ -61,11 +61,11 @@ func FindNucleusCondition(conditions []nucleusapiv1.StatusCondition, conditionTy
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetNucleusCondition(conditions *[]nucleusapiv1.StatusCondition, newCondition nucleusapiv1.StatusCondition) {
|
||||
func SetOperatorCondition(conditions *[]operatorapiv1.StatusCondition, newCondition operatorapiv1.StatusCondition) {
|
||||
if conditions == nil {
|
||||
conditions = &[]nucleusapiv1.StatusCondition{}
|
||||
conditions = &[]operatorapiv1.StatusCondition{}
|
||||
}
|
||||
existingCondition := FindNucleusCondition(*conditions, newCondition.Type)
|
||||
existingCondition := FindOperatorCondition(*conditions, newCondition.Type)
|
||||
if existingCondition == nil {
|
||||
newCondition.LastTransitionTime = metav1.NewTime(time.Now())
|
||||
*conditions = append(*conditions, newCondition)
|
||||
@@ -81,21 +81,21 @@ func SetNucleusCondition(conditions *[]nucleusapiv1.StatusCondition, newConditio
|
||||
existingCondition.Message = newCondition.Message
|
||||
}
|
||||
|
||||
type UpdateNucleusHubStatusFunc func(status *nucleusapiv1.HubCoreStatus) error
|
||||
type UpdateClusterManagerStatusFunc func(status *operatorapiv1.ClusterManagerStatus) error
|
||||
|
||||
func UpdateNucleusHubStatus(
|
||||
func UpdateClusterManagerStatus(
|
||||
ctx context.Context,
|
||||
client nucleusv1client.HubCoreInterface,
|
||||
nucleusHubCoreName string,
|
||||
updateFuncs ...UpdateNucleusHubStatusFunc) (*nucleusapiv1.HubCoreStatus, bool, error) {
|
||||
client operatorv1client.ClusterManagerInterface,
|
||||
clusterManagerName string,
|
||||
updateFuncs ...UpdateClusterManagerStatusFunc) (*operatorapiv1.ClusterManagerStatus, bool, error) {
|
||||
updated := false
|
||||
var updatedSpokeClusterStatus *nucleusapiv1.HubCoreStatus
|
||||
var updatedClusterManagerStatus *operatorapiv1.ClusterManagerStatus
|
||||
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
hubCore, err := client.Get(ctx, nucleusHubCoreName, metav1.GetOptions{})
|
||||
clusterManager, err := client.Get(ctx, clusterManagerName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldStatus := &hubCore.Status
|
||||
oldStatus := &clusterManager.Status
|
||||
|
||||
newStatus := oldStatus.DeepCopy()
|
||||
for _, update := range updateFuncs {
|
||||
@@ -105,47 +105,47 @@ func UpdateNucleusHubStatus(
|
||||
}
|
||||
if equality.Semantic.DeepEqual(oldStatus, newStatus) {
|
||||
// We return the newStatus which is a deep copy of oldStatus but with all update funcs applied.
|
||||
updatedSpokeClusterStatus = newStatus
|
||||
updatedClusterManagerStatus = newStatus
|
||||
return nil
|
||||
}
|
||||
|
||||
hubCore.Status = *newStatus
|
||||
updatedSpokeCluster, err := client.UpdateStatus(ctx, hubCore, metav1.UpdateOptions{})
|
||||
clusterManager.Status = *newStatus
|
||||
updatedClusterManager, err := client.UpdateStatus(ctx, clusterManager, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updatedSpokeClusterStatus = &updatedSpokeCluster.Status
|
||||
updatedClusterManagerStatus = &updatedClusterManager.Status
|
||||
updated = err == nil
|
||||
return err
|
||||
})
|
||||
|
||||
return updatedSpokeClusterStatus, updated, err
|
||||
return updatedClusterManagerStatus, updated, err
|
||||
}
|
||||
|
||||
func UpdateNucleusHubConditionFn(conds ...nucleusapiv1.StatusCondition) UpdateNucleusHubStatusFunc {
|
||||
return func(oldStatus *nucleusapiv1.HubCoreStatus) error {
|
||||
func UpdateClusterManagerConditionFn(conds ...operatorapiv1.StatusCondition) UpdateClusterManagerStatusFunc {
|
||||
return func(oldStatus *operatorapiv1.ClusterManagerStatus) error {
|
||||
for _, cond := range conds {
|
||||
SetNucleusCondition(&oldStatus.Conditions, cond)
|
||||
SetOperatorCondition(&oldStatus.Conditions, cond)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type UpdateNucleusSpokeStatusFunc func(status *nucleusapiv1.SpokeCoreStatus) error
|
||||
type UpdateKlusterletStatusFunc func(status *operatorapiv1.KlusterletStatus) error
|
||||
|
||||
func UpdateNucleusSpokeStatus(
|
||||
func UpdateKlusterletStatus(
|
||||
ctx context.Context,
|
||||
client nucleusv1client.SpokeCoreInterface,
|
||||
nucleusSpokeCoreName string,
|
||||
updateFuncs ...UpdateNucleusSpokeStatusFunc) (*nucleusapiv1.SpokeCoreStatus, bool, error) {
|
||||
client operatorv1client.KlusterletInterface,
|
||||
klusterletName string,
|
||||
updateFuncs ...UpdateKlusterletStatusFunc) (*operatorapiv1.KlusterletStatus, bool, error) {
|
||||
updated := false
|
||||
var updatedSpokeClusterStatus *nucleusapiv1.SpokeCoreStatus
|
||||
var updatedKlusterletStatus *operatorapiv1.KlusterletStatus
|
||||
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
spokeCore, err := client.Get(ctx, nucleusSpokeCoreName, metav1.GetOptions{})
|
||||
klusterlet, err := client.Get(ctx, klusterletName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldStatus := &spokeCore.Status
|
||||
oldStatus := &klusterlet.Status
|
||||
|
||||
newStatus := oldStatus.DeepCopy()
|
||||
for _, update := range updateFuncs {
|
||||
@@ -155,27 +155,27 @@ func UpdateNucleusSpokeStatus(
|
||||
}
|
||||
if equality.Semantic.DeepEqual(oldStatus, newStatus) {
|
||||
// We return the newStatus which is a deep copy of oldStatus but with all update funcs applied.
|
||||
updatedSpokeClusterStatus = newStatus
|
||||
updatedKlusterletStatus = newStatus
|
||||
return nil
|
||||
}
|
||||
|
||||
spokeCore.Status = *newStatus
|
||||
updatedSpokeCluster, err := client.UpdateStatus(ctx, spokeCore, metav1.UpdateOptions{})
|
||||
klusterlet.Status = *newStatus
|
||||
updatedKlusterlet, err := client.UpdateStatus(ctx, klusterlet, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updatedSpokeClusterStatus = &updatedSpokeCluster.Status
|
||||
updatedKlusterletStatus = &updatedKlusterlet.Status
|
||||
updated = err == nil
|
||||
return err
|
||||
})
|
||||
|
||||
return updatedSpokeClusterStatus, updated, err
|
||||
return updatedKlusterletStatus, updated, err
|
||||
}
|
||||
|
||||
func UpdateNucleusSpokeConditionFn(conds ...nucleusapiv1.StatusCondition) UpdateNucleusSpokeStatusFunc {
|
||||
return func(oldStatus *nucleusapiv1.SpokeCoreStatus) error {
|
||||
func UpdateKlusterletConditionFn(conds ...operatorapiv1.StatusCondition) UpdateKlusterletStatusFunc {
|
||||
return func(oldStatus *operatorapiv1.KlusterletStatus) error {
|
||||
for _, cond := range conds {
|
||||
SetNucleusCondition(&oldStatus.Conditions, cond)
|
||||
SetOperatorCondition(&oldStatus.Conditions, cond)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
nucleusfake "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/fake"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
opereatorfake "github.com/open-cluster-management/api/client/operator/clientset/versioned/fake"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
"github.com/openshift/library-go/pkg/operator/events/eventstesting"
|
||||
operatorhelpers "github.com/openshift/library-go/pkg/operator/v1helpers"
|
||||
admissionv1 "k8s.io/api/admissionregistration/v1"
|
||||
fakeapiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -29,52 +30,52 @@ func TestUpdateStatusCondition(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
startingConditions []nucleusapiv1.StatusCondition
|
||||
newCondition nucleusapiv1.StatusCondition
|
||||
startingConditions []operatorapiv1.StatusCondition
|
||||
newCondition operatorapiv1.StatusCondition
|
||||
expectedUpdated bool
|
||||
expectedConditions []nucleusapiv1.StatusCondition
|
||||
expectedConditions []operatorapiv1.StatusCondition
|
||||
}{
|
||||
{
|
||||
name: "add to empty",
|
||||
startingConditions: []nucleusapiv1.StatusCondition{},
|
||||
startingConditions: []operatorapiv1.StatusCondition{},
|
||||
newCondition: newCondition("test", "True", "my-reason", "my-message", nil),
|
||||
expectedUpdated: true,
|
||||
expectedConditions: []nucleusapiv1.StatusCondition{newCondition("test", "True", "my-reason", "my-message", nil)},
|
||||
expectedConditions: []operatorapiv1.StatusCondition{newCondition("test", "True", "my-reason", "my-message", nil)},
|
||||
},
|
||||
{
|
||||
name: "add to non-conflicting",
|
||||
startingConditions: []nucleusapiv1.StatusCondition{
|
||||
startingConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
},
|
||||
newCondition: newCondition("one", "True", "my-reason", "my-message", nil),
|
||||
expectedUpdated: true,
|
||||
expectedConditions: []nucleusapiv1.StatusCondition{
|
||||
expectedConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
newCondition("one", "True", "my-reason", "my-message", nil),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change existing status",
|
||||
startingConditions: []nucleusapiv1.StatusCondition{
|
||||
startingConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
newCondition("one", "True", "my-reason", "my-message", nil),
|
||||
},
|
||||
newCondition: newCondition("one", "False", "my-different-reason", "my-othermessage", nil),
|
||||
expectedUpdated: true,
|
||||
expectedConditions: []nucleusapiv1.StatusCondition{
|
||||
expectedConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
newCondition("one", "False", "my-different-reason", "my-othermessage", nil),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "leave existing transition time",
|
||||
startingConditions: []nucleusapiv1.StatusCondition{
|
||||
startingConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
newCondition("one", "True", "my-reason", "my-message", &beforeish),
|
||||
},
|
||||
newCondition: newCondition("one", "True", "my-reason", "my-message", &afterish),
|
||||
expectedUpdated: false,
|
||||
expectedConditions: []nucleusapiv1.StatusCondition{
|
||||
expectedConditions: []operatorapiv1.StatusCondition{
|
||||
newCondition("two", "True", "my-reason", "my-message", nil),
|
||||
newCondition("one", "True", "my-reason", "my-message", &beforeish),
|
||||
},
|
||||
@@ -83,26 +84,26 @@ func TestUpdateStatusCondition(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
fakeClusterClient := nucleusfake.NewSimpleClientset(
|
||||
&nucleusapiv1.HubCore{
|
||||
fakeOperatorClient := opereatorfake.NewSimpleClientset(
|
||||
&operatorapiv1.ClusterManager{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "testspokecluster"},
|
||||
Status: nucleusapiv1.HubCoreStatus{
|
||||
Status: operatorapiv1.ClusterManagerStatus{
|
||||
Conditions: c.startingConditions,
|
||||
},
|
||||
},
|
||||
&nucleusapiv1.SpokeCore{
|
||||
&operatorapiv1.Klusterlet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "testspokecluster"},
|
||||
Status: nucleusapiv1.SpokeCoreStatus{
|
||||
Status: operatorapiv1.KlusterletStatus{
|
||||
Conditions: c.startingConditions,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
hubstatus, updated, err := UpdateNucleusHubStatus(
|
||||
hubstatus, updated, err := UpdateClusterManagerStatus(
|
||||
context.TODO(),
|
||||
fakeClusterClient.NucleusV1().HubCores(),
|
||||
fakeOperatorClient.OperatorV1().ClusterManagers(),
|
||||
"testspokecluster",
|
||||
UpdateNucleusHubConditionFn(c.newCondition),
|
||||
UpdateClusterManagerConditionFn(c.newCondition),
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected err: %v", err)
|
||||
@@ -111,11 +112,11 @@ func TestUpdateStatusCondition(t *testing.T) {
|
||||
t.Errorf("expected %t, but %t", c.expectedUpdated, updated)
|
||||
}
|
||||
|
||||
spokestatus, updated, err := UpdateNucleusSpokeStatus(
|
||||
spokestatus, updated, err := UpdateKlusterletStatus(
|
||||
context.TODO(),
|
||||
fakeClusterClient.NucleusV1().SpokeCores(),
|
||||
fakeOperatorClient.OperatorV1().Klusterlets(),
|
||||
"testspokecluster",
|
||||
UpdateNucleusSpokeConditionFn(c.newCondition),
|
||||
UpdateKlusterletConditionFn(c.newCondition),
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected err: %v", err)
|
||||
@@ -146,8 +147,8 @@ func TestUpdateStatusCondition(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func newCondition(name, status, reason, message string, lastTransition *metav1.Time) nucleusapiv1.StatusCondition {
|
||||
ret := nucleusapiv1.StatusCondition{
|
||||
func newCondition(name, status, reason, message string, lastTransition *metav1.Time) operatorapiv1.StatusCondition {
|
||||
ret := operatorapiv1.StatusCondition{
|
||||
Type: name,
|
||||
Status: metav1.ConditionStatus(status),
|
||||
Reason: reason,
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
// Code generated by go-bindata.
|
||||
// Code generated for package bindata by go-bindata DO NOT EDIT. (@generated)
|
||||
// sources:
|
||||
// manifests/hub/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml
|
||||
// manifests/hub/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml
|
||||
// manifests/hub/hub-namespace.yaml
|
||||
// manifests/hub/hub-registration-clusterrole.yaml
|
||||
// manifests/hub/hub-registration-clusterrolebinding.yaml
|
||||
// manifests/hub/hub-registration-deployment.yaml
|
||||
// manifests/hub/hub-registration-serviceaccount.yaml
|
||||
// manifests/hub/hub-registration-webhook-apiservice.yaml
|
||||
// manifests/hub/hub-registration-webhook-clusterrole.yaml
|
||||
// manifests/hub/hub-registration-webhook-clusterrolebinding.yaml
|
||||
// manifests/hub/hub-registration-webhook-deployment.yaml
|
||||
// manifests/hub/hub-registration-webhook-secret.yaml
|
||||
// manifests/hub/hub-registration-webhook-service.yaml
|
||||
// manifests/hub/hub-registration-webhook-serviceaccount.yaml
|
||||
// manifests/hub/hub-registration-webhook-validatingconfiguration.yaml
|
||||
// DO NOT EDIT!
|
||||
|
||||
// manifests/cluster-manager/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml
|
||||
// manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml
|
||||
// manifests/cluster-manager/cluster-manager-clusterrolebinding.yaml
|
||||
// manifests/cluster-manager/cluster-manager-namespace.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-clusterrole.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-clusterrolebinding.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-deployment.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-serviceaccount.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-apiservice.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-clusterrole.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-clusterrolebinding.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-deployment.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-secret.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-service.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-serviceaccount.yaml
|
||||
// manifests/cluster-manager/cluster-manager-registration-webhook-validatingconfiguration.yaml
|
||||
package bindata
|
||||
|
||||
import (
|
||||
@@ -40,26 +39,37 @@ type bindataFileInfo struct {
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
// Name return file name
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
|
||||
// Size return file size
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
|
||||
// Mode return file mode
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
|
||||
// Mode return file modify time
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
|
||||
// IsDir return file whether a directory
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
return fi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
// Sys return file is sys mode
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1
|
||||
var _manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: spokeclusters.cluster.open-cluster-management.io
|
||||
@@ -115,6 +125,12 @@ spec:
|
||||
to grant the permision of access from agent on spoke. When the value
|
||||
is set false, the namespace representing the spoke cluster is deleted.
|
||||
type: boolean
|
||||
leaseDurationSeconds:
|
||||
description: LeaseDurationSeconds is used to coordinate the lease update
|
||||
time of spoke agents. If its value is zero, the spoke agent will update
|
||||
its lease per 60s by default
|
||||
type: integer
|
||||
format: int32
|
||||
spokeClientConfigs:
|
||||
description: SpokeClientConfigs represents a list of the apiserver address
|
||||
of the spoke cluster. If it is empty, spoke cluster has no accessible
|
||||
@@ -201,22 +217,22 @@ status:
|
||||
storedVersions: []
|
||||
`)
|
||||
|
||||
func manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYamlBytes() ([]byte, error) {
|
||||
return _manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml, nil
|
||||
func manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml() (*asset, error) {
|
||||
bytes, err := manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYamlBytes()
|
||||
func manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1
|
||||
var _manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
@@ -277,6 +293,39 @@ 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 spoke 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
|
||||
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
|
||||
@@ -404,46 +453,75 @@ status:
|
||||
storedVersions: []
|
||||
`)
|
||||
|
||||
func manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYamlBytes() ([]byte, error) {
|
||||
return _manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYaml, nil
|
||||
func manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYaml() (*asset, error) {
|
||||
bytes, err := manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYamlBytes()
|
||||
func manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubNamespaceYaml = []byte(`apiVersion: v1
|
||||
kind: Namespace
|
||||
var _manifestsClusterManagerClusterManagerClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ .HubCoreNamespace }}
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
name: {{ .ClusterManagerName }}-sa
|
||||
`)
|
||||
|
||||
func manifestsHubHubNamespaceYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubNamespaceYaml, nil
|
||||
func manifestsClusterManagerClusterManagerClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubNamespaceYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubNamespaceYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-namespace.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerNamespaceYaml = []byte(`apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .ClusterManagerNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsClusterManagerClusterManagerNamespaceYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerNamespaceYaml, nil
|
||||
}
|
||||
|
||||
func manifestsClusterManagerClusterManagerNamespaceYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerNamespaceYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-namespace.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsClusterManagerClusterManagerRegistrationClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
rules:
|
||||
# Allow hub to monitor and update status of csr
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
@@ -478,68 +556,68 @@ rules:
|
||||
verbs: ["update", "patch"]
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationClusterroleYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationClusterroleYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-controller
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .HubCoreName }}-registration-controller-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationClusterrolebindingYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationClusterrolebindingYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationDeploymentYaml = []byte(`kind: Deployment
|
||||
var _manifestsClusterManagerClusterManagerRegistrationDeploymentYaml = []byte(`kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-controller
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-controller
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
labels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-controller
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-registration-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nucleushub-registration-controller
|
||||
app: clustermanager-registration-controller
|
||||
spec:
|
||||
serviceAccountName: {{ .HubCoreName }}-registration-controller-sa
|
||||
serviceAccountName: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
containers:
|
||||
- name: hub-registration-controller
|
||||
image: {{ .RegistrationImage }}
|
||||
@@ -562,44 +640,44 @@ spec:
|
||||
initialDelaySeconds: 2
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationDeploymentYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationDeploymentYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationServiceaccountYaml = []byte(`apiVersion: v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-controller-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-controller-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationServiceaccountYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationServiceaccountYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookApiserviceYaml = []byte(`apiVersion: apiregistration.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYaml = []byte(`apiVersion: apiregistration.k8s.io/v1
|
||||
kind: APIService
|
||||
metadata:
|
||||
name: v1.admission.cluster.open-cluster-management.io
|
||||
@@ -607,32 +685,32 @@ spec:
|
||||
group: admission.cluster.open-cluster-management.io
|
||||
version: v1
|
||||
service:
|
||||
name: {{ .HubCoreWebhookRegistrationService }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerWebhookRegistrationService }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
caBundle: {{ .RegistrationAPIServiceCABundle }}
|
||||
groupPriorityMinimum: 10000
|
||||
versionPriority: 20
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookApiserviceYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookApiserviceYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookApiserviceYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookApiserviceYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-apiservice.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-apiservice.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-webhook
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
rules:
|
||||
# Allow spokecluster admission to get/list/watch configmaps
|
||||
- apiGroups: [""]
|
||||
@@ -644,70 +722,70 @@ rules:
|
||||
verbs: ["create"]
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookClusterroleYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookClusterroleYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .HubCoreName }}-registration-webhook
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ .HubCoreName }}-registration-webhook
|
||||
name: system:open-cluster-management:{{ .ClusterManagerName }}-registration-webhook
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookClusterrolebindingYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookClusterrolebindingYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookDeploymentYaml = []byte(`apiVersion: apps/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYaml = []byte(`apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-webhook
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-webhook
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
labels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
spec:
|
||||
serviceAccountName: {{ .HubCoreName }}-registration-webhook-sa
|
||||
serviceAccountName: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
containers:
|
||||
- name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
- name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
image: {{ .RegistrationImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
@@ -736,30 +814,30 @@ spec:
|
||||
volumes:
|
||||
- name: webhook-secret
|
||||
secret:
|
||||
secretName: {{ .HubCoreWebhookSecret }}
|
||||
secretName: {{ .ClusterManagerWebhookSecret }}
|
||||
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookDeploymentYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookDeploymentYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookSecretYaml = []byte(`apiVersion: v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookSecretYaml = []byte(`apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .HubCoreWebhookSecret }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerWebhookSecret }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
data:
|
||||
tls.crt: {{ .RegistrationServingCert }}
|
||||
tls.key: {{ .RegistrationServingKey }}
|
||||
@@ -767,72 +845,72 @@ data:
|
||||
type: Opaque
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookSecretYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookSecretYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookSecretYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookSecretYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookSecretYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookSecretYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookSecretYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookSecretYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-secret.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-secret.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookServiceYaml = []byte(`apiVersion: v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookServiceYaml = []byte(`apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .HubCoreWebhookRegistrationService }}
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerWebhookRegistrationService }}
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
spec:
|
||||
selector:
|
||||
app: {{ .HubCoreName }}-registration-webhook
|
||||
app: {{ .ClusterManagerName }}-registration-webhook
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 6443
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookServiceYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookServiceYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookServiceYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookServiceYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookServiceYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookServiceYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookServiceYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookServiceYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-service.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-service.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookServiceaccountYaml = []byte(`apiVersion: v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .HubCoreName }}-registration-webhook-sa
|
||||
namespace: {{ .HubCoreNamespace }}
|
||||
name: {{ .ClusterManagerName }}-registration-webhook-sa
|
||||
namespace: {{ .ClusterManagerNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookServiceaccountYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookServiceaccountYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsHubHubRegistrationWebhookValidatingconfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1
|
||||
var _manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: spokeclustervalidators.admission.cluster.open-cluster-management.io
|
||||
@@ -860,17 +938,17 @@ webhooks:
|
||||
timeoutSeconds: 3
|
||||
`)
|
||||
|
||||
func manifestsHubHubRegistrationWebhookValidatingconfigurationYamlBytes() ([]byte, error) {
|
||||
return _manifestsHubHubRegistrationWebhookValidatingconfigurationYaml, nil
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYamlBytes() ([]byte, error) {
|
||||
return _manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYaml, nil
|
||||
}
|
||||
|
||||
func manifestsHubHubRegistrationWebhookValidatingconfigurationYaml() (*asset, error) {
|
||||
bytes, err := manifestsHubHubRegistrationWebhookValidatingconfigurationYamlBytes()
|
||||
func manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYaml() (*asset, error) {
|
||||
bytes, err := manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/hub/hub-registration-webhook-validatingconfiguration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
info := bindataFileInfo{name: "manifests/cluster-manager/cluster-manager-registration-webhook-validatingconfiguration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -927,21 +1005,22 @@ func AssetNames() []string {
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"manifests/hub/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml": manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml,
|
||||
"manifests/hub/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml": manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYaml,
|
||||
"manifests/hub/hub-namespace.yaml": manifestsHubHubNamespaceYaml,
|
||||
"manifests/hub/hub-registration-clusterrole.yaml": manifestsHubHubRegistrationClusterroleYaml,
|
||||
"manifests/hub/hub-registration-clusterrolebinding.yaml": manifestsHubHubRegistrationClusterrolebindingYaml,
|
||||
"manifests/hub/hub-registration-deployment.yaml": manifestsHubHubRegistrationDeploymentYaml,
|
||||
"manifests/hub/hub-registration-serviceaccount.yaml": manifestsHubHubRegistrationServiceaccountYaml,
|
||||
"manifests/hub/hub-registration-webhook-apiservice.yaml": manifestsHubHubRegistrationWebhookApiserviceYaml,
|
||||
"manifests/hub/hub-registration-webhook-clusterrole.yaml": manifestsHubHubRegistrationWebhookClusterroleYaml,
|
||||
"manifests/hub/hub-registration-webhook-clusterrolebinding.yaml": manifestsHubHubRegistrationWebhookClusterrolebindingYaml,
|
||||
"manifests/hub/hub-registration-webhook-deployment.yaml": manifestsHubHubRegistrationWebhookDeploymentYaml,
|
||||
"manifests/hub/hub-registration-webhook-secret.yaml": manifestsHubHubRegistrationWebhookSecretYaml,
|
||||
"manifests/hub/hub-registration-webhook-service.yaml": manifestsHubHubRegistrationWebhookServiceYaml,
|
||||
"manifests/hub/hub-registration-webhook-serviceaccount.yaml": manifestsHubHubRegistrationWebhookServiceaccountYaml,
|
||||
"manifests/hub/hub-registration-webhook-validatingconfiguration.yaml": manifestsHubHubRegistrationWebhookValidatingconfigurationYaml,
|
||||
"manifests/cluster-manager/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml": manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml,
|
||||
"manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml": manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYaml,
|
||||
"manifests/cluster-manager/cluster-manager-clusterrolebinding.yaml": manifestsClusterManagerClusterManagerClusterrolebindingYaml,
|
||||
"manifests/cluster-manager/cluster-manager-namespace.yaml": manifestsClusterManagerClusterManagerNamespaceYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-clusterrole.yaml": manifestsClusterManagerClusterManagerRegistrationClusterroleYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-clusterrolebinding.yaml": manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-deployment.yaml": manifestsClusterManagerClusterManagerRegistrationDeploymentYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-serviceaccount.yaml": manifestsClusterManagerClusterManagerRegistrationServiceaccountYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-apiservice.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-clusterrole.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-clusterrolebinding.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-deployment.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-secret.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookSecretYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-service.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookServiceYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-serviceaccount.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYaml,
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-validatingconfiguration.yaml": manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYaml,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
@@ -986,22 +1065,23 @@ type bintree struct {
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"manifests": {nil, map[string]*bintree{
|
||||
"hub": {nil, map[string]*bintree{
|
||||
"0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml": {manifestsHub0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml, map[string]*bintree{}},
|
||||
"0000_00_work.open-cluster-management.io_manifestworks.crd.yaml": {manifestsHub0000_00_workOpenClusterManagementIo_manifestworksCrdYaml, map[string]*bintree{}},
|
||||
"hub-namespace.yaml": {manifestsHubHubNamespaceYaml, map[string]*bintree{}},
|
||||
"hub-registration-clusterrole.yaml": {manifestsHubHubRegistrationClusterroleYaml, map[string]*bintree{}},
|
||||
"hub-registration-clusterrolebinding.yaml": {manifestsHubHubRegistrationClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"hub-registration-deployment.yaml": {manifestsHubHubRegistrationDeploymentYaml, map[string]*bintree{}},
|
||||
"hub-registration-serviceaccount.yaml": {manifestsHubHubRegistrationServiceaccountYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-apiservice.yaml": {manifestsHubHubRegistrationWebhookApiserviceYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-clusterrole.yaml": {manifestsHubHubRegistrationWebhookClusterroleYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-clusterrolebinding.yaml": {manifestsHubHubRegistrationWebhookClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-deployment.yaml": {manifestsHubHubRegistrationWebhookDeploymentYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-secret.yaml": {manifestsHubHubRegistrationWebhookSecretYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-service.yaml": {manifestsHubHubRegistrationWebhookServiceYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-serviceaccount.yaml": {manifestsHubHubRegistrationWebhookServiceaccountYaml, map[string]*bintree{}},
|
||||
"hub-registration-webhook-validatingconfiguration.yaml": {manifestsHubHubRegistrationWebhookValidatingconfigurationYaml, map[string]*bintree{}},
|
||||
"cluster-manager": {nil, map[string]*bintree{
|
||||
"0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml": {manifestsClusterManager0000_00_clustersOpenClusterManagementIo_spokeclustersCrdYaml, map[string]*bintree{}},
|
||||
"0000_00_work.open-cluster-management.io_manifestworks.crd.yaml": {manifestsClusterManager0000_00_workOpenClusterManagementIo_manifestworksCrdYaml, map[string]*bintree{}},
|
||||
"cluster-manager-clusterrolebinding.yaml": {manifestsClusterManagerClusterManagerClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"cluster-manager-namespace.yaml": {manifestsClusterManagerClusterManagerNamespaceYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-clusterrole.yaml": {manifestsClusterManagerClusterManagerRegistrationClusterroleYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-clusterrolebinding.yaml": {manifestsClusterManagerClusterManagerRegistrationClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-deployment.yaml": {manifestsClusterManagerClusterManagerRegistrationDeploymentYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-serviceaccount.yaml": {manifestsClusterManagerClusterManagerRegistrationServiceaccountYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-apiservice.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookApiserviceYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-clusterrole.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookClusterroleYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-clusterrolebinding.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-deployment.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookDeploymentYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-secret.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookSecretYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-service.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookServiceYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-serviceaccount.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookServiceaccountYaml, map[string]*bintree{}},
|
||||
"cluster-manager-registration-webhook-validatingconfiguration.yaml": {manifestsClusterManagerClusterManagerRegistrationWebhookValidatingconfigurationYaml, map[string]*bintree{}},
|
||||
}},
|
||||
}},
|
||||
}}
|
||||
@@ -1,4 +1,4 @@
|
||||
package hub
|
||||
package clustermanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -23,12 +23,12 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
nucleusv1client "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/typed/nucleus/v1"
|
||||
nucleusinformer "github.com/open-cluster-management/api/client/nucleus/informers/externalversions/nucleus/v1"
|
||||
nucleuslister "github.com/open-cluster-management/api/client/nucleus/listers/nucleus/v1"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
operatorv1client "github.com/open-cluster-management/api/client/operator/clientset/versioned/typed/operator/v1"
|
||||
operatorinformer "github.com/open-cluster-management/api/client/operator/informers/externalversions/operator/v1"
|
||||
operatorlister "github.com/open-cluster-management/api/client/operator/listers/operator/v1"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
"github.com/open-cluster-management/nucleus/pkg/helpers"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/hub/bindata"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/clustermanager/bindata"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -37,58 +37,58 @@ var (
|
||||
"spokeclusters.cluster.open-cluster-management.io",
|
||||
}
|
||||
staticResourceFiles = []string{
|
||||
"manifests/hub/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml",
|
||||
"manifests/hub/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml",
|
||||
"manifests/hub/hub-registration-clusterrole.yaml",
|
||||
"manifests/hub/hub-registration-clusterrolebinding.yaml",
|
||||
"manifests/hub/hub-namespace.yaml",
|
||||
"manifests/hub/hub-registration-serviceaccount.yaml",
|
||||
"manifests/hub/hub-registration-webhook-clusterrole.yaml",
|
||||
"manifests/hub/hub-registration-webhook-clusterrolebinding.yaml",
|
||||
"manifests/hub/hub-registration-webhook-service.yaml",
|
||||
"manifests/hub/hub-registration-webhook-serviceaccount.yaml",
|
||||
"manifests/hub/hub-registration-webhook-apiservice.yaml",
|
||||
"manifests/hub/hub-registration-webhook-secret.yaml",
|
||||
"manifests/hub/hub-registration-webhook-validatingconfiguration.yaml",
|
||||
"manifests/cluster-manager/0000_00_clusters.open-cluster-management.io_spokeclusters.crd.yaml",
|
||||
"manifests/cluster-manager/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-clusterrole.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-clusterrolebinding.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-namespace.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-serviceaccount.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-clusterrole.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-clusterrolebinding.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-service.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-serviceaccount.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-apiservice.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-secret.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-validatingconfiguration.yaml",
|
||||
}
|
||||
|
||||
deploymentFiles = []string{
|
||||
"manifests/hub/hub-registration-deployment.yaml",
|
||||
"manifests/hub/hub-registration-webhook-deployment.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-deployment.yaml",
|
||||
"manifests/cluster-manager/cluster-manager-registration-webhook-deployment.yaml",
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
nucleusHubFinalizer = "nucleus.open-cluster-management.io/hub-core-cleanup"
|
||||
nucleusHubCoreNamespace = "open-cluster-management-hub"
|
||||
nucleusHubCoreWebhookSecret = "webhook-serving-cert"
|
||||
hubCoreApplied = "Applied"
|
||||
hubCoreAvailable = "Available"
|
||||
clusterManagerFinalizer = "operator.open-cluster-management.io/cluster-manager-cleanup"
|
||||
clusterManagerNamespace = "open-cluster-management-hub"
|
||||
clusterManagerWebhookSecret = "webhook-serving-cert"
|
||||
clusterManagerApplied = "Applied"
|
||||
clusterManagerAvailable = "Available"
|
||||
)
|
||||
|
||||
type nucleusHubController struct {
|
||||
nucleusClient nucleusv1client.HubCoreInterface
|
||||
nucleusLister nucleuslister.HubCoreLister
|
||||
type clusterManagerController struct {
|
||||
clusterManagerClient operatorv1client.ClusterManagerInterface
|
||||
clusterManagerLister operatorlister.ClusterManagerLister
|
||||
kubeClient kubernetes.Interface
|
||||
apiExtensionClient apiextensionsclient.Interface
|
||||
apiRegistrationClient apiregistrationclient.APIServicesGetter
|
||||
currentGeneration []int64
|
||||
}
|
||||
|
||||
// NewNucleusHubController construct nucleus hub controller
|
||||
func NewNucleusHubController(
|
||||
// NewClusterManagerController construct cluster manager hub controller
|
||||
func NewClusterManagerController(
|
||||
kubeClient kubernetes.Interface,
|
||||
apiExtensionClient apiextensionsclient.Interface,
|
||||
apiRegistrationClient apiregistrationclient.APIServicesGetter,
|
||||
nucleusClient nucleusv1client.HubCoreInterface,
|
||||
nucleusInformer nucleusinformer.HubCoreInformer,
|
||||
clusterManagerClient operatorv1client.ClusterManagerInterface,
|
||||
clusterManagerInformer operatorinformer.ClusterManagerInformer,
|
||||
recorder events.Recorder) factory.Controller {
|
||||
controller := &nucleusHubController{
|
||||
controller := &clusterManagerController{
|
||||
kubeClient: kubeClient,
|
||||
apiExtensionClient: apiExtensionClient,
|
||||
apiRegistrationClient: apiRegistrationClient,
|
||||
nucleusClient: nucleusClient,
|
||||
nucleusLister: nucleusInformer.Lister(),
|
||||
clusterManagerClient: clusterManagerClient,
|
||||
clusterManagerLister: clusterManagerInformer.Lister(),
|
||||
currentGeneration: make([]int64, len(deploymentFiles)),
|
||||
}
|
||||
|
||||
@@ -97,70 +97,70 @@ func NewNucleusHubController(
|
||||
WithInformersQueueKeyFunc(func(obj runtime.Object) string {
|
||||
accessor, _ := meta.Accessor(obj)
|
||||
return accessor.GetName()
|
||||
}, nucleusInformer.Informer()).
|
||||
ToController("NucleusHubController", recorder)
|
||||
}, clusterManagerInformer.Informer()).
|
||||
ToController("ClusterManagerController", recorder)
|
||||
}
|
||||
|
||||
// hubConfig is used to render the template of hub manifests
|
||||
type hubConfig struct {
|
||||
HubCoreName string
|
||||
HubCoreNamespace string
|
||||
RegistrationImage string
|
||||
HubCoreWebhookSecret string
|
||||
HubCoreWebhookRegistrationService string
|
||||
RegistrationAPIServiceCABundle string
|
||||
RegistrationServingCert string
|
||||
RegistrationServingKey string
|
||||
ClusterManagerName string
|
||||
ClusterManagerNamespace string
|
||||
RegistrationImage string
|
||||
ClusterManagerWebhookSecret string
|
||||
ClusterManagerWebhookRegistrationService string
|
||||
RegistrationAPIServiceCABundle string
|
||||
RegistrationServingCert string
|
||||
RegistrationServingKey string
|
||||
}
|
||||
|
||||
func (n *nucleusHubController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
|
||||
hubCoreName := controllerContext.QueueKey()
|
||||
klog.V(4).Infof("Reconciling HubCore %q", hubCoreName)
|
||||
func (n *clusterManagerController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
|
||||
clusterManagerName := controllerContext.QueueKey()
|
||||
klog.V(4).Infof("Reconciling ClusterManager %q", clusterManagerName)
|
||||
|
||||
hubCore, err := n.nucleusLister.Get(hubCoreName)
|
||||
clusterManager, err := n.clusterManagerLister.Get(clusterManagerName)
|
||||
if errors.IsNotFound(err) {
|
||||
// HubCore not found, could have been deleted, do nothing.
|
||||
// ClusterManager not found, could have been deleted, do nothing.
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hubCore = hubCore.DeepCopy()
|
||||
clusterManager = clusterManager.DeepCopy()
|
||||
|
||||
config := hubConfig{
|
||||
HubCoreName: hubCore.Name,
|
||||
HubCoreNamespace: nucleusHubCoreNamespace,
|
||||
RegistrationImage: hubCore.Spec.RegistrationImagePullSpec,
|
||||
HubCoreWebhookSecret: nucleusHubCoreWebhookSecret,
|
||||
HubCoreWebhookRegistrationService: fmt.Sprintf("%s-registration-webhook", hubCore.Name),
|
||||
ClusterManagerName: clusterManager.Name,
|
||||
ClusterManagerNamespace: clusterManagerNamespace,
|
||||
RegistrationImage: clusterManager.Spec.RegistrationImagePullSpec,
|
||||
ClusterManagerWebhookSecret: clusterManagerWebhookSecret,
|
||||
ClusterManagerWebhookRegistrationService: fmt.Sprintf("%s-registration-webhook", clusterManager.Name),
|
||||
}
|
||||
|
||||
// Update finalizer at first
|
||||
if hubCore.DeletionTimestamp.IsZero() {
|
||||
if clusterManager.DeletionTimestamp.IsZero() {
|
||||
hasFinalizer := false
|
||||
for i := range hubCore.Finalizers {
|
||||
if hubCore.Finalizers[i] == nucleusHubFinalizer {
|
||||
for i := range clusterManager.Finalizers {
|
||||
if clusterManager.Finalizers[i] == clusterManagerFinalizer {
|
||||
hasFinalizer = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasFinalizer {
|
||||
hubCore.Finalizers = append(hubCore.Finalizers, nucleusHubFinalizer)
|
||||
_, err := n.nucleusClient.Update(ctx, hubCore, metav1.UpdateOptions{})
|
||||
clusterManager.Finalizers = append(clusterManager.Finalizers, clusterManagerFinalizer)
|
||||
_, err := n.clusterManagerClient.Update(ctx, clusterManager, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// HubCore is deleting, we remove its related resources on hub
|
||||
if !hubCore.DeletionTimestamp.IsZero() {
|
||||
// ClusterManager is deleting, we remove its related resources on hub
|
||||
if !clusterManager.DeletionTimestamp.IsZero() {
|
||||
if err := n.cleanUp(ctx, controllerContext, config); err != nil {
|
||||
return err
|
||||
}
|
||||
return n.removeWorkFinalizer(ctx, hubCore)
|
||||
return n.removeClusterManagerFinalizer(ctx, clusterManager)
|
||||
}
|
||||
|
||||
ca, cert, key, err := n.ensureServingCertAndCA(
|
||||
ctx, config.HubCoreNamespace, config.HubCoreWebhookSecret, config.HubCoreWebhookRegistrationService)
|
||||
ctx, config.ClusterManagerNamespace, config.ClusterManagerWebhookSecret, config.ClusterManagerWebhookRegistrationService)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -202,27 +202,27 @@ func (n *nucleusHubController) sync(ctx context.Context, controllerContext facto
|
||||
n.currentGeneration[index] = currentGeneration
|
||||
}
|
||||
|
||||
conditions := &hubCore.Status.Conditions
|
||||
conditions := &clusterManager.Status.Conditions
|
||||
if len(errs) == 0 {
|
||||
helpers.SetNucleusCondition(conditions, nucleusapiv1.StatusCondition{
|
||||
Type: hubCoreApplied,
|
||||
helpers.SetOperatorCondition(conditions, operatorapiv1.StatusCondition{
|
||||
Type: clusterManagerApplied,
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: "HubCoreApplied",
|
||||
Message: "Components of hub core is applied",
|
||||
Reason: "ClusterManagerApplied",
|
||||
Message: "Components of cluster manager is applied",
|
||||
})
|
||||
} else {
|
||||
helpers.SetNucleusCondition(conditions, nucleusapiv1.StatusCondition{
|
||||
Type: hubCoreApplied,
|
||||
helpers.SetOperatorCondition(conditions, operatorapiv1.StatusCondition{
|
||||
Type: clusterManagerApplied,
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: "HubCoreApplyFailed",
|
||||
Message: "Components of hub core fail to be applied",
|
||||
Reason: "ClusterManagerApplyFailed",
|
||||
Message: "Components of cluster manager fail to be applied",
|
||||
})
|
||||
}
|
||||
|
||||
//TODO Check if all the pods are running.
|
||||
// Update status
|
||||
_, _, updatedErr := helpers.UpdateNucleusHubStatus(
|
||||
ctx, n.nucleusClient, hubCore.Name, helpers.UpdateNucleusHubConditionFn(*conditions...))
|
||||
_, _, updatedErr := helpers.UpdateClusterManagerStatus(
|
||||
ctx, n.clusterManagerClient, clusterManager.Name, helpers.UpdateClusterManagerConditionFn(*conditions...))
|
||||
if updatedErr != nil {
|
||||
errs = append(errs, updatedErr)
|
||||
}
|
||||
@@ -230,10 +230,10 @@ func (n *nucleusHubController) sync(ctx context.Context, controllerContext facto
|
||||
return operatorhelpers.NewMultiLineAggregate(errs)
|
||||
}
|
||||
|
||||
func (n *nucleusHubController) removeWorkFinalizer(ctx context.Context, deploy *nucleusapiv1.HubCore) error {
|
||||
func (n *clusterManagerController) removeClusterManagerFinalizer(ctx context.Context, deploy *operatorapiv1.ClusterManager) error {
|
||||
copiedFinalizers := []string{}
|
||||
for i := range deploy.Finalizers {
|
||||
if deploy.Finalizers[i] == nucleusHubFinalizer {
|
||||
if deploy.Finalizers[i] == clusterManagerFinalizer {
|
||||
continue
|
||||
}
|
||||
copiedFinalizers = append(copiedFinalizers, deploy.Finalizers[i])
|
||||
@@ -241,7 +241,7 @@ func (n *nucleusHubController) removeWorkFinalizer(ctx context.Context, deploy *
|
||||
|
||||
if len(deploy.Finalizers) != len(copiedFinalizers) {
|
||||
deploy.Finalizers = copiedFinalizers
|
||||
_, err := n.nucleusClient.Update(ctx, deploy, metav1.UpdateOptions{})
|
||||
_, err := n.clusterManagerClient.Update(ctx, deploy, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ func (n *nucleusHubController) removeWorkFinalizer(ctx context.Context, deploy *
|
||||
|
||||
// removeCRD removes crd, and check if crd resource is removed. Since the related cr is still being deleted,
|
||||
// it will check the crd existence after deletion, and only return nil when crd is not found.
|
||||
func (n *nucleusHubController) removeCRD(ctx context.Context, name string) error {
|
||||
func (n *clusterManagerController) removeCRD(ctx context.Context, name string) error {
|
||||
err := n.apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Delete(
|
||||
ctx, name, metav1.DeleteOptions{})
|
||||
switch {
|
||||
@@ -273,7 +273,7 @@ func (n *nucleusHubController) removeCRD(ctx context.Context, name string) error
|
||||
|
||||
// ensureServingCertAndCA generates self signed CA and server key/cert for webhook server.
|
||||
// TODO consider ca/cert renewal
|
||||
func (n *nucleusHubController) ensureServingCertAndCA(
|
||||
func (n *clusterManagerController) ensureServingCertAndCA(
|
||||
ctx context.Context, namespace, secretName, svcName string) ([]byte, []byte, []byte, error) {
|
||||
secret, err := n.kubeClient.CoreV1().Secrets(namespace).Get(ctx, secretName, metav1.GetOptions{})
|
||||
switch {
|
||||
@@ -285,7 +285,7 @@ func (n *nucleusHubController) ensureServingCertAndCA(
|
||||
}
|
||||
}
|
||||
|
||||
caConfig, err := crypto.MakeSelfSignedCAConfig("nucleus-webhook", 365)
|
||||
caConfig, err := crypto.MakeSelfSignedCAConfig("cluster-manager-webhook", 365)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -313,7 +313,7 @@ func (n *nucleusHubController) ensureServingCertAndCA(
|
||||
return caData, certData, keyData, nil
|
||||
}
|
||||
|
||||
func (n *nucleusHubController) cleanUp(
|
||||
func (n *clusterManagerController) cleanUp(
|
||||
ctx context.Context, controllerContext factory.SyncContext, config hubConfig) error {
|
||||
// Remove crd
|
||||
for _, name := range crdNames {
|
||||
@@ -1,4 +1,4 @@
|
||||
package hub
|
||||
package clustermanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
fakenucleusclient "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/fake"
|
||||
nucleusinformers "github.com/open-cluster-management/api/client/nucleus/informers/externalversions"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
fakeoperatorlient "github.com/open-cluster-management/api/client/operator/clientset/versioned/fake"
|
||||
operatorinformers "github.com/open-cluster-management/api/client/operator/informers/externalversions"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
@@ -28,11 +28,11 @@ import (
|
||||
)
|
||||
|
||||
type testController struct {
|
||||
controller *nucleusHubController
|
||||
controller *clusterManagerController
|
||||
kubeClient *fakekube.Clientset
|
||||
apiExtensionClient *fakeapiextensions.Clientset
|
||||
apiRegistrationClient *fakeapiregistration.Clientset
|
||||
nucleusClient *fakenucleusclient.Clientset
|
||||
operatorClient *fakeoperatorlient.Clientset
|
||||
}
|
||||
|
||||
type fakeSyncContext struct {
|
||||
@@ -53,34 +53,34 @@ func newFakeSyncContext(t *testing.T, key string) *fakeSyncContext {
|
||||
}
|
||||
}
|
||||
|
||||
func newHubCore(name string) *nucleusapiv1.HubCore {
|
||||
return &nucleusapiv1.HubCore{
|
||||
func newClusterManager(name string) *operatorapiv1.ClusterManager {
|
||||
return &operatorapiv1.ClusterManager{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Finalizers: []string{"nucleus.open-cluster-management.io/hub-core-cleanup"},
|
||||
Finalizers: []string{clusterManagerFinalizer},
|
||||
},
|
||||
Spec: nucleusapiv1.HubCoreSpec{
|
||||
Spec: operatorapiv1.ClusterManagerSpec{
|
||||
RegistrationImagePullSpec: "testregistration",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestController(hubcore *nucleusapiv1.HubCore) *testController {
|
||||
fakeNucleusClient := fakenucleusclient.NewSimpleClientset(hubcore)
|
||||
nucleusInformers := nucleusinformers.NewSharedInformerFactory(fakeNucleusClient, 5*time.Minute)
|
||||
func newTestController(clustermanager *operatorapiv1.ClusterManager) *testController {
|
||||
fakeOperatorClient := fakeoperatorlient.NewSimpleClientset(clustermanager)
|
||||
operatorInformers := operatorinformers.NewSharedInformerFactory(fakeOperatorClient, 5*time.Minute)
|
||||
|
||||
hubController := &nucleusHubController{
|
||||
nucleusClient: fakeNucleusClient.NucleusV1().HubCores(),
|
||||
nucleusLister: nucleusInformers.Nucleus().V1().HubCores().Lister(),
|
||||
currentGeneration: make([]int64, len(deploymentFiles)),
|
||||
hubController := &clusterManagerController{
|
||||
clusterManagerClient: fakeOperatorClient.OperatorV1().ClusterManagers(),
|
||||
clusterManagerLister: operatorInformers.Operator().V1().ClusterManagers().Lister(),
|
||||
currentGeneration: make([]int64, len(deploymentFiles)),
|
||||
}
|
||||
|
||||
store := nucleusInformers.Nucleus().V1().HubCores().Informer().GetStore()
|
||||
store.Add(hubcore)
|
||||
store := operatorInformers.Operator().V1().ClusterManagers().Informer().GetStore()
|
||||
store.Add(clustermanager)
|
||||
|
||||
return &testController{
|
||||
controller: hubController,
|
||||
nucleusClient: fakeNucleusClient,
|
||||
controller: hubController,
|
||||
operatorClient: fakeOperatorClient,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func assertEqualNumber(t *testing.T, actual, expected int) {
|
||||
}
|
||||
|
||||
func assertCondition(t *testing.T, actual runtime.Object, expectedCondition string, expectedStatus metav1.ConditionStatus) {
|
||||
hubCore := actual.(*nucleusapiv1.HubCore)
|
||||
hubCore := actual.(*operatorapiv1.ClusterManager)
|
||||
conditions := hubCore.Status.Conditions
|
||||
if len(conditions) != 1 {
|
||||
t.Errorf("expected 1 condition but got: %#v", conditions)
|
||||
@@ -142,7 +142,7 @@ func ensureNameNamespace(t *testing.T, actualName, actualNamespace, name, namesp
|
||||
}
|
||||
}
|
||||
|
||||
func ensureObject(t *testing.T, object runtime.Object, hubCore *nucleusapiv1.HubCore) {
|
||||
func ensureObject(t *testing.T, object runtime.Object, hubCore *operatorapiv1.ClusterManager) {
|
||||
access, err := meta.Accessor(object)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to access objectmeta: %v", err)
|
||||
@@ -150,7 +150,7 @@ func ensureObject(t *testing.T, object runtime.Object, hubCore *nucleusapiv1.Hub
|
||||
|
||||
switch o := object.(type) {
|
||||
case *corev1.Namespace:
|
||||
ensureNameNamespace(t, access.GetName(), "", nucleusHubCoreNamespace, "")
|
||||
ensureNameNamespace(t, access.GetName(), "", clusterManagerNamespace, "")
|
||||
case *appsv1.Deployment:
|
||||
if hubCore.Spec.RegistrationImagePullSpec != o.Spec.Template.Spec.Containers[0].Image {
|
||||
t.Errorf("Image does not match to the expected.")
|
||||
@@ -160,8 +160,8 @@ func ensureObject(t *testing.T, object runtime.Object, hubCore *nucleusapiv1.Hub
|
||||
|
||||
// TestSyncDeploy tests sync manifests of hub component
|
||||
func TestSyncDeploy(t *testing.T) {
|
||||
hubCore := newHubCore("testhub")
|
||||
controller := newTestController(hubCore).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
clusterManager := newClusterManager("testhub")
|
||||
controller := newTestController(clusterManager).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
syncContext := newFakeSyncContext(t, "testhub")
|
||||
|
||||
err := controller.controller.sync(nil, syncContext)
|
||||
@@ -181,7 +181,7 @@ func TestSyncDeploy(t *testing.T) {
|
||||
// Check if resources are created as expected
|
||||
assertEqualNumber(t, len(createKubeObjects), 12)
|
||||
for _, object := range createKubeObjects {
|
||||
ensureObject(t, object, hubCore)
|
||||
ensureObject(t, object, clusterManager)
|
||||
}
|
||||
|
||||
createCRDObjects := []runtime.Object{}
|
||||
@@ -206,18 +206,18 @@ func TestSyncDeploy(t *testing.T) {
|
||||
// Check if resources are created as expected
|
||||
assertEqualNumber(t, len(createAPIServiceObjects), 1)
|
||||
|
||||
nucleusAction := controller.nucleusClient.Actions()
|
||||
assertEqualNumber(t, len(nucleusAction), 2)
|
||||
assertAction(t, nucleusAction[1], "update")
|
||||
assertCondition(t, nucleusAction[1].(clienttesting.UpdateActionImpl).Object, hubCoreApplied, metav1.ConditionTrue)
|
||||
clusterManagerAction := controller.operatorClient.Actions()
|
||||
assertEqualNumber(t, len(clusterManagerAction), 2)
|
||||
assertAction(t, clusterManagerAction[1], "update")
|
||||
assertCondition(t, clusterManagerAction[1].(clienttesting.UpdateActionImpl).Object, clusterManagerApplied, metav1.ConditionTrue)
|
||||
}
|
||||
|
||||
// TestSyncDelete test cleanup hub deploy
|
||||
func TestSyncDelete(t *testing.T) {
|
||||
hubCore := newHubCore("testhub")
|
||||
clusterManager := newClusterManager("testhub")
|
||||
now := metav1.Now()
|
||||
hubCore.ObjectMeta.SetDeletionTimestamp(&now)
|
||||
controller := newTestController(hubCore).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
clusterManager.ObjectMeta.SetDeletionTimestamp(&now)
|
||||
controller := newTestController(clusterManager).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
syncContext := newFakeSyncContext(t, "testhub")
|
||||
|
||||
err := controller.controller.sync(nil, syncContext)
|
||||
@@ -260,22 +260,22 @@ func TestSyncDelete(t *testing.T) {
|
||||
for _, action := range deleteKubeActions {
|
||||
switch action.Resource.Resource {
|
||||
case "namespaces":
|
||||
ensureNameNamespace(t, action.Name, "", nucleusHubCoreNamespace, "")
|
||||
ensureNameNamespace(t, action.Name, "", clusterManagerNamespace, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeleteCRD test delete crds
|
||||
func TestDeleteCRD(t *testing.T) {
|
||||
hubCore := newHubCore("testhub")
|
||||
clusterManager := newClusterManager("testhub")
|
||||
now := metav1.Now()
|
||||
hubCore.ObjectMeta.SetDeletionTimestamp(&now)
|
||||
clusterManager.ObjectMeta.SetDeletionTimestamp(&now)
|
||||
crd := &apiextensionsv1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: crdNames[0],
|
||||
},
|
||||
}
|
||||
controller := newTestController(hubCore).withCRDObject(crd).withKubeObject().withAPIServiceObject()
|
||||
controller := newTestController(clusterManager).withCRDObject(crd).withKubeObject().withAPIServiceObject()
|
||||
|
||||
// Return crd with the first get, and return not found with the 2nd get
|
||||
getCount := 0
|
||||
@@ -301,8 +301,8 @@ func TestDeleteCRD(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnsureServingCertAndCA(t *testing.T) {
|
||||
hubCore := newHubCore("testhub")
|
||||
controller := newTestController(hubCore).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
clusterManager := newClusterManager("testhub")
|
||||
controller := newTestController(clusterManager).withCRDObject().withKubeObject().withAPIServiceObject()
|
||||
ca, certificate, key, err := controller.controller.ensureServingCertAndCA(context.TODO(), "ns1", "kubeconfig", "webhook")
|
||||
if err != nil {
|
||||
t.Errorf("Expect no error when generating serving cert: %v", err)
|
||||
@@ -315,7 +315,7 @@ func TestEnsureServingCertAndCA(t *testing.T) {
|
||||
t.Errorf("Expect 2 cert is parsed, actual %d", len(certs))
|
||||
}
|
||||
for _, cert := range certs {
|
||||
if cert.Subject.CommonName != "webhook.ns1.svc" && cert.Subject.CommonName != "nucleus-webhook" {
|
||||
if cert.Subject.CommonName != "webhook.ns1.svc" && cert.Subject.CommonName != "cluster-manager-webhook" {
|
||||
t.Errorf("Common name in cert is not correct, actual %s", cert.Subject.CommonName)
|
||||
}
|
||||
}
|
||||
@@ -331,7 +331,7 @@ func TestEnsureServingCertAndCA(t *testing.T) {
|
||||
"tls.key": key,
|
||||
},
|
||||
}
|
||||
controller = newTestController(hubCore).withCRDObject().withKubeObject(secret).withAPIServiceObject()
|
||||
controller = newTestController(clusterManager).withCRDObject().withKubeObject(secret).withAPIServiceObject()
|
||||
actualCA, actualCert, actualKey, err := controller.controller.ensureServingCertAndCA(context.TODO(), "ns1", "kubeconfig", "webhook")
|
||||
if err != nil {
|
||||
t.Errorf("Expect no error when generating serving cert: %v", err)
|
||||
641
pkg/operators/klusterlet/bindata/bindata.go
Normal file
641
pkg/operators/klusterlet/bindata/bindata.go
Normal file
@@ -0,0 +1,641 @@
|
||||
// Code generated for package bindata by go-bindata DO NOT EDIT. (@generated)
|
||||
// sources:
|
||||
// manifests/klusterlet/klusterlet-registration-clusterrole.yaml
|
||||
// manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml
|
||||
// manifests/klusterlet/klusterlet-registration-deployment.yaml
|
||||
// manifests/klusterlet/klusterlet-registration-role.yaml
|
||||
// manifests/klusterlet/klusterlet-registration-rolebinding.yaml
|
||||
// manifests/klusterlet/klusterlet-registration-serviceaccount.yaml
|
||||
// manifests/klusterlet/klusterlet-work-clusterrole.yaml
|
||||
// manifests/klusterlet/klusterlet-work-clusterrolebinding-addition.yaml
|
||||
// manifests/klusterlet/klusterlet-work-clusterrolebinding.yaml
|
||||
// manifests/klusterlet/klusterlet-work-deployment.yaml
|
||||
// manifests/klusterlet/klusterlet-work-serviceaccount.yaml
|
||||
package bindata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
// Name return file name
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
|
||||
// Size return file size
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
|
||||
// Mode return file mode
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
|
||||
// Mode return file modify time
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
|
||||
// IsDir return file whether a directory
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return fi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
// Sys return file is sys mode
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationClusterroleYaml = []byte(`# Clusterrole for work agent in addition to admin clusterrole.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch nodes.
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes", "configmaps", "secrets"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources: ["subjectaccessreviews"]
|
||||
verbs: ["create"]
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationDeploymentYaml = []byte(`kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
labels:
|
||||
app: klusterlet-registration-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: klusterlet-registration-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: klusterlet-registration-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .KlusterletName }}-registration-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .RegistrationImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- "/registration"
|
||||
- "agent"
|
||||
- "--cluster-name={{ .ClusterName }}"
|
||||
- "--bootstrap-kubeconfig=/spoke/bootstrap/kubeconfig"
|
||||
- "--spoke-external-server-urls={{ .ExternalServerURL }}"
|
||||
volumeMounts:
|
||||
- name: bootstrap-secret
|
||||
mountPath: "/spoke/bootstrap"
|
||||
readOnly: true
|
||||
- name: hub-kubeconfig-secret
|
||||
mountPath: "/spoke/hub-kubeconfig"
|
||||
readOnly: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
volumes:
|
||||
- name: bootstrap-secret
|
||||
secret:
|
||||
secretName: {{ .BootStrapKubeConfigSecret }}
|
||||
- name: hub-kubeconfig-secret
|
||||
secret:
|
||||
secretName: {{ .HubKubeConfigSecret }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationRoleYaml = []byte(`# Role for registration agent.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "secrets"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
|
||||
- apiGroups: ["", "events.k8s.io"]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch", "update"]
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationRoleYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationRoleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationRoleYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationRoleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationRolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationRolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationRolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationRolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationRolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletRegistrationServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-registration-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletRegistrationServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletRegistrationServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletRegistrationServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-registration-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletWorkClusterroleYaml = []byte(`# Clusterrole for work agent in addition to admin clusterrole.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch/create/delete crds.
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "update"]
|
||||
# Allow agent to create/delete namespaces, get/list are contained in admin role already
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces"]
|
||||
verbs: ["create", "delete"]
|
||||
# Allow agent to manage role/rolebinding/clusterrole/clusterrolebinding
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterrolebindings", "rolebindings"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "escalate", "bind"]
|
||||
# Allow agent to create sar
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources: ["subjectaccessreviews"]
|
||||
verbs: ["create"]
|
||||
# Allow agent to create events
|
||||
- apiGroups: ["", "events.k8s.io"]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch", "update"]
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletWorkClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletWorkClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-work-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent-addition
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletWorkClusterrolebindingAdditionYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-work-clusterrolebinding-addition.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletWorkClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .KlusterletName }}-work-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
# We deploy a controller that could work with permission lower than cluster-admin, the tradeoff is
|
||||
# responsivity because list/watch cannot be maintained over too many namespaces.
|
||||
name: admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletWorkClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletWorkClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletWorkClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-work-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletWorkDeploymentYaml = []byte(`kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-work-agent
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
labels:
|
||||
app: klusterlet-manifestwork-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: klusterlet-manifestwork-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: klusterlet-manifestwork-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .KlusterletName }}-work-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .WorkImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- "/work"
|
||||
- "agent"
|
||||
- "--spoke-cluster-name={{ .ClusterName }}"
|
||||
- "--hub-kubeconfig=/spoke/hub-kubeconfig/kubeconfig"
|
||||
volumeMounts:
|
||||
- name: hub-kubeconfig-secret
|
||||
mountPath: "/spoke/hub-kubeconfig"
|
||||
readOnly: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
volumes:
|
||||
- name: hub-kubeconfig-secret
|
||||
secret:
|
||||
secretName: {{ .HubKubeConfigSecret }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletWorkDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletWorkDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletWorkDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletWorkDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-work-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsKlusterletKlusterletWorkServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .KlusterletName }}-work-sa
|
||||
namespace: {{ .KlusterletNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsKlusterletKlusterletWorkServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsKlusterletKlusterletWorkServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsKlusterletKlusterletWorkServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsKlusterletKlusterletWorkServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/klusterlet/klusterlet-work-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.bytes, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
|
||||
// MustAsset is like Asset but panics when Asset would return an error.
|
||||
// It simplifies safe initialization of global variables.
|
||||
func MustAsset(name string) []byte {
|
||||
a, err := Asset(name)
|
||||
if err != nil {
|
||||
panic("asset: Asset(" + name + "): " + err.Error())
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// AssetInfo loads and returns the asset info for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func AssetInfo(name string) (os.FileInfo, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.info, nil
|
||||
}
|
||||
return nil, fmt.Errorf("AssetInfo %s not found", name)
|
||||
}
|
||||
|
||||
// AssetNames returns the names of the assets.
|
||||
func AssetNames() []string {
|
||||
names := make([]string, 0, len(_bindata))
|
||||
for name := range _bindata {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// _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,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
// directory embedded in the file by go-bindata.
|
||||
// For example if you run go-bindata on data/... and data contains the
|
||||
// following hierarchy:
|
||||
// data/
|
||||
// foo.txt
|
||||
// img/
|
||||
// a.png
|
||||
// b.png
|
||||
// then AssetDir("data") would return []string{"foo.txt", "img"}
|
||||
// AssetDir("data/img") would return []string{"a.png", "b.png"}
|
||||
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
|
||||
// AssetDir("") will return []string{"data"}.
|
||||
func AssetDir(name string) ([]string, error) {
|
||||
node := _bintree
|
||||
if len(name) != 0 {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
pathList := strings.Split(cannonicalName, "/")
|
||||
for _, p := range pathList {
|
||||
node = node.Children[p]
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Func != nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
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{}},
|
||||
}},
|
||||
}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory
|
||||
func RestoreAsset(dir, name string) error {
|
||||
data, err := Asset(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := AssetInfo(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreAssets restores an asset under the given directory recursively
|
||||
func RestoreAssets(dir, name string) error {
|
||||
children, err := AssetDir(name)
|
||||
// File
|
||||
if err != nil {
|
||||
return RestoreAsset(dir, name)
|
||||
}
|
||||
// Dir
|
||||
for _, child := range children {
|
||||
err = RestoreAssets(dir, filepath.Join(name, child))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package spoke
|
||||
package klusterlet
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -21,69 +21,69 @@ import (
|
||||
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
|
||||
operatorhelpers "github.com/openshift/library-go/pkg/operator/v1helpers"
|
||||
|
||||
nucleusv1client "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/typed/nucleus/v1"
|
||||
nucleusinformer "github.com/open-cluster-management/api/client/nucleus/informers/externalversions/nucleus/v1"
|
||||
nucleuslister "github.com/open-cluster-management/api/client/nucleus/listers/nucleus/v1"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
operatorv1client "github.com/open-cluster-management/api/client/operator/clientset/versioned/typed/operator/v1"
|
||||
operatorinformer "github.com/open-cluster-management/api/client/operator/informers/externalversions/operator/v1"
|
||||
operatorlister "github.com/open-cluster-management/api/client/operator/listers/operator/v1"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
"github.com/open-cluster-management/nucleus/pkg/helpers"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/spoke/bindata"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/klusterlet/bindata"
|
||||
)
|
||||
|
||||
const (
|
||||
nucleusSpokeFinalizer = "nucleus.open-cluster-management.io/spoke-core-cleanup"
|
||||
klusterletFinalizer = "operator.open-cluster-management.io/klusterlet-cleanup"
|
||||
bootstrapHubKubeConfigSecret = "bootstrap-hub-kubeconfig"
|
||||
hubKubeConfigSecret = "hub-kubeconfig-secret"
|
||||
nucleusSpokeCoreNamespace = "open-cluster-management-spoke"
|
||||
spokeCoreApplied = "Applied"
|
||||
klusterletNamespace = "open-cluster-management-agent"
|
||||
klusterletApplied = "Applied"
|
||||
spokeRegistrationDegraded = "SpokeRegistrationDegraded"
|
||||
)
|
||||
|
||||
var (
|
||||
staticResourceFiles = []string{
|
||||
"manifests/spoke/spoke-registration-serviceaccount.yaml",
|
||||
"manifests/spoke/spoke-registration-clusterrole.yaml",
|
||||
"manifests/spoke/spoke-registration-clusterrolebinding.yaml",
|
||||
"manifests/spoke/spoke-registration-role.yaml",
|
||||
"manifests/spoke/spoke-registration-rolebinding.yaml",
|
||||
"manifests/spoke/spoke-work-serviceaccount.yaml",
|
||||
"manifests/spoke/spoke-work-clusterrole.yaml",
|
||||
"manifests/spoke/spoke-work-clusterrolebinding.yaml",
|
||||
"manifests/spoke/spoke-work-clusterrolebinding-addition.yaml",
|
||||
"manifests/klusterlet/klusterlet-registration-serviceaccount.yaml",
|
||||
"manifests/klusterlet/klusterlet-registration-clusterrole.yaml",
|
||||
"manifests/klusterlet/klusterlet-registration-clusterrolebinding.yaml",
|
||||
"manifests/klusterlet/klusterlet-registration-role.yaml",
|
||||
"manifests/klusterlet/klusterlet-registration-rolebinding.yaml",
|
||||
"manifests/klusterlet/klusterlet-work-serviceaccount.yaml",
|
||||
"manifests/klusterlet/klusterlet-work-clusterrole.yaml",
|
||||
"manifests/klusterlet/klusterlet-work-clusterrolebinding.yaml",
|
||||
"manifests/klusterlet/klusterlet-work-clusterrolebinding-addition.yaml",
|
||||
}
|
||||
)
|
||||
|
||||
type nucleusSpokeController struct {
|
||||
nucleusClient nucleusv1client.SpokeCoreInterface
|
||||
nucleusLister nucleuslister.SpokeCoreLister
|
||||
type klusterletController struct {
|
||||
klusterletClient operatorv1client.KlusterletInterface
|
||||
klusterletLister operatorlister.KlusterletLister
|
||||
kubeClient kubernetes.Interface
|
||||
registrationGeneration int64
|
||||
workGeneration int64
|
||||
}
|
||||
|
||||
// NewNucleusSpokeController construct nucleus spoke controller
|
||||
func NewNucleusSpokeController(
|
||||
// NewKlusterletController construct klusterlet controller
|
||||
func NewKlusterletController(
|
||||
kubeClient kubernetes.Interface,
|
||||
nucleusClient nucleusv1client.SpokeCoreInterface,
|
||||
nucleusInformer nucleusinformer.SpokeCoreInformer,
|
||||
klusterletClient operatorv1client.KlusterletInterface,
|
||||
klusterletInformer operatorinformer.KlusterletInformer,
|
||||
recorder events.Recorder) factory.Controller {
|
||||
controller := &nucleusSpokeController{
|
||||
kubeClient: kubeClient,
|
||||
nucleusClient: nucleusClient,
|
||||
nucleusLister: nucleusInformer.Lister(),
|
||||
controller := &klusterletController{
|
||||
kubeClient: kubeClient,
|
||||
klusterletClient: klusterletClient,
|
||||
klusterletLister: klusterletInformer.Lister(),
|
||||
}
|
||||
|
||||
return factory.New().WithSync(controller.sync).
|
||||
WithInformersQueueKeyFunc(func(obj runtime.Object) string {
|
||||
accessor, _ := meta.Accessor(obj)
|
||||
return accessor.GetName()
|
||||
}, nucleusInformer.Informer()).
|
||||
ToController("NucleusSpokeController", recorder)
|
||||
}, klusterletInformer.Informer()).
|
||||
ToController("KlusterletController", recorder)
|
||||
}
|
||||
|
||||
// spokeConfig is used to render the template of hub manifests
|
||||
type spokeConfig struct {
|
||||
SpokeCoreName string
|
||||
SpokeCoreNamespace string
|
||||
KlusterletName string
|
||||
KlusterletNamespace string
|
||||
RegistrationImage string
|
||||
WorkImage string
|
||||
ClusterName string
|
||||
@@ -92,10 +92,10 @@ type spokeConfig struct {
|
||||
BootStrapKubeConfigSecret string
|
||||
}
|
||||
|
||||
func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
|
||||
spokeCoreName := controllerContext.QueueKey()
|
||||
klog.V(4).Infof("Reconciling SpokeCore %q", spokeCoreName)
|
||||
spokeCore, err := n.nucleusLister.Get(spokeCoreName)
|
||||
func (n *klusterletController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
|
||||
klusterletName := controllerContext.QueueKey()
|
||||
klog.V(4).Infof("Reconciling Klusterlet %q", klusterletName)
|
||||
klusterlet, err := n.klusterletLister.Get(klusterletName)
|
||||
if errors.IsNotFound(err) {
|
||||
// AgentCore not found, could have been deleted, do nothing.
|
||||
return nil
|
||||
@@ -103,77 +103,77 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spokeCore = spokeCore.DeepCopy()
|
||||
klusterlet = klusterlet.DeepCopy()
|
||||
|
||||
config := spokeConfig{
|
||||
SpokeCoreName: spokeCore.Name,
|
||||
SpokeCoreNamespace: spokeCore.Spec.Namespace,
|
||||
RegistrationImage: spokeCore.Spec.RegistrationImagePullSpec,
|
||||
WorkImage: spokeCore.Spec.WorkImagePullSpec,
|
||||
ClusterName: spokeCore.Spec.ClusterName,
|
||||
KlusterletName: klusterlet.Name,
|
||||
KlusterletNamespace: klusterlet.Spec.Namespace,
|
||||
RegistrationImage: klusterlet.Spec.RegistrationImagePullSpec,
|
||||
WorkImage: klusterlet.Spec.WorkImagePullSpec,
|
||||
ClusterName: klusterlet.Spec.ClusterName,
|
||||
BootStrapKubeConfigSecret: bootstrapHubKubeConfigSecret,
|
||||
HubKubeConfigSecret: hubKubeConfigSecret,
|
||||
ExternalServerURL: getServersFromSpokeCore(spokeCore),
|
||||
ExternalServerURL: getServersFromKlusterlet(klusterlet),
|
||||
}
|
||||
// If namespace is not set, use the default namespace
|
||||
if config.SpokeCoreNamespace == "" {
|
||||
config.SpokeCoreNamespace = nucleusSpokeCoreNamespace
|
||||
if config.KlusterletNamespace == "" {
|
||||
config.KlusterletNamespace = klusterletNamespace
|
||||
}
|
||||
|
||||
// Update finalizer at first
|
||||
if spokeCore.DeletionTimestamp.IsZero() {
|
||||
if klusterlet.DeletionTimestamp.IsZero() {
|
||||
hasFinalizer := false
|
||||
for i := range spokeCore.Finalizers {
|
||||
if spokeCore.Finalizers[i] == nucleusSpokeFinalizer {
|
||||
for i := range klusterlet.Finalizers {
|
||||
if klusterlet.Finalizers[i] == klusterletFinalizer {
|
||||
hasFinalizer = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasFinalizer {
|
||||
spokeCore.Finalizers = append(spokeCore.Finalizers, nucleusSpokeFinalizer)
|
||||
_, err := n.nucleusClient.Update(ctx, spokeCore, metav1.UpdateOptions{})
|
||||
klusterlet.Finalizers = append(klusterlet.Finalizers, klusterletFinalizer)
|
||||
_, err := n.klusterletClient.Update(ctx, klusterlet, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// SpokeCore is deleting, we remove its related resources on spoke
|
||||
if !spokeCore.DeletionTimestamp.IsZero() {
|
||||
// Klusterlet is deleting, we remove its related resources on spoke
|
||||
if !klusterlet.DeletionTimestamp.IsZero() {
|
||||
if err := n.cleanUp(ctx, controllerContext, config); err != nil {
|
||||
return err
|
||||
}
|
||||
return n.removeWorkFinalizer(ctx, spokeCore)
|
||||
return n.removeKlusterletFinalizer(ctx, klusterlet)
|
||||
}
|
||||
|
||||
// Start deploy spoke core components
|
||||
// Check if namespace exists
|
||||
_, err = n.kubeClient.CoreV1().Namespaces().Get(ctx, config.SpokeCoreNamespace, metav1.GetOptions{})
|
||||
_, err = n.kubeClient.CoreV1().Namespaces().Get(ctx, config.KlusterletNamespace, metav1.GetOptions{})
|
||||
switch {
|
||||
case errors.IsNotFound(err):
|
||||
_, createErr := n.kubeClient.CoreV1().Namespaces().Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: config.SpokeCoreNamespace},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: config.KlusterletNamespace},
|
||||
}, metav1.CreateOptions{})
|
||||
if createErr != nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to create namespace %q: %v", config.SpokeCoreNamespace, createErr),
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to create namespace %q: %v", config.KlusterletNamespace, createErr),
|
||||
}))
|
||||
return createErr
|
||||
}
|
||||
case err != nil:
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to get namespace %q: %v", config.SpokeCoreNamespace, err),
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to get namespace %q: %v", config.KlusterletNamespace, err),
|
||||
}))
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if bootstrap secret exists
|
||||
_, err = n.kubeClient.CoreV1().Secrets(config.SpokeCoreNamespace).Get(
|
||||
_, err = n.kubeClient.CoreV1().Secrets(config.KlusterletNamespace).Get(
|
||||
ctx, config.BootStrapKubeConfigSecret, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to get bootstrap secret -n %q %q: %v", config.SpokeCoreNamespace, config.BootStrapKubeConfigSecret, err),
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to get bootstrap secret -n %q %q: %v", config.KlusterletNamespace, config.BootStrapKubeConfigSecret, err),
|
||||
}))
|
||||
return err
|
||||
}
|
||||
@@ -197,36 +197,36 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
|
||||
if len(errs) > 0 {
|
||||
applyErrors := operatorhelpers.NewMultiLineAggregate(errs)
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: applyErrors.Error(),
|
||||
}))
|
||||
return applyErrors
|
||||
}
|
||||
|
||||
// Create hub config secret
|
||||
hubSecret, err := n.kubeClient.CoreV1().Secrets(config.SpokeCoreNamespace).Get(ctx, hubKubeConfigSecret, metav1.GetOptions{})
|
||||
hubSecret, err := n.kubeClient.CoreV1().Secrets(config.KlusterletNamespace).Get(ctx, hubKubeConfigSecret, metav1.GetOptions{})
|
||||
switch {
|
||||
case errors.IsNotFound(err):
|
||||
// Create an empty secret with placeholder
|
||||
hubSecret = &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: hubKubeConfigSecret,
|
||||
Namespace: config.SpokeCoreNamespace,
|
||||
Namespace: config.KlusterletNamespace,
|
||||
},
|
||||
Data: map[string][]byte{"placeholder": []byte("placeholder")},
|
||||
}
|
||||
hubSecret, err = n.kubeClient.CoreV1().Secrets(config.SpokeCoreNamespace).Create(ctx, hubSecret, metav1.CreateOptions{})
|
||||
hubSecret, err = n.kubeClient.CoreV1().Secrets(config.KlusterletNamespace).Create(ctx, hubSecret, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to create hub kubeconfig secret -n %q %q: %v", hubSecret.Namespace, hubSecret.Name, err),
|
||||
}))
|
||||
return err
|
||||
}
|
||||
case err != nil:
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to get hub kubeconfig secret with error %v", err),
|
||||
}))
|
||||
return err
|
||||
@@ -240,10 +240,10 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
return assets.MustCreateAssetFromTemplate(name, bindata.MustAsset(filepath.Join("", name)), config).Data, nil
|
||||
},
|
||||
controllerContext.Recorder(),
|
||||
"manifests/spoke/spoke-registration-deployment.yaml")
|
||||
"manifests/klusterlet/klusterlet-registration-deployment.yaml")
|
||||
if err != nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to deploy registration deployment with error %v", err),
|
||||
}))
|
||||
return err
|
||||
@@ -259,10 +259,10 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
return assets.MustCreateAssetFromTemplate(name, bindata.MustAsset(filepath.Join("", name)), config).Data, nil
|
||||
},
|
||||
controllerContext.Recorder(),
|
||||
"manifests/spoke/spoke-work-deployment.yaml")
|
||||
"manifests/klusterlet/klusterlet-work-deployment.yaml")
|
||||
if err != nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionFalse, Reason: "SpokeCoreApplyFailed",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionFalse, Reason: "KlusterletApplyFailed",
|
||||
Message: fmt.Sprintf("Failed to deploy work deployment with error %v", err),
|
||||
}))
|
||||
return err
|
||||
@@ -271,8 +271,8 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
n.workGeneration = generation
|
||||
|
||||
// if we get here, we have successfully applied everything and should indicate that
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
Type: spokeCoreApplied, Status: metav1.ConditionTrue, Reason: "SpokeCoreApplied",
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: klusterletApplied, Status: metav1.ConditionTrue, Reason: "KlusterletApplied",
|
||||
Message: "Spoke Core Component Applied",
|
||||
}))
|
||||
|
||||
@@ -285,7 +285,7 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
if config.ClusterName == "" {
|
||||
clusterName := hubSecret.Data["cluster-name"]
|
||||
if clusterName == nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: spokeRegistrationDegraded, Status: metav1.ConditionTrue, Reason: "ClusterNameMissing",
|
||||
Message: fmt.Sprintf("Failed to get cluster name from `kubectl get secret -n %q %q -ojsonpath='{.data.cluster-name}`. This is set by the spoke registration deployment.", hubSecret.Namespace, hubSecret.Name),
|
||||
}))
|
||||
@@ -296,7 +296,7 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
|
||||
// If hub kubeconfig does not exist, return err.
|
||||
if hubSecret.Data["kubeconfig"] == nil {
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: spokeRegistrationDegraded, Status: metav1.ConditionTrue, Reason: "HubKubeconfigMissing",
|
||||
Message: fmt.Sprintf("Failed to get cluster name from `kubectl get secret -n %q %q -ojsonpath='{.data.kubeconfig}`. This is set by the spoke registration deployment, but the CSR must be approved by the cluster-admin on the hub.", hubSecret.Namespace, hubSecret.Name),
|
||||
}))
|
||||
@@ -304,29 +304,29 @@ func (n *nucleusSpokeController) sync(ctx context.Context, controllerContext fac
|
||||
}
|
||||
// TODO it is possible to verify the kubeconfig actually works.
|
||||
|
||||
helpers.UpdateNucleusSpokeStatus(ctx, n.nucleusClient, spokeCoreName, helpers.UpdateNucleusSpokeConditionFn(nucleusapiv1.StatusCondition{
|
||||
helpers.UpdateKlusterletStatus(ctx, n.klusterletClient, klusterletName, helpers.UpdateKlusterletConditionFn(operatorapiv1.StatusCondition{
|
||||
Type: spokeRegistrationDegraded, Status: metav1.ConditionFalse, Reason: "RegistrationFunctional",
|
||||
Message: "Registration is managing credentials",
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nucleusSpokeController) cleanUp(ctx context.Context, controllerContext factory.SyncContext, config spokeConfig) error {
|
||||
func (n *klusterletController) cleanUp(ctx context.Context, controllerContext factory.SyncContext, config spokeConfig) error {
|
||||
// Remove deployment
|
||||
registrationDeployment := fmt.Sprintf("%s-registration-agent", config.SpokeCoreName)
|
||||
err := n.kubeClient.AppsV1().Deployments(config.SpokeCoreNamespace).Delete(ctx, registrationDeployment, metav1.DeleteOptions{})
|
||||
registrationDeployment := fmt.Sprintf("%s-registration-agent", config.KlusterletName)
|
||||
err := n.kubeClient.AppsV1().Deployments(config.KlusterletNamespace).Delete(ctx, registrationDeployment, metav1.DeleteOptions{})
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
controllerContext.Recorder().Eventf("DeploymentDeleted", "deployment %s is deleted", registrationDeployment)
|
||||
workDeployment := fmt.Sprintf("%s-work-agent", config.SpokeCoreName)
|
||||
err = n.kubeClient.AppsV1().Deployments(config.SpokeCoreNamespace).Delete(ctx, workDeployment, metav1.DeleteOptions{})
|
||||
workDeployment := fmt.Sprintf("%s-work-agent", config.KlusterletName)
|
||||
err = n.kubeClient.AppsV1().Deployments(config.KlusterletNamespace).Delete(ctx, workDeployment, metav1.DeleteOptions{})
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove secret
|
||||
err = n.kubeClient.CoreV1().Secrets(config.SpokeCoreNamespace).Delete(ctx, config.HubKubeConfigSecret, metav1.DeleteOptions{})
|
||||
err = n.kubeClient.CoreV1().Secrets(config.KlusterletNamespace).Delete(ctx, config.HubKubeConfigSecret, metav1.DeleteOptions{})
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -351,10 +351,10 @@ func (n *nucleusSpokeController) cleanUp(ctx context.Context, controllerContext
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nucleusSpokeController) removeWorkFinalizer(ctx context.Context, deploy *nucleusapiv1.SpokeCore) error {
|
||||
func (n *klusterletController) removeKlusterletFinalizer(ctx context.Context, deploy *operatorapiv1.Klusterlet) error {
|
||||
copiedFinalizers := []string{}
|
||||
for i := range deploy.Finalizers {
|
||||
if deploy.Finalizers[i] == nucleusSpokeFinalizer {
|
||||
if deploy.Finalizers[i] == klusterletFinalizer {
|
||||
continue
|
||||
}
|
||||
copiedFinalizers = append(copiedFinalizers, deploy.Finalizers[i])
|
||||
@@ -362,7 +362,7 @@ func (n *nucleusSpokeController) removeWorkFinalizer(ctx context.Context, deploy
|
||||
|
||||
if len(deploy.Finalizers) != len(copiedFinalizers) {
|
||||
deploy.Finalizers = copiedFinalizers
|
||||
_, err := n.nucleusClient.Update(ctx, deploy, metav1.UpdateOptions{})
|
||||
_, err := n.klusterletClient.Update(ctx, deploy, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ func readKubuConfigFromSecret(secret *corev1.Secret, config spokeConfig) (string
|
||||
}
|
||||
|
||||
// TODO also read CABundle from ExternalServerURLs and set into registration deployment
|
||||
func getServersFromSpokeCore(spokeCore *nucleusapiv1.SpokeCore) string {
|
||||
func getServersFromKlusterlet(spokeCore *operatorapiv1.Klusterlet) string {
|
||||
if spokeCore.Spec.ExternalServerURLs == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package spoke
|
||||
package klusterlet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
fakenucleusclient "github.com/open-cluster-management/api/client/nucleus/clientset/versioned/fake"
|
||||
nucleusinformers "github.com/open-cluster-management/api/client/nucleus/informers/externalversions"
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
fakeoperatorclient "github.com/open-cluster-management/api/client/operator/clientset/versioned/fake"
|
||||
operatorinformers "github.com/open-cluster-management/api/client/operator/informers/externalversions"
|
||||
opratorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
"github.com/open-cluster-management/nucleus/pkg/helpers"
|
||||
"github.com/openshift/library-go/pkg/operator/events"
|
||||
"github.com/openshift/library-go/pkg/operator/events/eventstesting"
|
||||
@@ -26,9 +26,9 @@ import (
|
||||
)
|
||||
|
||||
type testController struct {
|
||||
controller *nucleusSpokeController
|
||||
kubeClient *fakekube.Clientset
|
||||
nucleusClient *fakenucleusclient.Clientset
|
||||
controller *klusterletController
|
||||
kubeClient *fakekube.Clientset
|
||||
operatorClient *fakeoperatorclient.Clientset
|
||||
}
|
||||
|
||||
type fakeSyncContext struct {
|
||||
@@ -59,18 +59,18 @@ func newSecret(name, namespace string) *corev1.Secret {
|
||||
}
|
||||
}
|
||||
|
||||
func newSpokeCore(name, namespace, clustername string) *nucleusapiv1.SpokeCore {
|
||||
return &nucleusapiv1.SpokeCore{
|
||||
func newKlusterlet(name, namespace, clustername string) *opratorapiv1.Klusterlet {
|
||||
return &opratorapiv1.Klusterlet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Finalizers: []string{nucleusSpokeFinalizer},
|
||||
Finalizers: []string{klusterletFinalizer},
|
||||
},
|
||||
Spec: nucleusapiv1.SpokeCoreSpec{
|
||||
Spec: opratorapiv1.KlusterletSpec{
|
||||
RegistrationImagePullSpec: "testregistration",
|
||||
WorkImagePullSpec: "testwork",
|
||||
ClusterName: clustername,
|
||||
Namespace: namespace,
|
||||
ExternalServerURLs: []nucleusapiv1.ServerURL{},
|
||||
ExternalServerURLs: []opratorapiv1.ServerURL{},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -83,24 +83,24 @@ func newNamespace(name string) *corev1.Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
func newTestController(spokecore *nucleusapiv1.SpokeCore, objects ...runtime.Object) *testController {
|
||||
func newTestController(klusterlet *opratorapiv1.Klusterlet, objects ...runtime.Object) *testController {
|
||||
fakeKubeClient := fakekube.NewSimpleClientset(objects...)
|
||||
fakeNucleusClient := fakenucleusclient.NewSimpleClientset(spokecore)
|
||||
nucleusInformers := nucleusinformers.NewSharedInformerFactory(fakeNucleusClient, 5*time.Minute)
|
||||
fakeOperatorClient := fakeoperatorclient.NewSimpleClientset(klusterlet)
|
||||
operatorInformers := operatorinformers.NewSharedInformerFactory(fakeOperatorClient, 5*time.Minute)
|
||||
|
||||
hubController := &nucleusSpokeController{
|
||||
nucleusClient: fakeNucleusClient.NucleusV1().SpokeCores(),
|
||||
kubeClient: fakeKubeClient,
|
||||
nucleusLister: nucleusInformers.Nucleus().V1().SpokeCores().Lister(),
|
||||
hubController := &klusterletController{
|
||||
klusterletClient: fakeOperatorClient.OperatorV1().Klusterlets(),
|
||||
kubeClient: fakeKubeClient,
|
||||
klusterletLister: operatorInformers.Operator().V1().Klusterlets().Lister(),
|
||||
}
|
||||
|
||||
store := nucleusInformers.Nucleus().V1().SpokeCores().Informer().GetStore()
|
||||
store.Add(spokecore)
|
||||
store := operatorInformers.Operator().V1().Klusterlets().Informer().GetStore()
|
||||
store.Add(klusterlet)
|
||||
|
||||
return &testController{
|
||||
controller: hubController,
|
||||
kubeClient: fakeKubeClient,
|
||||
nucleusClient: fakeNucleusClient,
|
||||
controller: hubController,
|
||||
kubeClient: fakeKubeClient,
|
||||
operatorClient: fakeOperatorClient,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,21 +120,21 @@ func assertGet(t *testing.T, actual clienttesting.Action, group, version, resour
|
||||
}
|
||||
}
|
||||
|
||||
func namedCondition(name string, status metav1.ConditionStatus) nucleusapiv1.StatusCondition {
|
||||
return nucleusapiv1.StatusCondition{Type: name, Status: status}
|
||||
func namedCondition(name string, status metav1.ConditionStatus) opratorapiv1.StatusCondition {
|
||||
return opratorapiv1.StatusCondition{Type: name, Status: status}
|
||||
}
|
||||
|
||||
func assertOnlyConditions(t *testing.T, actual runtime.Object, expectedConditions ...nucleusapiv1.StatusCondition) {
|
||||
func assertOnlyConditions(t *testing.T, actual runtime.Object, expectedConditions ...opratorapiv1.StatusCondition) {
|
||||
t.Helper()
|
||||
|
||||
spokeCore := actual.(*nucleusapiv1.SpokeCore)
|
||||
actualConditions := spokeCore.Status.Conditions
|
||||
klusterlet := actual.(*opratorapiv1.Klusterlet)
|
||||
actualConditions := klusterlet.Status.Conditions
|
||||
if len(actualConditions) != len(expectedConditions) {
|
||||
t.Errorf("expected %v condition but got: %v", len(expectedConditions), spew.Sdump(actualConditions))
|
||||
}
|
||||
|
||||
for _, expectedCondition := range expectedConditions {
|
||||
actual := helpers.FindNucleusCondition(actualConditions, expectedCondition.Type)
|
||||
actual := helpers.FindOperatorCondition(actualConditions, expectedCondition.Type)
|
||||
if actual == nil {
|
||||
t.Errorf("missing %v in %v", spew.Sdump(expectedCondition), spew.Sdump(actual))
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func ensureNameNamespace(t *testing.T, actualName, actualNamespace, name, namesp
|
||||
}
|
||||
}
|
||||
|
||||
func ensureObject(t *testing.T, object runtime.Object, spokeCore *nucleusapiv1.SpokeCore) {
|
||||
func ensureObject(t *testing.T, object runtime.Object, klusterlet *opratorapiv1.Klusterlet) {
|
||||
access, err := meta.Accessor(object)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to access objectmeta: %v", err)
|
||||
@@ -165,15 +165,15 @@ func ensureObject(t *testing.T, object runtime.Object, spokeCore *nucleusapiv1.S
|
||||
if strings.Contains(access.GetName(), "registration") {
|
||||
ensureNameNamespace(
|
||||
t, access.GetName(), access.GetNamespace(),
|
||||
fmt.Sprintf("%s-registration-agent", spokeCore.Name), spokeCore.Spec.Namespace)
|
||||
if spokeCore.Spec.RegistrationImagePullSpec != o.Spec.Template.Spec.Containers[0].Image {
|
||||
fmt.Sprintf("%s-registration-agent", klusterlet.Name), klusterlet.Spec.Namespace)
|
||||
if klusterlet.Spec.RegistrationImagePullSpec != o.Spec.Template.Spec.Containers[0].Image {
|
||||
t.Errorf("Image does not match to the expected.")
|
||||
}
|
||||
} else if strings.Contains(access.GetName(), "work") {
|
||||
ensureNameNamespace(
|
||||
t, access.GetName(), access.GetNamespace(),
|
||||
fmt.Sprintf("%s-work-agent", spokeCore.Name), spokeCore.Spec.Namespace)
|
||||
if spokeCore.Spec.WorkImagePullSpec != o.Spec.Template.Spec.Containers[0].Image {
|
||||
fmt.Sprintf("%s-work-agent", klusterlet.Name), klusterlet.Spec.Namespace)
|
||||
if klusterlet.Spec.WorkImagePullSpec != o.Spec.Template.Spec.Containers[0].Image {
|
||||
t.Errorf("Image does not match to the expected.")
|
||||
}
|
||||
} else {
|
||||
@@ -184,7 +184,7 @@ func ensureObject(t *testing.T, object runtime.Object, spokeCore *nucleusapiv1.S
|
||||
|
||||
// TestSyncDeploy test deployment of spoke components
|
||||
func TestSyncDeploy(t *testing.T) {
|
||||
spokeCore := newSpokeCore("testspoke", "testns", "cluster1")
|
||||
spokeCore := newKlusterlet("testspoke", "testns", "cluster1")
|
||||
bootStrapSecret := newSecret(bootstrapHubKubeConfigSecret, "testns")
|
||||
hubKubeConfigSecret := newSecret(hubKubeConfigSecret, "testns")
|
||||
hubKubeConfigSecret.Data["kubeconfig"] = []byte("dummuykubeconnfig")
|
||||
@@ -214,28 +214,28 @@ func TestSyncDeploy(t *testing.T) {
|
||||
ensureObject(t, object, spokeCore)
|
||||
}
|
||||
|
||||
nucleusAction := controller.nucleusClient.Actions()
|
||||
if len(nucleusAction) != 4 {
|
||||
t.Errorf("Expect 4 actions in the sync loop, actual %#v", nucleusAction)
|
||||
operatorAction := controller.operatorClient.Actions()
|
||||
if len(operatorAction) != 4 {
|
||||
t.Errorf("Expect 4 actions in the sync loop, actual %#v", operatorAction)
|
||||
}
|
||||
|
||||
assertGet(t, nucleusAction[0], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[1], "update")
|
||||
assertOnlyConditions(t, nucleusAction[1].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(spokeCoreApplied, metav1.ConditionTrue))
|
||||
assertGet(t, nucleusAction[2], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[3], "update")
|
||||
assertOnlyConditions(t, nucleusAction[3].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(spokeCoreApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionFalse))
|
||||
assertGet(t, operatorAction[0], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[1], "update")
|
||||
assertOnlyConditions(t, operatorAction[1].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(klusterletApplied, metav1.ConditionTrue))
|
||||
assertGet(t, operatorAction[2], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[3], "update")
|
||||
assertOnlyConditions(t, operatorAction[3].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(klusterletApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionFalse))
|
||||
}
|
||||
|
||||
// TestSyncWithNoSecret test the scenario that bootstrap secret and hub config secret does not exist
|
||||
func TestSyncWithNoSecret(t *testing.T) {
|
||||
spokeCore := newSpokeCore("testspoke", "testns", "")
|
||||
klusterlet := newKlusterlet("testspoke", "testns", "")
|
||||
bootStrapSecret := newSecret(bootstrapHubKubeConfigSecret, "testns")
|
||||
hubSecret := newSecret(hubKubeConfigSecret, "testns")
|
||||
namespace := newNamespace("testns")
|
||||
controller := newTestController(spokeCore, namespace)
|
||||
controller := newTestController(klusterlet, namespace)
|
||||
syncContext := newFakeSyncContext(t, "testspoke")
|
||||
|
||||
// Return err since bootstrap secret does not exist
|
||||
@@ -243,17 +243,17 @@ func TestSyncWithNoSecret(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Errorf("Expected error when sync")
|
||||
}
|
||||
nucleusAction := controller.nucleusClient.Actions()
|
||||
if len(nucleusAction) != 2 {
|
||||
t.Errorf("Expect 2 actions in the sync loop, actual %#v", nucleusAction)
|
||||
operatorAction := controller.operatorClient.Actions()
|
||||
if len(operatorAction) != 2 {
|
||||
t.Errorf("Expect 2 actions in the sync loop, actual %#v", operatorAction)
|
||||
}
|
||||
|
||||
assertGet(t, nucleusAction[0], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[1], "update")
|
||||
assertOnlyConditions(t, nucleusAction[1].(clienttesting.UpdateActionImpl).Object, namedCondition(spokeCoreApplied, metav1.ConditionFalse))
|
||||
assertGet(t, operatorAction[0], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[1], "update")
|
||||
assertOnlyConditions(t, operatorAction[1].(clienttesting.UpdateActionImpl).Object, namedCondition(klusterletApplied, metav1.ConditionFalse))
|
||||
|
||||
// reset for round 2
|
||||
controller.nucleusClient.ClearActions()
|
||||
controller.operatorClient.ClearActions()
|
||||
// Add bootstrap secret and sync again
|
||||
controller.kubeClient.PrependReactor("get", "secrets", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if action.GetVerb() != "get" {
|
||||
@@ -272,22 +272,22 @@ func TestSyncWithNoSecret(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Errorf("Expected error when sync")
|
||||
}
|
||||
nucleusAction = controller.nucleusClient.Actions()
|
||||
if len(nucleusAction) != 4 {
|
||||
t.Errorf("Expect 4 actions in the sync loop, actual %#v", nucleusAction)
|
||||
operatorAction = controller.operatorClient.Actions()
|
||||
if len(operatorAction) != 4 {
|
||||
t.Errorf("Expect 4 actions in the sync loop, actual %#v", operatorAction)
|
||||
}
|
||||
|
||||
assertGet(t, nucleusAction[0], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[1], "update")
|
||||
assertOnlyConditions(t, nucleusAction[1].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(spokeCoreApplied, metav1.ConditionTrue))
|
||||
assertGet(t, nucleusAction[2], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[3], "update")
|
||||
assertOnlyConditions(t, nucleusAction[3].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(spokeCoreApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionTrue))
|
||||
assertGet(t, operatorAction[0], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[1], "update")
|
||||
assertOnlyConditions(t, operatorAction[1].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(klusterletApplied, metav1.ConditionTrue))
|
||||
assertGet(t, operatorAction[2], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[3], "update")
|
||||
assertOnlyConditions(t, operatorAction[3].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(klusterletApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionTrue))
|
||||
|
||||
// reset for round 3
|
||||
controller.nucleusClient.ClearActions()
|
||||
controller.operatorClient.ClearActions()
|
||||
// Add hub config secret and sync again
|
||||
hubSecret.Data["kubeconfig"] = []byte("dummykubeconfig")
|
||||
hubSecret.Data["cluster-name"] = []byte("cluster1")
|
||||
@@ -307,21 +307,21 @@ func TestSyncWithNoSecret(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when sync: %v", err)
|
||||
}
|
||||
nucleusAction = controller.nucleusClient.Actions()
|
||||
if len(nucleusAction) != 3 {
|
||||
t.Errorf("Expect 3 actions in the sync loop, actual %#v", nucleusAction)
|
||||
operatorAction = controller.operatorClient.Actions()
|
||||
if len(operatorAction) != 3 {
|
||||
t.Errorf("Expect 3 actions in the sync loop, actual %#v", operatorAction)
|
||||
}
|
||||
|
||||
assertGet(t, nucleusAction[0], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertGet(t, nucleusAction[1], "nucleus.open-cluster-management.io", "v1", "spokecores")
|
||||
assertAction(t, nucleusAction[2], "update")
|
||||
assertOnlyConditions(t, nucleusAction[2].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(spokeCoreApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionFalse))
|
||||
assertGet(t, operatorAction[0], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertGet(t, operatorAction[1], "operator.open-cluster-management.io", "v1", "klusterlets")
|
||||
assertAction(t, operatorAction[2], "update")
|
||||
assertOnlyConditions(t, operatorAction[2].(clienttesting.UpdateActionImpl).Object,
|
||||
namedCondition(klusterletApplied, metav1.ConditionTrue), namedCondition(spokeRegistrationDegraded, metav1.ConditionFalse))
|
||||
}
|
||||
|
||||
// TestSyncDelete test cleanup hub deploy
|
||||
func TestSyncDelete(t *testing.T) {
|
||||
spokeCore := newSpokeCore("testspoke", "testns", "")
|
||||
spokeCore := newKlusterlet("testspoke", "testns", "")
|
||||
now := metav1.Now()
|
||||
spokeCore.ObjectMeta.SetDeletionTimestamp(&now)
|
||||
namespace := newNamespace("testns")
|
||||
@@ -347,8 +347,8 @@ func TestSyncDelete(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetServersFromSpokeCore tests getServersFromSpokeCore func
|
||||
func TestGetServersFromSpokeCore(t *testing.T) {
|
||||
// TestGetServersFromKlusterlet tests getServersFromKlusterlet func
|
||||
func TestGetServersFromKlusterlet(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
servers []string
|
||||
@@ -378,12 +378,12 @@ func TestGetServersFromSpokeCore(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
spokeCore := newSpokeCore("testspoke", "testns", "")
|
||||
spokeCore := newKlusterlet("testspoke", "testns", "")
|
||||
for _, server := range c.servers {
|
||||
spokeCore.Spec.ExternalServerURLs = append(spokeCore.Spec.ExternalServerURLs,
|
||||
nucleusapiv1.ServerURL{URL: server})
|
||||
opratorapiv1.ServerURL{URL: server})
|
||||
}
|
||||
actual := getServersFromSpokeCore(spokeCore)
|
||||
actual := getServersFromKlusterlet(spokeCore)
|
||||
if actual != c.expected {
|
||||
t.Errorf("Expected to be same, actual %q, expected %q", actual, c.expected)
|
||||
}
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
|
||||
"github.com/openshift/library-go/pkg/controller/controllercmd"
|
||||
|
||||
nucleusclient "github.com/open-cluster-management/api/client/nucleus/clientset/versioned"
|
||||
nucleusinformer "github.com/open-cluster-management/api/client/nucleus/informers/externalversions"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/hub"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/spoke"
|
||||
operatorclient "github.com/open-cluster-management/api/client/operator/clientset/versioned"
|
||||
operatorinformer "github.com/open-cluster-management/api/client/operator/informers/externalversions"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/clustermanager"
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators/klusterlet"
|
||||
)
|
||||
|
||||
// RunNucleusHubOperator starts a new nucleus hub operator
|
||||
func RunNucleusHubOperator(ctx context.Context, controllerContext *controllercmd.ControllerContext) error {
|
||||
// RunClusterManagerOperator starts a new cluster manager operator
|
||||
func RunClusterManagerOperator(ctx context.Context, controllerContext *controllercmd.ControllerContext) error {
|
||||
// Build kubclient client and informer for spoke cluster
|
||||
kubeClient, err := kubernetes.NewForConfig(controllerContext.KubeConfig)
|
||||
if err != nil {
|
||||
@@ -32,50 +32,50 @@ func RunNucleusHubOperator(ctx context.Context, controllerContext *controllercmd
|
||||
return err
|
||||
}
|
||||
|
||||
// Build nucleus client and informer
|
||||
nucleusClient, err := nucleusclient.NewForConfig(controllerContext.KubeConfig)
|
||||
// Build operator client and informer
|
||||
operatorClient, err := operatorclient.NewForConfig(controllerContext.KubeConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nucleusInformer := nucleusinformer.NewSharedInformerFactory(nucleusClient, 5*time.Minute)
|
||||
operatorInformer := operatorinformer.NewSharedInformerFactory(operatorClient, 5*time.Minute)
|
||||
|
||||
hubcontroller := hub.NewNucleusHubController(
|
||||
clusterManagerController := clustermanager.NewClusterManagerController(
|
||||
kubeClient,
|
||||
apiExtensionClient,
|
||||
apiRegistrationClient.ApiregistrationV1(),
|
||||
nucleusClient.NucleusV1().HubCores(),
|
||||
nucleusInformer.Nucleus().V1().HubCores(),
|
||||
operatorClient.OperatorV1().ClusterManagers(),
|
||||
operatorInformer.Operator().V1().ClusterManagers(),
|
||||
controllerContext.EventRecorder)
|
||||
|
||||
go nucleusInformer.Start(ctx.Done())
|
||||
go hubcontroller.Run(ctx, 1)
|
||||
go operatorInformer.Start(ctx.Done())
|
||||
go clusterManagerController.Run(ctx, 1)
|
||||
<-ctx.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunNucleusSpokeOperator starts a new nucleus spoke operator
|
||||
func RunNucleusSpokeOperator(ctx context.Context, controllerContext *controllercmd.ControllerContext) error {
|
||||
// RunKlusterletOperator starts a new klusterlet operator
|
||||
func RunKlusterletOperator(ctx context.Context, controllerContext *controllercmd.ControllerContext) error {
|
||||
// Build kubclient client and informer for spoke cluster
|
||||
kubeClient, err := kubernetes.NewForConfig(controllerContext.KubeConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Build nucleus client and informer
|
||||
nucleusClient, err := nucleusclient.NewForConfig(controllerContext.KubeConfig)
|
||||
// Build operator client and informer
|
||||
operatorClient, err := operatorclient.NewForConfig(controllerContext.KubeConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nucleusInformer := nucleusinformer.NewSharedInformerFactory(nucleusClient, 5*time.Minute)
|
||||
operatorInformer := operatorinformer.NewSharedInformerFactory(operatorClient, 5*time.Minute)
|
||||
|
||||
spokeController := spoke.NewNucleusSpokeController(
|
||||
klusterletController := klusterlet.NewKlusterletController(
|
||||
kubeClient,
|
||||
nucleusClient.NucleusV1().SpokeCores(),
|
||||
nucleusInformer.Nucleus().V1().SpokeCores(),
|
||||
operatorClient.OperatorV1().Klusterlets(),
|
||||
operatorInformer.Operator().V1().Klusterlets(),
|
||||
controllerContext.EventRecorder)
|
||||
|
||||
go nucleusInformer.Start(ctx.Done())
|
||||
go spokeController.Run(ctx, 1)
|
||||
go operatorInformer.Start(ctx.Done())
|
||||
go klusterletController.Run(ctx, 1)
|
||||
<-ctx.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,632 +0,0 @@
|
||||
// Code generated by go-bindata.
|
||||
// sources:
|
||||
// manifests/spoke/spoke-registration-clusterrole.yaml
|
||||
// manifests/spoke/spoke-registration-clusterrolebinding.yaml
|
||||
// manifests/spoke/spoke-registration-deployment.yaml
|
||||
// manifests/spoke/spoke-registration-role.yaml
|
||||
// manifests/spoke/spoke-registration-rolebinding.yaml
|
||||
// manifests/spoke/spoke-registration-serviceaccount.yaml
|
||||
// manifests/spoke/spoke-work-clusterrole.yaml
|
||||
// manifests/spoke/spoke-work-clusterrolebinding-addition.yaml
|
||||
// manifests/spoke/spoke-work-clusterrolebinding.yaml
|
||||
// manifests/spoke/spoke-work-deployment.yaml
|
||||
// manifests/spoke/spoke-work-serviceaccount.yaml
|
||||
// DO NOT EDIT!
|
||||
|
||||
package bindata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type asset struct {
|
||||
bytes []byte
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
type bindataFileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationClusterroleYaml = []byte(`# Clusterrole for work agent in addition to admin clusterrole.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch nodes.
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes", "configmaps", "secrets"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources: ["subjectaccessreviews"]
|
||||
verbs: ["create"]
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationDeploymentYaml = []byte(`kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
labels:
|
||||
app: spoke-registration-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: spoke-registration-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: spoke-registration-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .SpokeCoreName }}-registration-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .RegistrationImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- "/registration"
|
||||
- "agent"
|
||||
- "--cluster-name={{ .ClusterName }}"
|
||||
- "--bootstrap-kubeconfig=/spoke/bootstrap/kubeconfig"
|
||||
- "--spoke-external-server-urls={{ .ExternalServerURL }}"
|
||||
volumeMounts:
|
||||
- name: bootstrap-secret
|
||||
mountPath: "/spoke/bootstrap"
|
||||
readOnly: true
|
||||
- name: hub-kubeconfig-secret
|
||||
mountPath: "/spoke/hub-kubeconfig"
|
||||
readOnly: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
volumes:
|
||||
- name: bootstrap-secret
|
||||
secret:
|
||||
secretName: {{ .BootStrapKubeConfigSecret }}
|
||||
- name: hub-kubeconfig-secret
|
||||
secret:
|
||||
secretName: {{ .HubKubeConfigSecret }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationRoleYaml = []byte(`# Role for registration agent.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "secrets"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
|
||||
- apiGroups: ["", "events.k8s.io"]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch", "update"]
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationRoleYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationRoleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationRoleYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationRoleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationRolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-registration-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationRolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationRolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationRolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationRolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeRegistrationServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-registration-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeRegistrationServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeRegistrationServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeRegistrationServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeRegistrationServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-registration-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeWorkClusterroleYaml = []byte(`# Clusterrole for work agent in addition to admin clusterrole.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
rules:
|
||||
# Allow agent to get/list/watch/create/delete crds.
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch", "create", "delete", "update"]
|
||||
# Allow agent to create/delete namespaces, get/list are contained in admin role already
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces"]
|
||||
verbs: ["create", "delete"]
|
||||
# Allow agent to manage role/rolebinding/clusterrole/clusterrolebinding
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterrolebindings", "rolebindings"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles", "roles"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "escalate", "bind"]
|
||||
# Allow agent to create sar
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources: ["subjectaccessreviews"]
|
||||
verbs: ["create"]
|
||||
# Allow agent to create events
|
||||
- apiGroups: ["", "events.k8s.io"]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch", "update"]
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterroleYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeWorkClusterroleYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterroleYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeWorkClusterroleYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-work-clusterrole.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeWorkClusterrolebindingAdditionYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent-addition
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterrolebindingAdditionYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeWorkClusterrolebindingAdditionYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterrolebindingAdditionYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeWorkClusterrolebindingAdditionYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-work-clusterrolebinding-addition.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeWorkClusterrolebindingYaml = []byte(`apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:open-cluster-management:{{ .SpokeCoreName }}-work-agent
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
# We deploy a controller that could work with permission lower than cluster-admin, the tradeoff is
|
||||
# responsivity because list/watch cannot be maintained over too many namespaces.
|
||||
name: admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterrolebindingYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeWorkClusterrolebindingYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeWorkClusterrolebindingYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeWorkClusterrolebindingYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-work-clusterrolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeWorkDeploymentYaml = []byte(`kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-work-agent
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
labels:
|
||||
app: spoke-work-agent
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: spoke-work-agent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: spoke-work-agent
|
||||
spec:
|
||||
serviceAccountName: {{ .SpokeCoreName }}-work-sa
|
||||
containers:
|
||||
- name: spoke-agent
|
||||
image: {{ .WorkImage }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- "/work"
|
||||
- "agent"
|
||||
- "--spoke-cluster-name={{ .ClusterName }}"
|
||||
- "--hub-kubeconfig=/spoke/hub-kubeconfig/kubeconfig"
|
||||
volumeMounts:
|
||||
- name: hub-kubeconfig-secret
|
||||
mountPath: "/spoke/hub-kubeconfig"
|
||||
readOnly: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
scheme: HTTPS
|
||||
port: 8443
|
||||
initialDelaySeconds: 2
|
||||
volumes:
|
||||
- name: hub-kubeconfig-secret
|
||||
secret:
|
||||
secretName: {{ .HubKubeConfigSecret }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeWorkDeploymentYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeWorkDeploymentYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeWorkDeploymentYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeWorkDeploymentYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-work-deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _manifestsSpokeSpokeWorkServiceaccountYaml = []byte(`apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .SpokeCoreName }}-work-sa
|
||||
namespace: {{ .SpokeCoreNamespace }}
|
||||
`)
|
||||
|
||||
func manifestsSpokeSpokeWorkServiceaccountYamlBytes() ([]byte, error) {
|
||||
return _manifestsSpokeSpokeWorkServiceaccountYaml, nil
|
||||
}
|
||||
|
||||
func manifestsSpokeSpokeWorkServiceaccountYaml() (*asset, error) {
|
||||
bytes, err := manifestsSpokeSpokeWorkServiceaccountYamlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "manifests/spoke/spoke-work-serviceaccount.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Asset loads and returns the asset for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func Asset(name string) ([]byte, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.bytes, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
|
||||
// MustAsset is like Asset but panics when Asset would return an error.
|
||||
// It simplifies safe initialization of global variables.
|
||||
func MustAsset(name string) []byte {
|
||||
a, err := Asset(name)
|
||||
if err != nil {
|
||||
panic("asset: Asset(" + name + "): " + err.Error())
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// AssetInfo loads and returns the asset info for the given name.
|
||||
// It returns an error if the asset could not be found or
|
||||
// could not be loaded.
|
||||
func AssetInfo(name string) (os.FileInfo, error) {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
if f, ok := _bindata[cannonicalName]; ok {
|
||||
a, err := f()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
|
||||
}
|
||||
return a.info, nil
|
||||
}
|
||||
return nil, fmt.Errorf("AssetInfo %s not found", name)
|
||||
}
|
||||
|
||||
// AssetNames returns the names of the assets.
|
||||
func AssetNames() []string {
|
||||
names := make([]string, 0, len(_bindata))
|
||||
for name := range _bindata {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"manifests/spoke/spoke-registration-clusterrole.yaml": manifestsSpokeSpokeRegistrationClusterroleYaml,
|
||||
"manifests/spoke/spoke-registration-clusterrolebinding.yaml": manifestsSpokeSpokeRegistrationClusterrolebindingYaml,
|
||||
"manifests/spoke/spoke-registration-deployment.yaml": manifestsSpokeSpokeRegistrationDeploymentYaml,
|
||||
"manifests/spoke/spoke-registration-role.yaml": manifestsSpokeSpokeRegistrationRoleYaml,
|
||||
"manifests/spoke/spoke-registration-rolebinding.yaml": manifestsSpokeSpokeRegistrationRolebindingYaml,
|
||||
"manifests/spoke/spoke-registration-serviceaccount.yaml": manifestsSpokeSpokeRegistrationServiceaccountYaml,
|
||||
"manifests/spoke/spoke-work-clusterrole.yaml": manifestsSpokeSpokeWorkClusterroleYaml,
|
||||
"manifests/spoke/spoke-work-clusterrolebinding-addition.yaml": manifestsSpokeSpokeWorkClusterrolebindingAdditionYaml,
|
||||
"manifests/spoke/spoke-work-clusterrolebinding.yaml": manifestsSpokeSpokeWorkClusterrolebindingYaml,
|
||||
"manifests/spoke/spoke-work-deployment.yaml": manifestsSpokeSpokeWorkDeploymentYaml,
|
||||
"manifests/spoke/spoke-work-serviceaccount.yaml": manifestsSpokeSpokeWorkServiceaccountYaml,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
// directory embedded in the file by go-bindata.
|
||||
// For example if you run go-bindata on data/... and data contains the
|
||||
// following hierarchy:
|
||||
// data/
|
||||
// foo.txt
|
||||
// img/
|
||||
// a.png
|
||||
// b.png
|
||||
// then AssetDir("data") would return []string{"foo.txt", "img"}
|
||||
// AssetDir("data/img") would return []string{"a.png", "b.png"}
|
||||
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
|
||||
// AssetDir("") will return []string{"data"}.
|
||||
func AssetDir(name string) ([]string, error) {
|
||||
node := _bintree
|
||||
if len(name) != 0 {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
pathList := strings.Split(cannonicalName, "/")
|
||||
for _, p := range pathList {
|
||||
node = node.Children[p]
|
||||
if node == nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.Func != nil {
|
||||
return nil, fmt.Errorf("Asset %s not found", name)
|
||||
}
|
||||
rv := make([]string, 0, len(node.Children))
|
||||
for childName := range node.Children {
|
||||
rv = append(rv, childName)
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
type bintree struct {
|
||||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"manifests": {nil, map[string]*bintree{
|
||||
"spoke": {nil, map[string]*bintree{
|
||||
"spoke-registration-clusterrole.yaml": {manifestsSpokeSpokeRegistrationClusterroleYaml, map[string]*bintree{}},
|
||||
"spoke-registration-clusterrolebinding.yaml": {manifestsSpokeSpokeRegistrationClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"spoke-registration-deployment.yaml": {manifestsSpokeSpokeRegistrationDeploymentYaml, map[string]*bintree{}},
|
||||
"spoke-registration-role.yaml": {manifestsSpokeSpokeRegistrationRoleYaml, map[string]*bintree{}},
|
||||
"spoke-registration-rolebinding.yaml": {manifestsSpokeSpokeRegistrationRolebindingYaml, map[string]*bintree{}},
|
||||
"spoke-registration-serviceaccount.yaml": {manifestsSpokeSpokeRegistrationServiceaccountYaml, map[string]*bintree{}},
|
||||
"spoke-work-clusterrole.yaml": {manifestsSpokeSpokeWorkClusterroleYaml, map[string]*bintree{}},
|
||||
"spoke-work-clusterrolebinding-addition.yaml": {manifestsSpokeSpokeWorkClusterrolebindingAdditionYaml, map[string]*bintree{}},
|
||||
"spoke-work-clusterrolebinding.yaml": {manifestsSpokeSpokeWorkClusterrolebindingYaml, map[string]*bintree{}},
|
||||
"spoke-work-deployment.yaml": {manifestsSpokeSpokeWorkDeploymentYaml, map[string]*bintree{}},
|
||||
"spoke-work-serviceaccount.yaml": {manifestsSpokeSpokeWorkServiceaccountYaml, map[string]*bintree{}},
|
||||
}},
|
||||
}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory
|
||||
func RestoreAsset(dir, name string) error {
|
||||
data, err := Asset(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := AssetInfo(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreAssets restores an asset under the given directory recursively
|
||||
func RestoreAssets(dir, name string) error {
|
||||
children, err := AssetDir(name)
|
||||
// File
|
||||
if err != nil {
|
||||
return RestoreAsset(dir, name)
|
||||
}
|
||||
// Dir
|
||||
for _, child := range children {
|
||||
err = RestoreAssets(dir, filepath.Join(name, child))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package integration provides integration tests for open-cluster-management nucleus, the test cases include
|
||||
// - TODO deploy/update/remvoe the hub core
|
||||
// - TODO deploy/update/remvoe the cluster manager
|
||||
// - TODO deploy/update/remvoe the spoke agents
|
||||
package integration
|
||||
|
||||
@@ -15,11 +15,11 @@ import (
|
||||
"github.com/open-cluster-management/nucleus/pkg/operators"
|
||||
"github.com/open-cluster-management/nucleus/test/integration/util"
|
||||
|
||||
nucleusapiv1 "github.com/open-cluster-management/api/nucleus/v1"
|
||||
operatorapiv1 "github.com/open-cluster-management/api/operator/v1"
|
||||
)
|
||||
|
||||
func startHubOperator(ctx context.Context) {
|
||||
err := operators.RunNucleusHubOperator(ctx, &controllercmd.ControllerContext{
|
||||
err := operators.RunClusterManagerOperator(ctx, &controllercmd.ControllerContext{
|
||||
KubeConfig: restConfig,
|
||||
EventRecorder: util.NewIntegrationTestEventRecorder("integration"),
|
||||
})
|
||||
@@ -29,7 +29,7 @@ func startHubOperator(ctx context.Context) {
|
||||
var _ = ginkgo.Describe("HubCore", func() {
|
||||
var cancel context.CancelFunc
|
||||
var err error
|
||||
var hubCoreName string
|
||||
var clusterManagerName string
|
||||
var hubRegistrationClusterRole string
|
||||
var hubWebhookClusterRole string
|
||||
var hubRegistrationSA string
|
||||
@@ -46,15 +46,15 @@ var _ = ginkgo.Describe("HubCore", func() {
|
||||
})
|
||||
|
||||
ginkgo.JustBeforeEach(func() {
|
||||
hubcore := &nucleusapiv1.HubCore{
|
||||
clusterManager := &operatorapiv1.ClusterManager{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: hubCoreName,
|
||||
Name: clusterManagerName,
|
||||
},
|
||||
Spec: nucleusapiv1.HubCoreSpec{
|
||||
Spec: operatorapiv1.ClusterManagerSpec{
|
||||
RegistrationImagePullSpec: "quay.io/open-cluster-management/registration",
|
||||
},
|
||||
}
|
||||
hubcore, err = nucleusClient.NucleusV1().HubCores().Create(context.Background(), hubcore, metav1.CreateOptions{})
|
||||
_, err = operatorClient.OperatorV1().ClusterManagers().Create(context.Background(), clusterManager, metav1.CreateOptions{})
|
||||
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
@@ -66,13 +66,13 @@ var _ = ginkgo.Describe("HubCore", func() {
|
||||
|
||||
ginkgo.Context("Deploy and clean hub component", func() {
|
||||
ginkgo.BeforeEach(func() {
|
||||
hubCoreName = "hub"
|
||||
hubRegistrationClusterRole = fmt.Sprintf("system:open-cluster-management:%s-registration-controller", hubCoreName)
|
||||
hubWebhookClusterRole = fmt.Sprintf("system:open-cluster-management:%s-registration-webhook", hubCoreName)
|
||||
hubRegistrationSA = fmt.Sprintf("%s-registration-controller-sa", hubCoreName)
|
||||
hubWebhookSA = fmt.Sprintf("%s-registration-webhook-sa", hubCoreName)
|
||||
hubRegistrationDeployment = fmt.Sprintf("%s-registration-controller", hubCoreName)
|
||||
hubWebhookDeployment = fmt.Sprintf("%s-registration-webhook", hubCoreName)
|
||||
clusterManagerName = "hub"
|
||||
hubRegistrationClusterRole = fmt.Sprintf("system:open-cluster-management:%s-registration-controller", clusterManagerName)
|
||||
hubWebhookClusterRole = fmt.Sprintf("system:open-cluster-management:%s-registration-webhook", clusterManagerName)
|
||||
hubRegistrationSA = fmt.Sprintf("%s-registration-controller-sa", clusterManagerName)
|
||||
hubWebhookSA = fmt.Sprintf("%s-registration-webhook-sa", clusterManagerName)
|
||||
hubRegistrationDeployment = fmt.Sprintf("%s-registration-controller", clusterManagerName)
|
||||
hubWebhookDeployment = fmt.Sprintf("%s-registration-webhook", clusterManagerName)
|
||||
webhookSecret = "webhook-serving-cert"
|
||||
validtingWebhook = "spokeclustervalidators.admission.cluster.open-cluster-management.io"
|
||||
})
|
||||
@@ -168,7 +168,7 @@ var _ = ginkgo.Describe("HubCore", func() {
|
||||
return true
|
||||
}, eventuallyTimeout, eventuallyInterval).Should(gomega.BeTrue())
|
||||
|
||||
err := nucleusClient.NucleusV1().HubCores().Delete(context.Background(), hubCoreName, metav1.DeleteOptions{})
|
||||
err := operatorClient.OperatorV1().ClusterManagers().Delete(context.Background(), clusterManagerName, metav1.DeleteOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
// Check namespace deletion
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
nucleusclient "github.com/open-cluster-management/api/client/nucleus/clientset/versioned"
|
||||
operatorclient "github.com/open-cluster-management/api/client/operator/clientset/versioned"
|
||||
)
|
||||
|
||||
func TestIntegration(t *testing.T) {
|
||||
@@ -36,7 +36,7 @@ var kubeClient kubernetes.Interface
|
||||
|
||||
var restConfig *rest.Config
|
||||
|
||||
var nucleusClient nucleusclient.Interface
|
||||
var operatorClient operatorclient.Interface
|
||||
|
||||
var _ = ginkgo.BeforeSuite(func(done ginkgo.Done) {
|
||||
logf.SetLogger(zap.LoggerTo(ginkgo.GinkgoWriter, true))
|
||||
@@ -49,7 +49,7 @@ var _ = ginkgo.BeforeSuite(func(done ginkgo.Done) {
|
||||
testEnv = &envtest.Environment{
|
||||
ErrorIfCRDPathMissing: true,
|
||||
CRDDirectoryPaths: []string{
|
||||
filepath.Join(".", "vendor", "github.com", "open-cluster-management", "api", "nucleus", "v1"),
|
||||
filepath.Join(".", "vendor", "github.com", "open-cluster-management", "api", "operator", "v1"),
|
||||
},
|
||||
}
|
||||
cfg, err := testEnv.Start()
|
||||
@@ -60,7 +60,7 @@ var _ = ginkgo.BeforeSuite(func(done ginkgo.Done) {
|
||||
kubeClient, err = kubernetes.NewForConfig(cfg)
|
||||
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||
gomega.Expect(kubeClient).ToNot(gomega.BeNil())
|
||||
nucleusClient, err = nucleusclient.NewForConfig(cfg)
|
||||
operatorClient, err = operatorclient.NewForConfig(cfg)
|
||||
gomega.Expect(err).ToNot(gomega.HaveOccurred())
|
||||
gomega.Expect(kubeClient).ToNot(gomega.BeNil())
|
||||
|
||||
|
||||
16
vendor/github.com/go-bindata/go-bindata/.gitignore
generated
vendored
Normal file
16
vendor/github.com/go-bindata/go-bindata/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Goland project files
|
||||
.idea/
|
||||
*.iml
|
||||
@@ -1,5 +1,7 @@
|
||||
## bindata
|
||||
|
||||
[](https://goreportcard.com/report/github.com/go-bindata/bindata)
|
||||
|
||||
This package converts any file into managable Go source code. Useful for
|
||||
embedding binary data into a go program. The file data is optionally gzip
|
||||
compressed before being converted to a raw byte slice.
|
||||
@@ -13,7 +15,7 @@ output being generated.
|
||||
|
||||
To install the library and command line program, use the following:
|
||||
|
||||
go get -u github.com/jteeuwen/go-bindata/...
|
||||
go get -u github.com/go-bindata/go-bindata/...
|
||||
|
||||
|
||||
### Usage
|
||||
@@ -182,8 +184,16 @@ format is specified at build time with the appropriate tags.
|
||||
The tags are appended to a `// +build` line in the beginning of the output file
|
||||
and must follow the build tags syntax specified by the go tool.
|
||||
|
||||
### Related projects
|
||||
### Serve assets with `net/http`
|
||||
|
||||
[go-bindata-assetfs](https://github.com/elazarl/go-bindata-assetfs#readme) -
|
||||
implements `http.FileSystem` interface. Allows you to serve assets with `net/http`.
|
||||
With the `-fs` flag, `go-bindata` will add an `AssetFile()` method returning an `http.FileSystem` interface:
|
||||
|
||||
$ go-bindata -fs -prefix "static/" static/
|
||||
|
||||
Use `-prefix` flag to strip first level dir, then in your `net/http` router, you can use `AssetFile()` with `http.FileServer()` like:
|
||||
|
||||
```go
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/static", http.FileServer(AssetFile()))
|
||||
http.ListenAndServe(":8080", mux)
|
||||
```
|
||||
1
vendor/github.com/go-bindata/go-bindata/_config.yml
generated
vendored
Normal file
1
vendor/github.com/go-bindata/go-bindata/_config.yml
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-cayman
|
||||
@@ -106,6 +106,10 @@ type Config struct {
|
||||
// the file data when called. Defaults to false.
|
||||
NoCompress bool
|
||||
|
||||
// HttpFileSystem means whether generate return http.FileSystem interface
|
||||
// instance's function.When true,will generate relate code.
|
||||
HttpFileSystem bool
|
||||
|
||||
// Perform a debug build. This generates an asset file, which
|
||||
// loads the asset contents directly from disk at their original
|
||||
// location, instead of embedding the contents in the code.
|
||||
@@ -148,6 +152,7 @@ func NewConfig() *Config {
|
||||
c.Package = "main"
|
||||
c.NoMemCopy = false
|
||||
c.NoCompress = false
|
||||
c.HttpFileSystem = false
|
||||
c.Debug = false
|
||||
c.Output = "./bindata.go"
|
||||
c.Ignore = make([]*regexp.Regexp, 0)
|
||||
@@ -50,7 +50,7 @@ func Translate(c *Config) error {
|
||||
defer bfd.Flush()
|
||||
|
||||
// Write the header. This makes e.g. Github ignore diffs in generated files.
|
||||
if _, err = fmt.Fprint(bfd, "// Code generated by go-bindata.\n"); err != nil {
|
||||
if _, err = fmt.Fprintf(bfd, "// Code generated for package %s by go-bindata DO NOT EDIT. (@generated)\n", c.Package); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = fmt.Fprint(bfd, "// sources:\n"); err != nil {
|
||||
@@ -68,9 +68,9 @@ func Translate(c *Config) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err = fmt.Fprint(bfd, "// DO NOT EDIT!\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
//if _, err = fmt.Fprint(bfd, "// DO NOT EDIT!\n\n"); err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
// Write build tags, if applicable.
|
||||
if len(c.Tags) > 0 {
|
||||
@@ -109,7 +109,7 @@ func Translate(c *Config) error {
|
||||
return writeRestore(bfd)
|
||||
}
|
||||
|
||||
// Implement sort.Interface for []os.FileInfo based on Name()
|
||||
// ByName implements sort.Interface for []os.FileInfo based on Name()
|
||||
type ByName []os.FileInfo
|
||||
|
||||
func (v ByName) Len() int { return len(v) }
|
||||
@@ -11,7 +11,12 @@ import (
|
||||
|
||||
// writeDebug writes the debug code file.
|
||||
func writeDebug(w io.Writer, c *Config, toc []Asset) error {
|
||||
err := writeDebugHeader(w)
|
||||
err := writeDebugHeader(w, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeAssetFS(w, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -28,13 +33,29 @@ func writeDebug(w io.Writer, c *Config, toc []Asset) error {
|
||||
|
||||
// writeDebugHeader writes output file headers.
|
||||
// This targets debug builds.
|
||||
func writeDebugHeader(w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, `import (
|
||||
func writeDebugHeader(w io.Writer, c *Config) error {
|
||||
var header string
|
||||
|
||||
if c.HttpFileSystem {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"`
|
||||
} else {
|
||||
header = `import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"`
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `%s
|
||||
)
|
||||
|
||||
// bindataRead reads the given file from disk. It returns an error on failure.
|
||||
@@ -51,7 +72,7 @@ type asset struct {
|
||||
info os.FileInfo
|
||||
}
|
||||
|
||||
`)
|
||||
`, header)
|
||||
return err
|
||||
}
|
||||
|
||||
102
vendor/github.com/go-bindata/go-bindata/file.go
generated
vendored
Normal file
102
vendor/github.com/go-bindata/go-bindata/file.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package bindata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func writeAssetFS(w io.Writer, c *Config) error {
|
||||
if !c.HttpFileSystem {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `
|
||||
type assetFile struct {
|
||||
*bytes.Reader
|
||||
name string
|
||||
childInfos []os.FileInfo
|
||||
childInfoOffset int
|
||||
}
|
||||
|
||||
type assetOperator struct{}
|
||||
|
||||
// Open implement http.FileSystem interface
|
||||
func (f *assetOperator) Open(name string) (http.File, error) {
|
||||
var err error
|
||||
if len(name) > 0 && name[0] == '/' {
|
||||
name = name[1:]
|
||||
}
|
||||
content, err := Asset(name)
|
||||
if err == nil {
|
||||
return &assetFile{name: name, Reader: bytes.NewReader(content)}, nil
|
||||
}
|
||||
children, err := AssetDir(name)
|
||||
if err == nil {
|
||||
childInfos := make([]os.FileInfo, 0, len(children))
|
||||
for _, child := range children {
|
||||
childPath := filepath.Join(name, child)
|
||||
info, errInfo := AssetInfo(filepath.Join(name, child))
|
||||
if errInfo == nil {
|
||||
childInfos = append(childInfos, info)
|
||||
} else {
|
||||
childInfos = append(childInfos, newDirFileInfo(childPath))
|
||||
}
|
||||
}
|
||||
return &assetFile{name: name, childInfos: childInfos}, nil
|
||||
} else {
|
||||
// If the error is not found, return an error that will
|
||||
// result in a 404 error. Otherwise the server returns
|
||||
// a 500 error for files not found.
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Close no need do anything
|
||||
func (f *assetFile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Readdir read dir's children file info
|
||||
func (f *assetFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||
if len(f.childInfos) == 0 {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
if count <= 0 {
|
||||
return f.childInfos, nil
|
||||
}
|
||||
if f.childInfoOffset+count > len(f.childInfos) {
|
||||
count = len(f.childInfos) - f.childInfoOffset
|
||||
}
|
||||
offset := f.childInfoOffset
|
||||
f.childInfoOffset += count
|
||||
return f.childInfos[offset : offset+count], nil
|
||||
}
|
||||
|
||||
// Stat read file info from asset item
|
||||
func (f *assetFile) Stat() (os.FileInfo, error) {
|
||||
if len(f.childInfos) != 0 {
|
||||
return newDirFileInfo(f.name), nil
|
||||
}
|
||||
return AssetInfo(f.name)
|
||||
}
|
||||
|
||||
// newDirFileInfo return default dir file info
|
||||
func newDirFileInfo(name string) os.FileInfo {
|
||||
return &bindataFileInfo{
|
||||
name: name,
|
||||
size: 0,
|
||||
mode: os.FileMode(2147484068), // equal os.FileMode(0644)|os.ModeDir
|
||||
modTime: time.Time{}}
|
||||
}
|
||||
|
||||
// AssetFile return a http.FileSystem instance that data backend by asset
|
||||
func AssetFile() http.FileSystem {
|
||||
return &assetOperator{}
|
||||
}
|
||||
|
||||
`)
|
||||
return err
|
||||
}
|
||||
1
vendor/github.com/go-bindata/go-bindata/go-bindata/.gitignore
generated
vendored
Normal file
1
vendor/github.com/go-bindata/go-bindata/go-bindata/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
go-bindata
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jteeuwen/go-bindata"
|
||||
"github.com/go-bindata/go-bindata"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -48,6 +48,7 @@ func parseArgs() *bindata.Config {
|
||||
flag.BoolVar(&c.NoMemCopy, "nomemcopy", c.NoMemCopy, "Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.")
|
||||
flag.BoolVar(&c.NoCompress, "nocompress", c.NoCompress, "Assets will *not* be GZIP compressed when this flag is specified.")
|
||||
flag.BoolVar(&c.NoMetadata, "nometadata", c.NoMetadata, "Assets will not preserve size, mode, and modtime info.")
|
||||
flag.BoolVar(&c.HttpFileSystem, "fs", c.HttpFileSystem, "Whether generate instance http.FileSystem interface code.")
|
||||
flag.UintVar(&c.Mode, "mode", c.Mode, "Optional file mode override for all files.")
|
||||
flag.Int64Var(&c.ModTime, "modtime", c.ModTime, "Optional modification unix timestamp override for all files.")
|
||||
flag.StringVar(&c.Output, "o", c.Output, "Optional name of the output file to be generated.")
|
||||
@@ -23,7 +23,7 @@ var AppVersionRev string
|
||||
|
||||
func Version() string {
|
||||
if len(AppVersionRev) == 0 {
|
||||
AppVersionRev = "0"
|
||||
AppVersionRev = "2"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s %d.%d.%s (Go runtime %s).\nCopyright (c) 2010-2013, Jim Teeuwen.",
|
||||
@@ -21,6 +21,11 @@ func writeRelease(w io.Writer, c *Config, toc []Asset) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeAssetFS(w, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range toc {
|
||||
err = writeReleaseAsset(w, c, &toc[i])
|
||||
if err != nil {
|
||||
@@ -37,15 +42,15 @@ func writeReleaseHeader(w io.Writer, c *Config) error {
|
||||
var err error
|
||||
if c.NoCompress {
|
||||
if c.NoMemCopy {
|
||||
err = header_uncompressed_nomemcopy(w)
|
||||
err = header_uncompressed_nomemcopy(w, c)
|
||||
} else {
|
||||
err = header_uncompressed_memcopy(w)
|
||||
err = header_uncompressed_memcopy(w, c)
|
||||
}
|
||||
} else {
|
||||
if c.NoMemCopy {
|
||||
err = header_compressed_nomemcopy(w)
|
||||
err = header_compressed_nomemcopy(w, c)
|
||||
} else {
|
||||
err = header_compressed_memcopy(w)
|
||||
err = header_compressed_memcopy(w, c)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
@@ -97,8 +102,23 @@ func sanitize(b []byte) []byte {
|
||||
return bytes.Replace(b, []byte("\xEF\xBB\xBF"), []byte("`+\"\\xEF\\xBB\\xBF\"+`"), -1)
|
||||
}
|
||||
|
||||
func header_compressed_nomemcopy(w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, `import (
|
||||
func header_compressed_nomemcopy(w io.Writer, c *Config) error {
|
||||
var header string
|
||||
|
||||
if c.HttpFileSystem {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"`
|
||||
} else {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
@@ -107,7 +127,10 @@ func header_compressed_nomemcopy(w io.Writer) error {
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
"time"`
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `%s
|
||||
)
|
||||
|
||||
func bindataRead(data, name string) ([]byte, error) {
|
||||
@@ -130,12 +153,27 @@ func bindataRead(data, name string) ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
`)
|
||||
`, header)
|
||||
return err
|
||||
}
|
||||
|
||||
func header_compressed_memcopy(w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, `import (
|
||||
func header_compressed_memcopy(w io.Writer, c *Config) error {
|
||||
var header string
|
||||
|
||||
if c.HttpFileSystem {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"`
|
||||
} else {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
@@ -144,7 +182,10 @@ func header_compressed_memcopy(w io.Writer) error {
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
"time"`
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `%s
|
||||
)
|
||||
|
||||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
@@ -167,12 +208,27 @@ func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
`)
|
||||
`, header)
|
||||
return err
|
||||
}
|
||||
|
||||
func header_uncompressed_nomemcopy(w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, `import (
|
||||
func header_uncompressed_nomemcopy(w io.Writer, c *Config) error {
|
||||
var header string
|
||||
|
||||
if c.HttpFileSystem {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"`
|
||||
} else {
|
||||
header = `import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -180,7 +236,10 @@ func header_uncompressed_nomemcopy(w io.Writer) error {
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
"unsafe"`
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `%s
|
||||
)
|
||||
|
||||
func bindataRead(data, name string) ([]byte, error) {
|
||||
@@ -194,20 +253,36 @@ func bindataRead(data, name string) ([]byte, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
`)
|
||||
`, header)
|
||||
return err
|
||||
}
|
||||
|
||||
func header_uncompressed_memcopy(w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, `import (
|
||||
func header_uncompressed_memcopy(w io.Writer, c *Config) error {
|
||||
var header string
|
||||
|
||||
if c.HttpFileSystem {
|
||||
header = `import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"`
|
||||
} else {
|
||||
header = `import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
"time"`
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(w, `%s
|
||||
)
|
||||
`)
|
||||
`, header)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -224,21 +299,32 @@ type bindataFileInfo struct {
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
// Name return file name
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
|
||||
// Size return file size
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
|
||||
// Mode return file mode
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
|
||||
// Mode return file modify time
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
|
||||
// IsDir return file whether a directory
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
return fi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
// Sys return file is sys mode
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
@@ -57,7 +57,6 @@ func _filePath(dir, name string) string {
|
||||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
|
||||
`)
|
||||
return err
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user