From 6692944e9a6cceb93a049fbf1535732b52fb9100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Thu, 25 Nov 2021 11:56:56 +0100 Subject: [PATCH] Update and rework OLM bundle creation (#898) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update operator-sdk Signed-off-by: Christoph Stäbler * Fix operator rbac Signed-off-by: Christoph Stäbler * Rework bundle generation * Added a base clusterserviceversion with default values for the generated csv. * Moved the nncp and nmstate CRs into the examples directory so they will be included in the CSV. Signed-off-by: Christoph Stäbler --- Makefile | 7 +- PROJECT | 2 +- bundle.Dockerfile | 14 +- ...mstate-operator.clusterserviceversion.yaml | 163 +++++++--- .../nmstate-operator_v1_serviceaccount.yaml | 7 - bundle/manifests/nmstate.io_nmstates.yaml | 257 ++++++++++++++- ...io_nodenetworkconfigurationenactments.yaml | 160 ++++++++++ ...e.io_nodenetworkconfigurationpolicies.yaml | 293 ++++++++++++++++++ .../nmstate.io_nodenetworkstates.yaml | 157 ++++++++++ bundle/metadata/annotations.yaml | 15 +- bundle/tests/scorecard/.gitkeep | 0 cluster/sync.sh | 2 +- controllers/operator/nmstate_controller.go | 2 +- ...mstate-operator.clusterserviceversion.yaml | 50 +++ ..._nodenetworkconfigurationenactment_cr.yaml | 32 -- ...mstate.io_v1beta1_nodenetworkstate_cr.yaml | 188 ----------- .../nmstate.io_v1_nmstate_cr.yaml | 0 ..._v1_nodenetworkconfigurationpolicy_cr.yaml | 0 deploy/operator/role.yaml | 1 - hack/render-manifests.go | 5 + 20 files changed, 1062 insertions(+), 293 deletions(-) delete mode 100644 bundle/manifests/nmstate-operator_v1_serviceaccount.yaml create mode 100644 bundle/manifests/nmstate.io_nodenetworkconfigurationenactments.yaml create mode 100644 bundle/manifests/nmstate.io_nodenetworkconfigurationpolicies.yaml create mode 100644 bundle/manifests/nmstate.io_nodenetworkstates.yaml create mode 100644 bundle/tests/scorecard/.gitkeep create mode 100644 deploy/bases/kubernetes-nmstate-operator.clusterserviceversion.yaml delete mode 100644 deploy/crds/nmstate.io_v1beta1_nodenetworkconfigurationenactment_cr.yaml delete mode 100644 deploy/crds/nmstate.io_v1beta1_nodenetworkstate_cr.yaml rename deploy/{crds => examples}/nmstate.io_v1_nmstate_cr.yaml (100%) rename deploy/{crds => examples}/nmstate.io_v1_nodenetworkconfigurationpolicy_cr.yaml (100%) diff --git a/Makefile b/Makefile index 4186958fa0..f43febe9e1 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ OPERATOR_SDK ?= $(GOBIN)/operator-sdk GINKGO = go run github.com/onsi/ginkgo/ginkgo CONTROLLER_GEN = go run sigs.k8s.io/controller-tools/cmd/controller-gen -OPM = go run github.com/operator-framework/operator-registry/cmd/opm +OPM = go run -tags=json1 github.com/operator-framework/operator-registry/cmd/opm LOCAL_REGISTRY ?= registry:5000 @@ -122,7 +122,7 @@ lint: $(GO) hack/lint.sh $(OPERATOR_SDK): - curl https://github.com/operator-framework/operator-sdk/releases/download/v1.7.1/operator-sdk_linux_amd64 -o $(OPERATOR_SDK) + curl https://github.com/operator-framework/operator-sdk/releases/download/v1.15.0/operator-sdk_linux_amd64 -o $(OPERATOR_SDK) gen-k8s: $(GO) $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." @@ -206,6 +206,7 @@ vendor: $(GO) # Generate bundle manifests and metadata, then validate generated files. bundle: $(OPERATOR_SDK) gen-crds manifests + cp -r deploy/bases $(MANIFESTS_DIR)/bases $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) --deploy-dir $(MANIFESTS_DIR) --crds-dir deploy/crds $(OPERATOR_SDK) bundle validate ./bundle @@ -215,7 +216,7 @@ bundle-build: # Build the index index-build: $(GO) bundle-build - $(OPM) index add --bundles $(BUNDLE_IMG) --tag $(INDEX_IMG) + $(OPM) index add --bundles $(BUNDLE_IMG) --tag $(INDEX_IMG) --build-tool $(IMAGE_BUILDER) bundle-push: bundle-build $(IMAGE_BUILDER) push $(BUNDLE_IMG) diff --git a/PROJECT b/PROJECT index 305246e8a9..e61ac7f3d5 100644 --- a/PROJECT +++ b/PROJECT @@ -1,7 +1,7 @@ domain: nmstate.io layout: - go.kubebuilder.io/v3 -projectName: kubernetes-nmstate +projectName: kubernetes-nmstate-operator repo: github.com/nmstate/kubernetes-nmstate resources: - api: diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 4077c82c25..1725a90216 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -1,14 +1,20 @@ FROM scratch +# Core bundle labels. LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ -LABEL operators.operatorframework.io.bundle.package.v1=kubernetes-nmstate +LABEL operators.operatorframework.io.bundle.package.v1=kubernetes-nmstate-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-unknown +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.13.0+git LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v2 -LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 + +# Labels for testing. LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 +LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ + +# Copy files to locations specified by labels. COPY bundle/manifests /manifests/ COPY bundle/metadata /metadata/ +COPY bundle/tests/scorecard /tests/scorecard/ diff --git a/bundle/manifests/kubernetes-nmstate-operator.clusterserviceversion.yaml b/bundle/manifests/kubernetes-nmstate-operator.clusterserviceversion.yaml index 07e3b7fc07..976fdd0b8a 100644 --- a/bundle/manifests/kubernetes-nmstate-operator.clusterserviceversion.yaml +++ b/bundle/manifests/kubernetes-nmstate-operator.clusterserviceversion.yaml @@ -3,28 +3,76 @@ kind: ClusterServiceVersion metadata: annotations: alm-examples: |- - [{ - "apiVersion": "nmstate.io/v1", - "kind": "NMState", - "metadata": { - "name": "nmstate" + [ + { + "apiVersion": "nmstate.io/v1", + "kind": "NMState", + "metadata": { + "name": "nmstate" + } }, - "spec": { - "nodeSelector": "" + { + "apiVersion": "nmstate.io/v1", + "kind": "NodeNetworkConfigurationPolicy", + "metadata": { + "name": "example-nodenetworkconfigurationpolicy" + }, + "spec": { + "desiredState": { + "interfaces": [ + { + "bridge": { + "options": { + "stp": { + "enabled": false + } + }, + "port": [ + { + "name": "eth1" + } + ] + }, + "name": "br0", + "state": "up", + "type": "linux-bridge" + }, + { + "bridge": { + "options": { + "stp": { + "enabled": false + } + }, + "port": [ + { + "name": "eth2" + } + ] + }, + "name": "br1", + "state": "up", + "type": "linux-bridge" + } + ] + } + } } - }] + ] capabilities: Basic Install - operators.operatorframework.io/builder: operator-sdk-v1.0.0 - operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 categories: Networking + certified: "false" + containerImage: quay.io/nmstate/kubernetes-nmstate-operator:latest + createdAt: "2021-11-24 16:05:00" description: | Kubernetes NMState is a declaritive means of configuring NetworkManager. - containerImage: quay.io/nmstate/kubernetes-nmstate-operator:latest - createdAt: 2020-011-12 17:13:03 - support: nmstate.io - repository: https://github.com/nmstate/kubernetes-nmstate operatorframework.io/suggested-namespace: nmstate - certified: "false" + operators.operatorframework.io/builder: operator-sdk-v1.13.0+git + operators.operatorframework.io/internal-objects: '["nodenetworkconfigurationenactments.nmstate.io", + "nodenetworkstates.nmstate.io"]' + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + repository: https://github.com/nmstate/kubernetes-nmstate + support: nmstate.io name: kubernetes-nmstate-operator.v0.0.1 namespace: placeholder spec: @@ -34,37 +82,51 @@ spec: - kind: NMState name: nmstates.nmstate.io version: v1 - description: Represents an NMState deployment. - displayName: NMState - description: A Kubernetes Operator to install Kubernetes NMState - displayName: Kubernetes NMState Operator + - kind: NMState + name: nmstates.nmstate.io + version: v1beta1 + - kind: NodeNetworkConfigurationEnactment + name: nodenetworkconfigurationenactments.nmstate.io + version: v1alpha1 + - kind: NodeNetworkConfigurationEnactment + name: nodenetworkconfigurationenactments.nmstate.io + version: v1beta1 + - kind: NodeNetworkConfigurationPolicy + name: nodenetworkconfigurationpolicies.nmstate.io + version: v1 + - kind: NodeNetworkConfigurationPolicy + name: nodenetworkconfigurationpolicies.nmstate.io + version: v1alpha1 + - kind: NodeNetworkConfigurationPolicy + name: nodenetworkconfigurationpolicies.nmstate.io + version: v1beta1 + - kind: NodeNetworkState + name: nodenetworkstates.nmstate.io + version: v1alpha1 + - kind: NodeNetworkState + name: nodenetworkstates.nmstate.io + version: v1beta1 + description: Kubernetes Nmstate description. + displayName: Kubernetes Nmstate icon: - - base64data: >- - PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzkuNDcgMTMzLjg4Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6IzFkNTZkODt9LmNscy0ye2ZpbGw6IzcwYWRlZjt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkxheWVyXzIiIGRhdGEtbmFtZT0iTGF5ZXIgMiI+PGcgaWQ9IkxheWVyXzEtMiIgZGF0YS1uYW1lPSJMYXllciAxIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNy41MSwxMTMuNjhhNi41LDYuNSwwLDAsMC00LjMtMS4zMywxMS43LDExLjcsMCwwLDAtMy42MS41MUExMy42NywxMy42NywwLDAsMCw2LjksMTE0djE5YTUuMTgsNS4xOCwwLDAsMS0uNzYuMjMsNC40MSw0LjQxLDAsMCwxLTEuMTIuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE0LjI0YTMuMjMsMy4yMywwLDAsMSwuNDMtMS43Niw0LjU5LDQuNTksMCwwLDEsMS41LTEuMzUsMTUuMTgsMTUuMTgsMCwwLDEsMy41MS0xLjQ3LDE3LjExLDE3LjExLDAsMCwxLDQuOTQtLjY3LDExLjU2LDExLjU2LDAsMCwxLDcuMywyLjA5cTIuNjcsMi4wOCwyLjY3LDYuNTZ2MTUuNDJhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE3Ljg1QTUuMDksNS4wOSwwLDAsMCwxNy41MSwxMTMuNjhaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNTkuMjEsMTEzLjUyYTUuODMsNS44MywwLDAsMC0zLjgyLTEuMTcsOC41Nyw4LjU3LDAsMCwwLTUuOSwyLjM0LDcuNzMsNy43MywwLDAsMSwuMywyLjE5djE2LjE4YTUuMiw1LjIsMCwwLDEtLjc4LjIzLDQuNDgsNC40OCwwLDAsMS0xLjEuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRhNC40OCw0LjQ4LDAsMCwwLTEuNDItMy42Nyw1LjkyLDUuOTIsMCwwLDAtMy44Ny0xLjE3LDkuMjYsOS4yNiwwLDAsMC0zLjA4LjUxQTExLjUxLDExLjUxLDAsMCwwLDM0Ljg5LDExNHYxOWE1LjM5LDUuMzksMCwwLDEtLjc3LjIzLDQuMzYsNC4zNiwwLDAsMS0xLjEyLjEzYy0xLjQ2LDAtMi4xOC0uNjEtMi4xOC0xLjgzVjExNC4yNGEzLjE1LDMuMTUsMCwwLDEsLjQzLTEuNzEsNSw1LDAsMCwxLDEuNS0xLjRBMTUuNzUsMTUuNzUsMCwwLDEsNDAuNDgsMTA5YTEyLjQzLDEyLjQzLDAsMCwxLDQuNDMuNzQsNi43Miw2LjcyLDAsMCwxLDMsMiwxMS4yOCwxMS4yOCwwLDAsMSwzLjMxLTJBMTIuMjksMTIuMjksMCwwLDEsNTUuNywxMDlhMTAuMjMsMTAuMjMsMCwwLDEsNi41NiwycTIuNDUsMiwyLjQ0LDZ2MTYuMDhhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRBNC40OCw0LjQ4LDAsMCwwLDU5LjIxLDExMy41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik04OC45MiwxMjYuOTFBNiw2LDAsMCwxLDg2LjUzLDEzMnEtMi4zOSwxLjg0LTYuOTIsMS44NGExOCwxOCwwLDAsMS0zLjU2LS4zMywxMi41OCwxMi41OCwwLDAsMS0yLjc3LS44Nyw1LjU1LDUuNTUsMCwwLDEtMS43OC0xLjIyLDIsMiwwLDAsMS0uNjQtMS40LDIuMjUsMi4yNSwwLDAsMSwuMzMtMS4xNywyLjg4LDIuODgsMCwwLDEsMS0xLDE2LjMxLDE2LjMxLDAsMCwwLDMuMjEsMS44MSwxMC4zNywxMC4zNywwLDAsMCw0LjE3Ljc5cTUuMywwLDUuMjktMy41NmMwLTEuOTQtMS4xNy0zLjE5LTMuNTEtMy43N0w3Ny4xMiwxMjJhOS4xMyw5LjEzLDAsMCwxLTQuNTMtMi4zNyw1LjY1LDUuNjUsMCwwLDEtMS40Mi00LDYuMTksNi4xOSwwLDAsMSwuNTMtMi41NEE1Ljc1LDUuNzUsMCwwLDEsNzMuMzUsMTExYTguMzEsOC4zMSwwLDAsMSwyLjc4LTEuNDVBMTIuNTYsMTIuNTYsMCwwLDEsODAsMTA5LDEzLjQsMTMuNCwwLDAsMSw4NS43NywxMTBjMS40Ni42OSwyLjE5LDEuNSwyLjE5LDIuNDFhMi4wNiwyLjA2LDAsMCwxLTEuMjIsMS45NCwxNS43NywxNS43NywwLDAsMC0yLjYtMS4zMiwxMCwxMCwwLDAsMC00LS43Miw2LjY3LDYuNjcsMCwwLDAtMy42NC44NywyLjczLDIuNzMsMCwwLDAtMS4zNCwyLjQ0LDIuNzcsMi43NywwLDAsMCwuNzYsMiw0LjkxLDQuOTEsMCwwLDAsMi41NCwxLjIzbDMuNTEuODZhMTEuMDgsMTEuMDgsMCwwLDEsNS4xOSwyLjU3QTYuMTUsNi4xNSwwLDAsMSw4OC45MiwxMjYuOTFaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTAzLjEyLDEzMy44M2E5LjczLDkuNzMsMCwwLDEtNS43Ny0xLjU4cS0yLjIyLTEuNTgtMi4yMi01LjI0VjEwMi44NGE1LDUsMCwwLDEsLjc5LS4yMyw0LjY5LDQuNjksMCwwLDEsMS4xNC0uMTNjMS40MywwLDIuMTQuNjEsMi4xNCwxLjgzdjUuODVoOC4zNWE0LjI3LDQuMjcsMCwwLDEsLjMuNjksMi44NSwyLjg1LDAsMCwxLC4xNS45NGMwLDEuMTYtLjUsMS43My0xLjUyLDEuNzNIOTkuMnYxMy4yM2EzLjMyLDMuMzIsMCwwLDAsMS4xNSwyLjg4LDUuMzgsNS4zOCwwLDAsMCwzLjIzLjg0LDYuODgsNi44OCwwLDAsMCwxLjkzLS4zMSw3LjkzLDcuOTMsMCwwLDAsMS43OC0uNzEsMy4yNiwzLjI2LDAsMCwxLC41Ni43NiwyLjE3LDIuMTcsMCwwLDEsLjI2LDEuMDcsMi4wOCwyLjA4LDAsMCwxLTEuMzMsMS44M0E3LjcxLDcuNzEsMCwwLDEsMTAzLjEyLDEzMy44M1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjIuNjYsMTA5YTExLjMsMTEuMywwLDAsMSw3LDJxMi41OSwyLDIuNiw2LjI2VjEyOS4zYTIuODIsMi44MiwwLDAsMS0uNDQsMS43LDQuMzcsNC4zNywwLDAsMS0xLjI5LDEuMSwxMy4zMSwxMy4zMSwwLDAsMS0zLjIzLDEuMjQsMTcuOSwxNy45LDAsMCwxLTQuNjEuNTRxLTQuNzgsMC03LjQtMS44OWE2LjI3LDYuMjcsMCwwLDEtMi42Mi01LjQ0LDYsNiwwLDAsMSwyLjE4LTUuMDYsMTEuODEsMTEuODEsMCwwLDEsNi4xNi0yLjExbDcuMjMtLjcydi0xLjQyYTQuMzgsNC4zOCwwLDAsMC0xLjUzLTMuNzIsNi42MSw2LjYxLDAsMCwwLTQuMTItMS4xNywxMy4xMiwxMy4xMiwwLDAsMC00LC42MSwyMi4xMSwyMi4xMSwwLDAsMC0zLjM2LDEuMzgsNC44Niw0Ljg2LDAsMCwxLS43NC0uODIsMS42NywxLjY3LDAsMCwxLS4zMy0xLDEuODIsMS44MiwwLDAsMSwuMzYtMS4xNywzLjMsMy4zLDAsMCwxLDEuMTItLjg3LDEyLjQsMTIuNCwwLDAsMSwzLjE1LTEuMDlBMTguMTIsMTguMTIsMCwwLDEsMTIyLjY2LDEwOVptMCwyMS41M2ExMi41OCwxMi41OCwwLDAsMCwzLjU0LS40Myw4LjQ4LDguNDgsMCwwLDAsMi0uODR2LTcuMzhsLTYuMzEuNjZhNy44OSw3Ljg5LDAsMCwwLTMuOTIsMS4yLDMuMjEsMy4yMSwwLDAsMC0xLjI3LDIuNzcsMy40NCwzLjQ0LDAsMCwwLDEuNDcsM0E3Ljg2LDcuODYsMCwwLDAsMTIyLjcxLDEzMC41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNDcuNzQsMTMzLjgzYTkuNzUsOS43NSwwLDAsMS01Ljc3LTEuNThjLTEuNDgtMS4wNS0yLjIxLTIuOC0yLjIxLTUuMjRWMTAyLjg0YTQuODYsNC44NiwwLDAsMSwuNzgtLjIzLDQuNzEsNC43MSwwLDAsMSwxLjE1LS4xM2MxLjQyLDAsMi4xNC42MSwyLjE0LDEuODN2NS44NWg4LjM0YTQuMiw0LjIsMCwwLDEsLjMxLjY5LDIuODUsMi44NSwwLDAsMSwuMTUuOTRjMCwxLjE2LS41MSwxLjczLTEuNTMsMS43M2gtNy4yN3YxMy4yM2EzLjM1LDMuMzUsMCwwLDAsMS4xNCwyLjg4LDUuNCw1LjQsMCwwLDAsMy4yMy44NCw3LDcsMCwwLDAsMS45NC0uMzEsOC4xMyw4LjEzLDAsMCwwLDEuNzgtLjcxLDMuNTcsMy41NywwLDAsMSwuNTYuNzYsMi4xNywyLjE3LDAsMCwxLC4yNSwxLjA3LDIuMDgsMi4wOCwwLDAsMS0xLjMyLDEuODNBNy43Niw3Ljc2LDAsMCwxLDE0Ny43NCwxMzMuODNaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTYwLjc3LDEyMy44cTEuMzgsNi42Nyw4Ljc1LDYuNjdhMTAuMTUsMTAuMTUsMCwwLDAsMy44Ny0uNzEsMTEuNzEsMTEuNzEsMCwwLDAsMi43NS0xLjUzLDIuMTYsMi4xNiwwLDAsMSwxLjIyLDEuOTMsMiwyLDAsMCwxLS42NCwxLjM4LDUuNjksNS42OSwwLDAsMS0xLjczLDEuMTcsMTEuNDksMTEuNDksMCwwLDEtMi41NC44MSwxNS40NSwxNS40NSwwLDAsMS0zLjEzLjMxcS01LjkxLDAtOS4zNC0zLjIxdC0zLjQzLTkuMzZhMTQuNzksMTQuNzksMCwwLDEsLjg0LTUuMTcsMTEuMDcsMTEuMDcsMCwwLDEsMi4zNC0zLjg0LDEwLDEwLDAsMCwxLDMuNTktMi40MiwxMiwxMiwwLDAsMSw0LjUyLS44NCwxMS40MSwxMS40MSwwLDAsMSw0LjIzLjc3LDkuNjgsOS42OCwwLDAsMSwzLjMzLDIuMTYsMTAuMTcsMTAuMTcsMCwwLDEsMi4xOSwzLjMxLDExLDExLDAsMCwxLC43OSw0LjIsMi4xMywyLjEzLDAsMCwxLS41MSwxLjYsMi4zNywyLjM3LDAsMCwxLTEuNDMuNThabTctMTEuNWE2Ljc3LDYuNzcsMCwwLDAtNS4xNCwyLjE2LDkuMDYsOS4wNiwwLDAsMC0yLjEzLDYuMTlsMTQtMS45NGE3LjQ1LDcuNDUsMCwwLDAtMi00LjZBNi4yMSw2LjIxLDAsMCwwLDE2Ny43OSwxMTIuM1oiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik02Ni45MiwxMy4xM3Y5LjM5YzEuMjctLjA5LDIuNTQtLjE2LDMuODMtLjJWMTEuMzloLS4zM2E4My4yOSw4My4yOSwwLDAsMSwzMy4yNC03LjU0VjI3LjEyYzEuMy40NCwyLjU3LjkxLDMuODMsMS40VjMuODVBODMsODMsMCwwLDEsMTQxLjk0LDEyVjU1Ljc3aDMuODNWMTRjMTYuOCw5LjQyLDI4LjIsMjQuNTksMjkuNjgsNDEuODloMy44NEMxNzYuODMsMjQuNzMsMTQ0LjcxLDAsMTA1LjU4LDBjLTI2LDAtNDguODQsMTAuODktNjIsMjcuMzEsMi4yNy0uNzksNC42LTEuNDksNy0yLjExQTY3LjI4LDY3LjI4LDAsMCwxLDY2LjkyLDEzLjEzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTE0NC42OSw1OS42MWE1My44NCw1My44NCwwLDAsMSw2Ljc5LDIyLjY5bDI4LTIyLjZaIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTQ3LjgxLDg0LjMzYTUwLjM5LDUwLjM5LDAsMCwwLTcuNTQtMjQuNzNjLTctMTEuNTktMTguNTgtMjEuMDgtMzIuNzgtMjctMS4yNS0uNTItMi41My0xLTMuODMtMS40OEE4OC42LDg4LjYsMCwwLDAsNzMuOSwyNi4wOWMtMS4wNSwwLTIuMTEsMC0zLjE1LjA2LTEuMjksMC0yLjU2LjExLTMuODMuMjFhODcuNTgsODcuNTgsMCwwLDAtMjEuMDgsNC4yMWMtMi4xNS43Mi00LjI0LDEuNTEtNi4yOSwyLjM4QzE2LjU4LDQyLjc1LjY3LDYyLjA1LDAsODQuMzN2MS4yNWMwLDEuMjIuNywxLjgzLDIuMDksMS44M2E0LDQsMCwwLDAsMS4wNy0uMTMsNC41OCw0LjU4LDAsMCwwLC43My0uMjNWODQuMzNoMGMwLS40NywwLS45My4wNi0xLjQuMDktMS40My4yNS0yLjg0LjQ3LTQuMjRhNDUuNzQsNDUuNzQsMCwwLDEsMS42NS02Ljg0QzYuNSw3MC41MSw3LDY5LjIsNy41NCw2Ny45Yy4zNy0uODcuNzctMS43MiwxLjE4LTIuNTdhNTIuNzksNTIuNzksMCwwLDEsMi44MS00Ljk1LDU1LjYxLDU1LjYxLDAsMCwxLDUuMjctNi45MWMuMzItLjM2LjY2LS43MiwxLTEuMDgsMS0xLjA4LDIuMDctMi4xMiwzLjE3LTMuMTRzMi4yNS0yLDMuNDQtMi45NHEyLjM3LTEuOTEsNS0zLjYxYy44Ny0uNTcsMS43NS0xLjEzLDIuNjUtMS42Ni40NS0uMjcuOS0uNTQsMS4zNi0uOGwxLjg2LTF2NDUuMWgwdjEuMjVjMCwxLjIyLjY5LDEuODMsMi4wOSwxLjgzYTQsNCwwLDAsMCwxLjA3LS4xMyw1LjM5LDUuMzksMCwwLDAsLjczLS4yM1Y4NC4zM2gwbDAtMjVWMzcuNDloLS4zM2wxLjgtLjgyYy41My0uMjMsMS4wOC0uNDQsMS42Mi0uNjZzLjkzLS4zOSwxLjQtLjU3cTIuMy0uODgsNC42OC0xLjY0YTg0LjY2LDg0LjY2LDAsMCwxLDE4LjY4LTMuNTljMS4yNy0uMSwyLjU0LS4xNywzLjgzLS4yMmwxLjI0LDBWNTkuNDJsLS4wNiwyNC45MWgwdjEuMjVjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDUsNSwwLDAsMCwuNzMtLjIzVjg0LjMzaDBWMjkuOTRBODUuMDUsODUuMDUsMCwwLDEsOTkuNTYsMzMuOGMxLjM5LjQ0LDIuNzYuOTIsNC4xLDEuNDMuMi4wNy4zOS4xMy41OC4yMSwxLC4zOSwyLC44LDMsMS4yM2wuMjMuMTFjLjkxLjQsMS44Mi44MSwyLjcxLDEuMjRsLjA3LDBWODQuMzNoMHYxLjI1YS4yMi4yMiwwLDAsMCwwLC4wOHYuMTRoMGMuMDgsMS4wNy43NywxLjYxLDIuMDcsMS42MWE0LDQsMCwwLDAsMS4wNy0uMTMsNSw1LDAsMCwwLC43My0uMjNWODQuMzNoMGwtLjA2LTI0LjhWNDAuMDZsLjMzLjE4LDEuMzcuOGMuODkuNTMsMS43OCwxLjA5LDIuNjQsMS42NnEyLjU5LDEuNzEsNSwzLjYxYzEuMTkuOTQsMi4zMywxLjkzLDMuNDQsMi45NFMxMjksNTEuMzEsMTMwLDUyLjM5bDEsMS4wOGE1NS4wNiw1NS4wNiwwLDAsMSw0Ljc0LDYuMTJsLjUyLjc5YTUwLjY0LDUwLjY0LDAsMCwxLDIuODEsNC45NWMuNDIuODUuODEsMS43LDEuMTgsMi41Ny41NSwxLjMsMS4wNSwyLjYxLDEuNDgsMy45NWE0NS43MSw0NS43MSwwLDAsMSwxLjY0LDYuODQsNDIuNjIsNDIuNjIsMCwwLDEsLjQ4LDQuMjRjMCwuNjEsMCwxLjIzLjA2LDEuODV2LjhjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDQuNTgsNC41OCwwLDAsMCwuNzMtLjIzVjg0LjMzWiIvPjwvZz48L2c+PC9zdmc+ - mediatype: image/svg+xml + - base64data: PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzkuNDcgMTMzLjg4Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6IzFkNTZkODt9LmNscy0ye2ZpbGw6IzcwYWRlZjt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkxheWVyXzIiIGRhdGEtbmFtZT0iTGF5ZXIgMiI+PGcgaWQ9IkxheWVyXzEtMiIgZGF0YS1uYW1lPSJMYXllciAxIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNy41MSwxMTMuNjhhNi41LDYuNSwwLDAsMC00LjMtMS4zMywxMS43LDExLjcsMCwwLDAtMy42MS41MUExMy42NywxMy42NywwLDAsMCw2LjksMTE0djE5YTUuMTgsNS4xOCwwLDAsMS0uNzYuMjMsNC40MSw0LjQxLDAsMCwxLTEuMTIuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE0LjI0YTMuMjMsMy4yMywwLDAsMSwuNDMtMS43Niw0LjU5LDQuNTksMCwwLDEsMS41LTEuMzUsMTUuMTgsMTUuMTgsMCwwLDEsMy41MS0xLjQ3LDE3LjExLDE3LjExLDAsMCwxLDQuOTQtLjY3LDExLjU2LDExLjU2LDAsMCwxLDcuMywyLjA5cTIuNjcsMi4wOCwyLjY3LDYuNTZ2MTUuNDJhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE3Ljg1QTUuMDksNS4wOSwwLDAsMCwxNy41MSwxMTMuNjhaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNTkuMjEsMTEzLjUyYTUuODMsNS44MywwLDAsMC0zLjgyLTEuMTcsOC41Nyw4LjU3LDAsMCwwLTUuOSwyLjM0LDcuNzMsNy43MywwLDAsMSwuMywyLjE5djE2LjE4YTUuMiw1LjIsMCwwLDEtLjc4LjIzLDQuNDgsNC40OCwwLDAsMS0xLjEuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRhNC40OCw0LjQ4LDAsMCwwLTEuNDItMy42Nyw1LjkyLDUuOTIsMCwwLDAtMy44Ny0xLjE3LDkuMjYsOS4yNiwwLDAsMC0zLjA4LjUxQTExLjUxLDExLjUxLDAsMCwwLDM0Ljg5LDExNHYxOWE1LjM5LDUuMzksMCwwLDEtLjc3LjIzLDQuMzYsNC4zNiwwLDAsMS0xLjEyLjEzYy0xLjQ2LDAtMi4xOC0uNjEtMi4xOC0xLjgzVjExNC4yNGEzLjE1LDMuMTUsMCwwLDEsLjQzLTEuNzEsNSw1LDAsMCwxLDEuNS0xLjRBMTUuNzUsMTUuNzUsMCwwLDEsNDAuNDgsMTA5YTEyLjQzLDEyLjQzLDAsMCwxLDQuNDMuNzQsNi43Miw2LjcyLDAsMCwxLDMsMiwxMS4yOCwxMS4yOCwwLDAsMSwzLjMxLTJBMTIuMjksMTIuMjksMCwwLDEsNTUuNywxMDlhMTAuMjMsMTAuMjMsMCwwLDEsNi41NiwycTIuNDUsMiwyLjQ0LDZ2MTYuMDhhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRBNC40OCw0LjQ4LDAsMCwwLDU5LjIxLDExMy41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik04OC45MiwxMjYuOTFBNiw2LDAsMCwxLDg2LjUzLDEzMnEtMi4zOSwxLjg0LTYuOTIsMS44NGExOCwxOCwwLDAsMS0zLjU2LS4zMywxMi41OCwxMi41OCwwLDAsMS0yLjc3LS44Nyw1LjU1LDUuNTUsMCwwLDEtMS43OC0xLjIyLDIsMiwwLDAsMS0uNjQtMS40LDIuMjUsMi4yNSwwLDAsMSwuMzMtMS4xNywyLjg4LDIuODgsMCwwLDEsMS0xLDE2LjMxLDE2LjMxLDAsMCwwLDMuMjEsMS44MSwxMC4zNywxMC4zNywwLDAsMCw0LjE3Ljc5cTUuMywwLDUuMjktMy41NmMwLTEuOTQtMS4xNy0zLjE5LTMuNTEtMy43N0w3Ny4xMiwxMjJhOS4xMyw5LjEzLDAsMCwxLTQuNTMtMi4zNyw1LjY1LDUuNjUsMCwwLDEtMS40Mi00LDYuMTksNi4xOSwwLDAsMSwuNTMtMi41NEE1Ljc1LDUuNzUsMCwwLDEsNzMuMzUsMTExYTguMzEsOC4zMSwwLDAsMSwyLjc4LTEuNDVBMTIuNTYsMTIuNTYsMCwwLDEsODAsMTA5LDEzLjQsMTMuNCwwLDAsMSw4NS43NywxMTBjMS40Ni42OSwyLjE5LDEuNSwyLjE5LDIuNDFhMi4wNiwyLjA2LDAsMCwxLTEuMjIsMS45NCwxNS43NywxNS43NywwLDAsMC0yLjYtMS4zMiwxMCwxMCwwLDAsMC00LS43Miw2LjY3LDYuNjcsMCwwLDAtMy42NC44NywyLjczLDIuNzMsMCwwLDAtMS4zNCwyLjQ0LDIuNzcsMi43NywwLDAsMCwuNzYsMiw0LjkxLDQuOTEsMCwwLDAsMi41NCwxLjIzbDMuNTEuODZhMTEuMDgsMTEuMDgsMCwwLDEsNS4xOSwyLjU3QTYuMTUsNi4xNSwwLDAsMSw4OC45MiwxMjYuOTFaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTAzLjEyLDEzMy44M2E5LjczLDkuNzMsMCwwLDEtNS43Ny0xLjU4cS0yLjIyLTEuNTgtMi4yMi01LjI0VjEwMi44NGE1LDUsMCwwLDEsLjc5LS4yMyw0LjY5LDQuNjksMCwwLDEsMS4xNC0uMTNjMS40MywwLDIuMTQuNjEsMi4xNCwxLjgzdjUuODVoOC4zNWE0LjI3LDQuMjcsMCwwLDEsLjMuNjksMi44NSwyLjg1LDAsMCwxLC4xNS45NGMwLDEuMTYtLjUsMS43My0xLjUyLDEuNzNIOTkuMnYxMy4yM2EzLjMyLDMuMzIsMCwwLDAsMS4xNSwyLjg4LDUuMzgsNS4zOCwwLDAsMCwzLjIzLjg0LDYuODgsNi44OCwwLDAsMCwxLjkzLS4zMSw3LjkzLDcuOTMsMCwwLDAsMS43OC0uNzEsMy4yNiwzLjI2LDAsMCwxLC41Ni43NiwyLjE3LDIuMTcsMCwwLDEsLjI2LDEuMDcsMi4wOCwyLjA4LDAsMCwxLTEuMzMsMS44M0E3LjcxLDcuNzEsMCwwLDEsMTAzLjEyLDEzMy44M1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjIuNjYsMTA5YTExLjMsMTEuMywwLDAsMSw3LDJxMi41OSwyLDIuNiw2LjI2VjEyOS4zYTIuODIsMi44MiwwLDAsMS0uNDQsMS43LDQuMzcsNC4zNywwLDAsMS0xLjI5LDEuMSwxMy4zMSwxMy4zMSwwLDAsMS0zLjIzLDEuMjQsMTcuOSwxNy45LDAsMCwxLTQuNjEuNTRxLTQuNzgsMC03LjQtMS44OWE2LjI3LDYuMjcsMCwwLDEtMi42Mi01LjQ0LDYsNiwwLDAsMSwyLjE4LTUuMDYsMTEuODEsMTEuODEsMCwwLDEsNi4xNi0yLjExbDcuMjMtLjcydi0xLjQyYTQuMzgsNC4zOCwwLDAsMC0xLjUzLTMuNzIsNi42MSw2LjYxLDAsMCwwLTQuMTItMS4xNywxMy4xMiwxMy4xMiwwLDAsMC00LC42MSwyMi4xMSwyMi4xMSwwLDAsMC0zLjM2LDEuMzgsNC44Niw0Ljg2LDAsMCwxLS43NC0uODIsMS42NywxLjY3LDAsMCwxLS4zMy0xLDEuODIsMS44MiwwLDAsMSwuMzYtMS4xNywzLjMsMy4zLDAsMCwxLDEuMTItLjg3LDEyLjQsMTIuNCwwLDAsMSwzLjE1LTEuMDlBMTguMTIsMTguMTIsMCwwLDEsMTIyLjY2LDEwOVptMCwyMS41M2ExMi41OCwxMi41OCwwLDAsMCwzLjU0LS40Myw4LjQ4LDguNDgsMCwwLDAsMi0uODR2LTcuMzhsLTYuMzEuNjZhNy44OSw3Ljg5LDAsMCwwLTMuOTIsMS4yLDMuMjEsMy4yMSwwLDAsMC0xLjI3LDIuNzcsMy40NCwzLjQ0LDAsMCwwLDEuNDcsM0E3Ljg2LDcuODYsMCwwLDAsMTIyLjcxLDEzMC41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNDcuNzQsMTMzLjgzYTkuNzUsOS43NSwwLDAsMS01Ljc3LTEuNThjLTEuNDgtMS4wNS0yLjIxLTIuOC0yLjIxLTUuMjRWMTAyLjg0YTQuODYsNC44NiwwLDAsMSwuNzgtLjIzLDQuNzEsNC43MSwwLDAsMSwxLjE1LS4xM2MxLjQyLDAsMi4xNC42MSwyLjE0LDEuODN2NS44NWg4LjM0YTQuMiw0LjIsMCwwLDEsLjMxLjY5LDIuODUsMi44NSwwLDAsMSwuMTUuOTRjMCwxLjE2LS41MSwxLjczLTEuNTMsMS43M2gtNy4yN3YxMy4yM2EzLjM1LDMuMzUsMCwwLDAsMS4xNCwyLjg4LDUuNCw1LjQsMCwwLDAsMy4yMy44NCw3LDcsMCwwLDAsMS45NC0uMzEsOC4xMyw4LjEzLDAsMCwwLDEuNzgtLjcxLDMuNTcsMy41NywwLDAsMSwuNTYuNzYsMi4xNywyLjE3LDAsMCwxLC4yNSwxLjA3LDIuMDgsMi4wOCwwLDAsMS0xLjMyLDEuODNBNy43Niw3Ljc2LDAsMCwxLDE0Ny43NCwxMzMuODNaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTYwLjc3LDEyMy44cTEuMzgsNi42Nyw4Ljc1LDYuNjdhMTAuMTUsMTAuMTUsMCwwLDAsMy44Ny0uNzEsMTEuNzEsMTEuNzEsMCwwLDAsMi43NS0xLjUzLDIuMTYsMi4xNiwwLDAsMSwxLjIyLDEuOTMsMiwyLDAsMCwxLS42NCwxLjM4LDUuNjksNS42OSwwLDAsMS0xLjczLDEuMTcsMTEuNDksMTEuNDksMCwwLDEtMi41NC44MSwxNS40NSwxNS40NSwwLDAsMS0zLjEzLjMxcS01LjkxLDAtOS4zNC0zLjIxdC0zLjQzLTkuMzZhMTQuNzksMTQuNzksMCwwLDEsLjg0LTUuMTcsMTEuMDcsMTEuMDcsMCwwLDEsMi4zNC0zLjg0LDEwLDEwLDAsMCwxLDMuNTktMi40MiwxMiwxMiwwLDAsMSw0LjUyLS44NCwxMS40MSwxMS40MSwwLDAsMSw0LjIzLjc3LDkuNjgsOS42OCwwLDAsMSwzLjMzLDIuMTYsMTAuMTcsMTAuMTcsMCwwLDEsMi4xOSwzLjMxLDExLDExLDAsMCwxLC43OSw0LjIsMi4xMywyLjEzLDAsMCwxLS41MSwxLjYsMi4zNywyLjM3LDAsMCwxLTEuNDMuNThabTctMTEuNWE2Ljc3LDYuNzcsMCwwLDAtNS4xNCwyLjE2LDkuMDYsOS4wNiwwLDAsMC0yLjEzLDYuMTlsMTQtMS45NGE3LjQ1LDcuNDUsMCwwLDAtMi00LjZBNi4yMSw2LjIxLDAsMCwwLDE2Ny43OSwxMTIuM1oiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik02Ni45MiwxMy4xM3Y5LjM5YzEuMjctLjA5LDIuNTQtLjE2LDMuODMtLjJWMTEuMzloLS4zM2E4My4yOSw4My4yOSwwLDAsMSwzMy4yNC03LjU0VjI3LjEyYzEuMy40NCwyLjU3LjkxLDMuODMsMS40VjMuODVBODMsODMsMCwwLDEsMTQxLjk0LDEyVjU1Ljc3aDMuODNWMTRjMTYuOCw5LjQyLDI4LjIsMjQuNTksMjkuNjgsNDEuODloMy44NEMxNzYuODMsMjQuNzMsMTQ0LjcxLDAsMTA1LjU4LDBjLTI2LDAtNDguODQsMTAuODktNjIsMjcuMzEsMi4yNy0uNzksNC42LTEuNDksNy0yLjExQTY3LjI4LDY3LjI4LDAsMCwxLDY2LjkyLDEzLjEzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTE0NC42OSw1OS42MWE1My44NCw1My44NCwwLDAsMSw2Ljc5LDIyLjY5bDI4LTIyLjZaIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTQ3LjgxLDg0LjMzYTUwLjM5LDUwLjM5LDAsMCwwLTcuNTQtMjQuNzNjLTctMTEuNTktMTguNTgtMjEuMDgtMzIuNzgtMjctMS4yNS0uNTItMi41My0xLTMuODMtMS40OEE4OC42LDg4LjYsMCwwLDAsNzMuOSwyNi4wOWMtMS4wNSwwLTIuMTEsMC0zLjE1LjA2LTEuMjksMC0yLjU2LjExLTMuODMuMjFhODcuNTgsODcuNTgsMCwwLDAtMjEuMDgsNC4yMWMtMi4xNS43Mi00LjI0LDEuNTEtNi4yOSwyLjM4QzE2LjU4LDQyLjc1LjY3LDYyLjA1LDAsODQuMzN2MS4yNWMwLDEuMjIuNywxLjgzLDIuMDksMS44M2E0LDQsMCwwLDAsMS4wNy0uMTMsNC41OCw0LjU4LDAsMCwwLC43My0uMjNWODQuMzNoMGMwLS40NywwLS45My4wNi0xLjQuMDktMS40My4yNS0yLjg0LjQ3LTQuMjRhNDUuNzQsNDUuNzQsMCwwLDEsMS42NS02Ljg0QzYuNSw3MC41MSw3LDY5LjIsNy41NCw2Ny45Yy4zNy0uODcuNzctMS43MiwxLjE4LTIuNTdhNTIuNzksNTIuNzksMCwwLDEsMi44MS00Ljk1LDU1LjYxLDU1LjYxLDAsMCwxLDUuMjctNi45MWMuMzItLjM2LjY2LS43MiwxLTEuMDgsMS0xLjA4LDIuMDctMi4xMiwzLjE3LTMuMTRzMi4yNS0yLDMuNDQtMi45NHEyLjM3LTEuOTEsNS0zLjYxYy44Ny0uNTcsMS43NS0xLjEzLDIuNjUtMS42Ni40NS0uMjcuOS0uNTQsMS4zNi0uOGwxLjg2LTF2NDUuMWgwdjEuMjVjMCwxLjIyLjY5LDEuODMsMi4wOSwxLjgzYTQsNCwwLDAsMCwxLjA3LS4xMyw1LjM5LDUuMzksMCwwLDAsLjczLS4yM1Y4NC4zM2gwbDAtMjVWMzcuNDloLS4zM2wxLjgtLjgyYy41My0uMjMsMS4wOC0uNDQsMS42Mi0uNjZzLjkzLS4zOSwxLjQtLjU3cTIuMy0uODgsNC42OC0xLjY0YTg0LjY2LDg0LjY2LDAsMCwxLDE4LjY4LTMuNTljMS4yNy0uMSwyLjU0LS4xNywzLjgzLS4yMmwxLjI0LDBWNTkuNDJsLS4wNiwyNC45MWgwdjEuMjVjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDUsNSwwLDAsMCwuNzMtLjIzVjg0LjMzaDBWMjkuOTRBODUuMDUsODUuMDUsMCwwLDEsOTkuNTYsMzMuOGMxLjM5LjQ0LDIuNzYuOTIsNC4xLDEuNDMuMi4wNy4zOS4xMy41OC4yMSwxLC4zOSwyLC44LDMsMS4yM2wuMjMuMTFjLjkxLjQsMS44Mi44MSwyLjcxLDEuMjRsLjA3LDBWODQuMzNoMHYxLjI1YS4yMi4yMiwwLDAsMCwwLC4wOHYuMTRoMGMuMDgsMS4wNy43NywxLjYxLDIuMDcsMS42MWE0LDQsMCwwLDAsMS4wNy0uMTMsNSw1LDAsMCwwLC43My0uMjNWODQuMzNoMGwtLjA2LTI0LjhWNDAuMDZsLjMzLjE4LDEuMzcuOGMuODkuNTMsMS43OCwxLjA5LDIuNjQsMS42NnEyLjU5LDEuNzEsNSwzLjYxYzEuMTkuOTQsMi4zMywxLjkzLDMuNDQsMi45NFMxMjksNTEuMzEsMTMwLDUyLjM5bDEsMS4wOGE1NS4wNiw1NS4wNiwwLDAsMSw0Ljc0LDYuMTJsLjUyLjc5YTUwLjY0LDUwLjY0LDAsMCwxLDIuODEsNC45NWMuNDIuODUuODEsMS43LDEuMTgsMi41Ny41NSwxLjMsMS4wNSwyLjYxLDEuNDgsMy45NWE0NS43MSw0NS43MSwwLDAsMSwxLjY0LDYuODQsNDIuNjIsNDIuNjIsMCwwLDEsLjQ4LDQuMjRjMCwuNjEsMCwxLjIzLjA2LDEuODV2LjhjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDQuNTgsNC41OCwwLDAsMCwuNzMtLjIzVjg0LjMzWiIvPjwvZz48L2c+PC9zdmc+ + mediatype: image/svg+xml install: spec: clusterPermissions: - rules: - apiGroups: - - admissionregistration.k8s.io - resources: - - mutatingwebhookconfigurations - verbs: - - '*' - - apiGroups: - - rbac.authorization.k8s.io + - "" resources: - - clusterroles - - clusterrolebindings - - rolebindings - - roles + - configmaps + - namespaces + - serviceaccounts verbs: - '*' - apiGroups: - - nmstate.io + - admissionregistration.k8s.io resources: - - '*' + - mutatingwebhookconfigurations verbs: - '*' - apiGroups: @@ -76,18 +138,25 @@ spec: - apiGroups: - apps resources: - - deployments - daemonsets + - deployments - replicasets - statefulsets verbs: - '*' - apiGroups: - - "" + - nmstate.io resources: - - serviceaccounts - - configmaps - - namespaces + - '*' + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles verbs: - '*' serviceAccountName: nmstate-operator @@ -125,9 +194,7 @@ spec: - name: HANDLER_IMAGE_PULL_POLICY value: Always - name: HANDLER_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] + value: nmstate image: quay.io/nmstate/kubernetes-nmstate-operator:latest imagePullPolicy: Always name: nmstate-operator @@ -144,20 +211,20 @@ spec: - apiGroups: - "" resources: - - services + - configmaps - endpoints - - persistentvolumeclaims - events - - configmaps - - secrets + - persistentvolumeclaims - pods + - secrets + - services verbs: - '*' - apiGroups: - apps resources: - - deployments - daemonsets + - deployments - replicasets - statefulsets verbs: diff --git a/bundle/manifests/nmstate-operator_v1_serviceaccount.yaml b/bundle/manifests/nmstate-operator_v1_serviceaccount.yaml deleted file mode 100644 index 468ca5c894..0000000000 --- a/bundle/manifests/nmstate-operator_v1_serviceaccount.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - creationTimestamp: null - labels: - nmstate.io: "" - name: nmstate-operator diff --git a/bundle/manifests/nmstate.io_nmstates.yaml b/bundle/manifests/nmstate.io_nmstates.yaml index 5dae12fdde..1b662acf33 100644 --- a/bundle/manifests/nmstate.io_nmstates.yaml +++ b/bundle/manifests/nmstate.io_nmstates.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.1 + controller-gen.kubebuilder.io/version: v0.6.0 creationTimestamp: null name: nmstates.nmstate.io spec: @@ -34,6 +34,58 @@ spec: spec: description: NMStateSpec defines the desired state of NMState properties: + infraNodeSelector: + additionalProperties: + type: string + description: InfraNodeSelector is an optional selector that will be + added to webhook & certmanager Deployment manifests If InfraNodeSelector + is specified, the webhook and certmanager will run only on nodes + that have each of the indicated key-value pairs as labels applied + to the node. + type: object + infraTolerations: + description: InfraTolerations is an optional list of tolerations to + be added to webhook & certmanager Deployment manifests If InfraTolerations + is specified, the webhook and certmanager will be able to be scheduled + on nodes with corresponding taints + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array nodeSelector: additionalProperties: type: string @@ -44,6 +96,49 @@ spec: that have each of the indicated key-value pairs as labels applied to the node. type: object + tolerations: + description: Tolerations is an optional list of tolerations to be + added to handler DaemonSet manifest If Tolerations is specified, + the handler daemonset will be also scheduled on nodes with corresponding + taints + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array type: object status: description: NMStateStatus defines the observed state of NMState @@ -59,6 +154,8 @@ spec: type: string message: type: string + messageEncoded: + type: string reason: type: string status: @@ -74,6 +171,164 @@ spec: type: object served: true storage: true + - deprecated: true + name: v1beta1 + schema: + openAPIV3Schema: + description: NMState is the Schema for the nmstates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NMStateSpec defines the desired state of NMState + properties: + infraNodeSelector: + additionalProperties: + type: string + description: InfraNodeSelector is an optional selector that will be + added to webhook & certmanager Deployment manifests If InfraNodeSelector + is specified, the webhook and certmanager will run only on nodes + that have each of the indicated key-value pairs as labels applied + to the node. + type: object + infraTolerations: + description: InfraTolerations is an optional list of tolerations to + be added to webhook & certmanager Deployment manifests If InfraTolerations + is specified, the webhook and certmanager will be able to be scheduled + on nodes with corresponding taints + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is an optional selector that will be added + to handler DaemonSet manifest for both workers and control-plane + (https://github.com/nmstate/kubernetes-nmstate/blob/main/deploy/handler/operator.yaml). + If NodeSelector is specified, the handler will run only on nodes + that have each of the indicated key-value pairs as labels applied + to the node. + type: object + tolerations: + description: Tolerations is an optional list of tolerations to be + added to handler DaemonSet manifest If Tolerations is specified, + the handler daemonset will be also scheduled on nodes with corresponding + taints + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + status: + description: NMStateStatus defines the observed state of NMState + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: false status: acceptedNames: kind: "" diff --git a/bundle/manifests/nmstate.io_nodenetworkconfigurationenactments.yaml b/bundle/manifests/nmstate.io_nodenetworkconfigurationenactments.yaml new file mode 100644 index 0000000000..0f91989006 --- /dev/null +++ b/bundle/manifests/nmstate.io_nodenetworkconfigurationenactments.yaml @@ -0,0 +1,160 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.0 + creationTimestamp: null + name: nodenetworkconfigurationenactments.nmstate.io +spec: + group: nmstate.io + names: + kind: NodeNetworkConfigurationEnactment + listKind: NodeNetworkConfigurationEnactmentList + plural: nodenetworkconfigurationenactments + shortNames: + - nnce + singular: nodenetworkconfigurationenactment + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[?(@.status=="True")].type + name: Status + type: string + deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeNetworkConfigurationEnactment is the Schema for the nodenetworkconfigurationenactments + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: NodeNetworkConfigurationEnactmentStatus defines the observed + state of NodeNetworkConfigurationEnactment + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + desiredState: + description: The desired state rendered for the enactment's node using + the policy desiredState as template + type: object + x-kubernetes-preserve-unknown-fields: true + policyGeneration: + description: The generation from policy needed to check if an enactment + condition status belongs to the same policy version + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[?(@.status=="True")].type + name: Status + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: NodeNetworkConfigurationEnactment is the Schema for the nodenetworkconfigurationenactments + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: NodeNetworkConfigurationEnactmentStatus defines the observed + state of NodeNetworkConfigurationEnactment + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + desiredState: + description: The desired state rendered for the enactment's node using + the policy desiredState as template + type: object + x-kubernetes-preserve-unknown-fields: true + policyGeneration: + description: The generation from policy needed to check if an enactment + condition status belongs to the same policy version + format: int64 + type: integer + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/nmstate.io_nodenetworkconfigurationpolicies.yaml b/bundle/manifests/nmstate.io_nodenetworkconfigurationpolicies.yaml new file mode 100644 index 0000000000..f797687b54 --- /dev/null +++ b/bundle/manifests/nmstate.io_nodenetworkconfigurationpolicies.yaml @@ -0,0 +1,293 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.0 + creationTimestamp: null + name: nodenetworkconfigurationpolicies.nmstate.io +spec: + group: nmstate.io + names: + kind: NodeNetworkConfigurationPolicy + listKind: NodeNetworkConfigurationPolicyList + plural: nodenetworkconfigurationpolicies + shortNames: + - nncp + singular: nodenetworkconfigurationpolicy + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[?(@.status=="True")].type + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: NodeNetworkConfigurationPolicy is the Schema for the nodenetworkconfigurationpolicies + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NodeNetworkConfigurationPolicySpec defines the desired state + of NodeNetworkConfigurationPolicy + properties: + desiredState: + description: The desired configuration of the policy + type: object + x-kubernetes-preserve-unknown-fields: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: MaxUnavailable specifies percentage or number of machines + that can be updating at a time. Default is "50%". + x-kubernetes-int-or-string: true + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be true for the + policy to be applied to the node. Selector which must match a node''s + labels for the policy to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + type: object + status: + description: NodeNetworkConfigurationPolicyStatus defines the observed + state of NodeNetworkConfigurationPolicy + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + lastUnavailableNodeCountUpdate: + description: LastUnavailableNodeCountUpdate is time of the last UnavailableNodeCount + update + format: date-time + type: string + unavailableNodeCount: + description: UnavailableNodeCount represents the total number of potentially + unavailable nodes that are processing a NodeNetworkConfigurationPolicy + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[?(@.status=="True")].type + name: Status + type: string + deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeNetworkConfigurationPolicy is the Schema for the nodenetworkconfigurationpolicies + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NodeNetworkConfigurationPolicySpec defines the desired state + of NodeNetworkConfigurationPolicy + properties: + desiredState: + description: The desired configuration of the policy + type: object + x-kubernetes-preserve-unknown-fields: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: MaxUnavailable specifies percentage or number of machines + that can be updating at a time. Default is "50%". + x-kubernetes-int-or-string: true + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be true for the + policy to be applied to the node. Selector which must match a node''s + labels for the policy to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + type: object + status: + description: NodeNetworkConfigurationPolicyStatus defines the observed + state of NodeNetworkConfigurationPolicy + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + lastUnavailableNodeCountUpdate: + description: LastUnavailableNodeCountUpdate is time of the last UnavailableNodeCount + update + format: date-time + type: string + unavailableNodeCount: + description: UnavailableNodeCount represents the total number of potentially + unavailable nodes that are processing a NodeNetworkConfigurationPolicy + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[?(@.status=="True")].type + name: Status + type: string + deprecated: true + name: v1beta1 + schema: + openAPIV3Schema: + description: NodeNetworkConfigurationPolicy is the Schema for the nodenetworkconfigurationpolicies + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NodeNetworkConfigurationPolicySpec defines the desired state + of NodeNetworkConfigurationPolicy + properties: + desiredState: + description: The desired configuration of the policy + type: object + x-kubernetes-preserve-unknown-fields: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: MaxUnavailable specifies percentage or number of machines + that can be updating at a time. Default is "50%". + x-kubernetes-int-or-string: true + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be true for the + policy to be applied to the node. Selector which must match a node''s + labels for the policy to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + type: object + status: + description: NodeNetworkConfigurationPolicyStatus defines the observed + state of NodeNetworkConfigurationPolicy + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + lastUnavailableNodeCountUpdate: + description: LastUnavailableNodeCountUpdate is time of the last UnavailableNodeCount + update + format: date-time + type: string + unavailableNodeCount: + description: UnavailableNodeCount represents the total number of potentially + unavailable nodes that are processing a NodeNetworkConfigurationPolicy + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/nmstate.io_nodenetworkstates.yaml b/bundle/manifests/nmstate.io_nodenetworkstates.yaml new file mode 100644 index 0000000000..5baadf2c8a --- /dev/null +++ b/bundle/manifests/nmstate.io_nodenetworkstates.yaml @@ -0,0 +1,157 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.0 + creationTimestamp: null + name: nodenetworkstates.nmstate.io +spec: + group: nmstate.io + names: + kind: NodeNetworkState + listKind: NodeNetworkStateList + plural: nodenetworkstates + shortNames: + - nns + singular: nodenetworkstate + scope: Cluster + versions: + - deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeNetworkState is the Schema for the nodenetworkstates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: NodeNetworkStateStatus is the status of the NodeNetworkState + of a specific node + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + currentState: + description: "State contains the namestatectl yaml [1] as string instead + of golang struct so we don't need to be in sync with the schema. + \n [1] https://github.com/nmstate/nmstate/blob/base/libnmstate/schemas/operational-state.yaml" + type: object + x-kubernetes-preserve-unknown-fields: true + handlerNetworkManagerVersion: + type: string + handlerNmstateVersion: + type: string + hostNetworkManagerVersion: + type: string + lastSuccessfulUpdateTime: + format: date-time + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: NodeNetworkState is the Schema for the nodenetworkstates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: NodeNetworkStateStatus is the status of the NodeNetworkState + of a specific node + properties: + conditions: + items: + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + messageEncoded: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + currentState: + description: "State contains the namestatectl yaml [1] as string instead + of golang struct so we don't need to be in sync with the schema. + \n [1] https://github.com/nmstate/nmstate/blob/base/libnmstate/schemas/operational-state.yaml" + type: object + x-kubernetes-preserve-unknown-fields: true + handlerNetworkManagerVersion: + type: string + handlerNmstateVersion: + type: string + hostNetworkManagerVersion: + type: string + lastSuccessfulUpdateTime: + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 40bb3a1667..d5fc691a68 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -1,11 +1,14 @@ annotations: - operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.bundle.manifests.v1: manifests/ + # Core bundle annotations. operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.manifests.v1: manifests/ operators.operatorframework.io.bundle.metadata.v1: metadata/ - operators.operatorframework.io.bundle.package.v1: kubernetes-nmstate - operators.operatorframework.io.metrics.builder: operator-sdk-unknown + operators.operatorframework.io.bundle.package.v1: kubernetes-nmstate-operator + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.metrics.builder: operator-sdk-v1.13.0+git operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v2 - operators.operatorframework.io.test.config.v1: tests/scorecard/ + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 + + # Annotations for testing. operators.operatorframework.io.test.mediatype.v1: scorecard+v1 + operators.operatorframework.io.test.config.v1: tests/scorecard/ diff --git a/bundle/tests/scorecard/.gitkeep b/bundle/tests/scorecard/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cluster/sync.sh b/cluster/sync.sh index 83000b27aa..0ffe13c858 100755 --- a/cluster/sync.sh +++ b/cluster/sync.sh @@ -7,7 +7,7 @@ source ./cluster/sync-operator.sh kubectl=./cluster/kubectl.sh -nmstate_cr_manifest=deploy/crds/nmstate.io_v1_nmstate_cr.yaml +nmstate_cr_manifest=deploy/examples/nmstate.io_v1_nmstate_cr.yaml function deploy_handler() { $kubectl apply -f $nmstate_cr_manifest diff --git a/controllers/operator/nmstate_controller.go b/controllers/operator/nmstate_controller.go index 5a9bf69f30..602d8ac081 100644 --- a/controllers/operator/nmstate_controller.go +++ b/controllers/operator/nmstate_controller.go @@ -59,7 +59,7 @@ type NMStateReconciler struct { // +kubebuilder:rbac:groups=nmstate.io,resources="*",verbs="*" // +kubebuilder:rbac:groups=apiextensions.k8s.io,resources="*",verbs="*" // +kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;replicasets;statefulsets,verbs="*" -// +kubebuilder:rbac:groups="",resources=serviceaccounts;configmaps;namespaces;statefulsets,verbs="*" +// +kubebuilder:rbac:groups="",resources=serviceaccounts;configmaps;namespaces,verbs="*" func (r *NMStateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { _ = context.Background() diff --git a/deploy/bases/kubernetes-nmstate-operator.clusterserviceversion.yaml b/deploy/bases/kubernetes-nmstate-operator.clusterserviceversion.yaml new file mode 100644 index 0000000000..b7eac92ceb --- /dev/null +++ b/deploy/bases/kubernetes-nmstate-operator.clusterserviceversion.yaml @@ -0,0 +1,50 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + capabilities: Basic Install + categories: Networking + description: | + Kubernetes NMState is a declaritive means of configuring NetworkManager. + containerImage: quay.io/nmstate/kubernetes-nmstate-operator:latest + createdAt: "2021-11-24 16:05:00" + support: nmstate.io + repository: https://github.com/nmstate/kubernetes-nmstate + operatorframework.io/suggested-namespace: nmstate + operators.operatorframework.io/internal-objects: '["nodenetworkconfigurationenactments.nmstate.io", "nodenetworkstates.nmstate.io"]' + certified: "false" + name: kubernetes-nmstate-operator.v0.0.1 + namespace: placeholder +spec: + description: Kubernetes Nmstate description. + displayName: Kubernetes Nmstate + icon: + - base64data: >- + PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzkuNDcgMTMzLjg4Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6IzFkNTZkODt9LmNscy0ye2ZpbGw6IzcwYWRlZjt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkxheWVyXzIiIGRhdGEtbmFtZT0iTGF5ZXIgMiI+PGcgaWQ9IkxheWVyXzEtMiIgZGF0YS1uYW1lPSJMYXllciAxIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNy41MSwxMTMuNjhhNi41LDYuNSwwLDAsMC00LjMtMS4zMywxMS43LDExLjcsMCwwLDAtMy42MS41MUExMy42NywxMy42NywwLDAsMCw2LjksMTE0djE5YTUuMTgsNS4xOCwwLDAsMS0uNzYuMjMsNC40MSw0LjQxLDAsMCwxLTEuMTIuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE0LjI0YTMuMjMsMy4yMywwLDAsMSwuNDMtMS43Niw0LjU5LDQuNTksMCwwLDEsMS41LTEuMzUsMTUuMTgsMTUuMTgsMCwwLDEsMy41MS0xLjQ3LDE3LjExLDE3LjExLDAsMCwxLDQuOTQtLjY3LDExLjU2LDExLjU2LDAsMCwxLDcuMywyLjA5cTIuNjcsMi4wOCwyLjY3LDYuNTZ2MTUuNDJhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODNWMTE3Ljg1QTUuMDksNS4wOSwwLDAsMCwxNy41MSwxMTMuNjhaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNTkuMjEsMTEzLjUyYTUuODMsNS44MywwLDAsMC0zLjgyLTEuMTcsOC41Nyw4LjU3LDAsMCwwLTUuOSwyLjM0LDcuNzMsNy43MywwLDAsMSwuMywyLjE5djE2LjE4YTUuMiw1LjIsMCwwLDEtLjc4LjIzLDQuNDgsNC40OCwwLDAsMS0xLjEuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRhNC40OCw0LjQ4LDAsMCwwLTEuNDItMy42Nyw1LjkyLDUuOTIsMCwwLDAtMy44Ny0xLjE3LDkuMjYsOS4yNiwwLDAsMC0zLjA4LjUxQTExLjUxLDExLjUxLDAsMCwwLDM0Ljg5LDExNHYxOWE1LjM5LDUuMzksMCwwLDEtLjc3LjIzLDQuMzYsNC4zNiwwLDAsMS0xLjEyLjEzYy0xLjQ2LDAtMi4xOC0uNjEtMi4xOC0xLjgzVjExNC4yNGEzLjE1LDMuMTUsMCwwLDEsLjQzLTEuNzEsNSw1LDAsMCwxLDEuNS0xLjRBMTUuNzUsMTUuNzUsMCwwLDEsNDAuNDgsMTA5YTEyLjQzLDEyLjQzLDAsMCwxLDQuNDMuNzQsNi43Miw2LjcyLDAsMCwxLDMsMiwxMS4yOCwxMS4yOCwwLDAsMSwzLjMxLTJBMTIuMjksMTIuMjksMCwwLDEsNTUuNywxMDlhMTAuMjMsMTAuMjMsMCwwLDEsNi41NiwycTIuNDUsMiwyLjQ0LDZ2MTYuMDhhNSw1LDAsMCwxLS43OS4yMyw0LjQsNC40LDAsMCwxLTEuMDkuMTNxLTIuMTksMC0yLjE5LTEuODN2LTE0LjRBNC40OCw0LjQ4LDAsMCwwLDU5LjIxLDExMy41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik04OC45MiwxMjYuOTFBNiw2LDAsMCwxLDg2LjUzLDEzMnEtMi4zOSwxLjg0LTYuOTIsMS44NGExOCwxOCwwLDAsMS0zLjU2LS4zMywxMi41OCwxMi41OCwwLDAsMS0yLjc3LS44Nyw1LjU1LDUuNTUsMCwwLDEtMS43OC0xLjIyLDIsMiwwLDAsMS0uNjQtMS40LDIuMjUsMi4yNSwwLDAsMSwuMzMtMS4xNywyLjg4LDIuODgsMCwwLDEsMS0xLDE2LjMxLDE2LjMxLDAsMCwwLDMuMjEsMS44MSwxMC4zNywxMC4zNywwLDAsMCw0LjE3Ljc5cTUuMywwLDUuMjktMy41NmMwLTEuOTQtMS4xNy0zLjE5LTMuNTEtMy43N0w3Ny4xMiwxMjJhOS4xMyw5LjEzLDAsMCwxLTQuNTMtMi4zNyw1LjY1LDUuNjUsMCwwLDEtMS40Mi00LDYuMTksNi4xOSwwLDAsMSwuNTMtMi41NEE1Ljc1LDUuNzUsMCwwLDEsNzMuMzUsMTExYTguMzEsOC4zMSwwLDAsMSwyLjc4LTEuNDVBMTIuNTYsMTIuNTYsMCwwLDEsODAsMTA5LDEzLjQsMTMuNCwwLDAsMSw4NS43NywxMTBjMS40Ni42OSwyLjE5LDEuNSwyLjE5LDIuNDFhMi4wNiwyLjA2LDAsMCwxLTEuMjIsMS45NCwxNS43NywxNS43NywwLDAsMC0yLjYtMS4zMiwxMCwxMCwwLDAsMC00LS43Miw2LjY3LDYuNjcsMCwwLDAtMy42NC44NywyLjczLDIuNzMsMCwwLDAtMS4zNCwyLjQ0LDIuNzcsMi43NywwLDAsMCwuNzYsMiw0LjkxLDQuOTEsMCwwLDAsMi41NCwxLjIzbDMuNTEuODZhMTEuMDgsMTEuMDgsMCwwLDEsNS4xOSwyLjU3QTYuMTUsNi4xNSwwLDAsMSw4OC45MiwxMjYuOTFaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTAzLjEyLDEzMy44M2E5LjczLDkuNzMsMCwwLDEtNS43Ny0xLjU4cS0yLjIyLTEuNTgtMi4yMi01LjI0VjEwMi44NGE1LDUsMCwwLDEsLjc5LS4yMyw0LjY5LDQuNjksMCwwLDEsMS4xNC0uMTNjMS40MywwLDIuMTQuNjEsMi4xNCwxLjgzdjUuODVoOC4zNWE0LjI3LDQuMjcsMCwwLDEsLjMuNjksMi44NSwyLjg1LDAsMCwxLC4xNS45NGMwLDEuMTYtLjUsMS43My0xLjUyLDEuNzNIOTkuMnYxMy4yM2EzLjMyLDMuMzIsMCwwLDAsMS4xNSwyLjg4LDUuMzgsNS4zOCwwLDAsMCwzLjIzLjg0LDYuODgsNi44OCwwLDAsMCwxLjkzLS4zMSw3LjkzLDcuOTMsMCwwLDAsMS43OC0uNzEsMy4yNiwzLjI2LDAsMCwxLC41Ni43NiwyLjE3LDIuMTcsMCwwLDEsLjI2LDEuMDcsMi4wOCwyLjA4LDAsMCwxLTEuMzMsMS44M0E3LjcxLDcuNzEsMCwwLDEsMTAzLjEyLDEzMy44M1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjIuNjYsMTA5YTExLjMsMTEuMywwLDAsMSw3LDJxMi41OSwyLDIuNiw2LjI2VjEyOS4zYTIuODIsMi44MiwwLDAsMS0uNDQsMS43LDQuMzcsNC4zNywwLDAsMS0xLjI5LDEuMSwxMy4zMSwxMy4zMSwwLDAsMS0zLjIzLDEuMjQsMTcuOSwxNy45LDAsMCwxLTQuNjEuNTRxLTQuNzgsMC03LjQtMS44OWE2LjI3LDYuMjcsMCwwLDEtMi42Mi01LjQ0LDYsNiwwLDAsMSwyLjE4LTUuMDYsMTEuODEsMTEuODEsMCwwLDEsNi4xNi0yLjExbDcuMjMtLjcydi0xLjQyYTQuMzgsNC4zOCwwLDAsMC0xLjUzLTMuNzIsNi42MSw2LjYxLDAsMCwwLTQuMTItMS4xNywxMy4xMiwxMy4xMiwwLDAsMC00LC42MSwyMi4xMSwyMi4xMSwwLDAsMC0zLjM2LDEuMzgsNC44Niw0Ljg2LDAsMCwxLS43NC0uODIsMS42NywxLjY3LDAsMCwxLS4zMy0xLDEuODIsMS44MiwwLDAsMSwuMzYtMS4xNywzLjMsMy4zLDAsMCwxLDEuMTItLjg3LDEyLjQsMTIuNCwwLDAsMSwzLjE1LTEuMDlBMTguMTIsMTguMTIsMCwwLDEsMTIyLjY2LDEwOVptMCwyMS41M2ExMi41OCwxMi41OCwwLDAsMCwzLjU0LS40Myw4LjQ4LDguNDgsMCwwLDAsMi0uODR2LTcuMzhsLTYuMzEuNjZhNy44OSw3Ljg5LDAsMCwwLTMuOTIsMS4yLDMuMjEsMy4yMSwwLDAsMC0xLjI3LDIuNzcsMy40NCwzLjQ0LDAsMCwwLDEuNDcsM0E3Ljg2LDcuODYsMCwwLDAsMTIyLjcxLDEzMC41MloiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xNDcuNzQsMTMzLjgzYTkuNzUsOS43NSwwLDAsMS01Ljc3LTEuNThjLTEuNDgtMS4wNS0yLjIxLTIuOC0yLjIxLTUuMjRWMTAyLjg0YTQuODYsNC44NiwwLDAsMSwuNzgtLjIzLDQuNzEsNC43MSwwLDAsMSwxLjE1LS4xM2MxLjQyLDAsMi4xNC42MSwyLjE0LDEuODN2NS44NWg4LjM0YTQuMiw0LjIsMCwwLDEsLjMxLjY5LDIuODUsMi44NSwwLDAsMSwuMTUuOTRjMCwxLjE2LS41MSwxLjczLTEuNTMsMS43M2gtNy4yN3YxMy4yM2EzLjM1LDMuMzUsMCwwLDAsMS4xNCwyLjg4LDUuNCw1LjQsMCwwLDAsMy4yMy44NCw3LDcsMCwwLDAsMS45NC0uMzEsOC4xMyw4LjEzLDAsMCwwLDEuNzgtLjcxLDMuNTcsMy41NywwLDAsMSwuNTYuNzYsMi4xNywyLjE3LDAsMCwxLC4yNSwxLjA3LDIuMDgsMi4wOCwwLDAsMS0xLjMyLDEuODNBNy43Niw3Ljc2LDAsMCwxLDE0Ny43NCwxMzMuODNaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTYwLjc3LDEyMy44cTEuMzgsNi42Nyw4Ljc1LDYuNjdhMTAuMTUsMTAuMTUsMCwwLDAsMy44Ny0uNzEsMTEuNzEsMTEuNzEsMCwwLDAsMi43NS0xLjUzLDIuMTYsMi4xNiwwLDAsMSwxLjIyLDEuOTMsMiwyLDAsMCwxLS42NCwxLjM4LDUuNjksNS42OSwwLDAsMS0xLjczLDEuMTcsMTEuNDksMTEuNDksMCwwLDEtMi41NC44MSwxNS40NSwxNS40NSwwLDAsMS0zLjEzLjMxcS01LjkxLDAtOS4zNC0zLjIxdC0zLjQzLTkuMzZhMTQuNzksMTQuNzksMCwwLDEsLjg0LTUuMTcsMTEuMDcsMTEuMDcsMCwwLDEsMi4zNC0zLjg0LDEwLDEwLDAsMCwxLDMuNTktMi40MiwxMiwxMiwwLDAsMSw0LjUyLS44NCwxMS40MSwxMS40MSwwLDAsMSw0LjIzLjc3LDkuNjgsOS42OCwwLDAsMSwzLjMzLDIuMTYsMTAuMTcsMTAuMTcsMCwwLDEsMi4xOSwzLjMxLDExLDExLDAsMCwxLC43OSw0LjIsMi4xMywyLjEzLDAsMCwxLS41MSwxLjYsMi4zNywyLjM3LDAsMCwxLTEuNDMuNThabTctMTEuNWE2Ljc3LDYuNzcsMCwwLDAtNS4xNCwyLjE2LDkuMDYsOS4wNiwwLDAsMC0yLjEzLDYuMTlsMTQtMS45NGE3LjQ1LDcuNDUsMCwwLDAtMi00LjZBNi4yMSw2LjIxLDAsMCwwLDE2Ny43OSwxMTIuM1oiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik02Ni45MiwxMy4xM3Y5LjM5YzEuMjctLjA5LDIuNTQtLjE2LDMuODMtLjJWMTEuMzloLS4zM2E4My4yOSw4My4yOSwwLDAsMSwzMy4yNC03LjU0VjI3LjEyYzEuMy40NCwyLjU3LjkxLDMuODMsMS40VjMuODVBODMsODMsMCwwLDEsMTQxLjk0LDEyVjU1Ljc3aDMuODNWMTRjMTYuOCw5LjQyLDI4LjIsMjQuNTksMjkuNjgsNDEuODloMy44NEMxNzYuODMsMjQuNzMsMTQ0LjcxLDAsMTA1LjU4LDBjLTI2LDAtNDguODQsMTAuODktNjIsMjcuMzEsMi4yNy0uNzksNC42LTEuNDksNy0yLjExQTY3LjI4LDY3LjI4LDAsMCwxLDY2LjkyLDEzLjEzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTE0NC42OSw1OS42MWE1My44NCw1My44NCwwLDAsMSw2Ljc5LDIyLjY5bDI4LTIyLjZaIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMTQ3LjgxLDg0LjMzYTUwLjM5LDUwLjM5LDAsMCwwLTcuNTQtMjQuNzNjLTctMTEuNTktMTguNTgtMjEuMDgtMzIuNzgtMjctMS4yNS0uNTItMi41My0xLTMuODMtMS40OEE4OC42LDg4LjYsMCwwLDAsNzMuOSwyNi4wOWMtMS4wNSwwLTIuMTEsMC0zLjE1LjA2LTEuMjksMC0yLjU2LjExLTMuODMuMjFhODcuNTgsODcuNTgsMCwwLDAtMjEuMDgsNC4yMWMtMi4xNS43Mi00LjI0LDEuNTEtNi4yOSwyLjM4QzE2LjU4LDQyLjc1LjY3LDYyLjA1LDAsODQuMzN2MS4yNWMwLDEuMjIuNywxLjgzLDIuMDksMS44M2E0LDQsMCwwLDAsMS4wNy0uMTMsNC41OCw0LjU4LDAsMCwwLC43My0uMjNWODQuMzNoMGMwLS40NywwLS45My4wNi0xLjQuMDktMS40My4yNS0yLjg0LjQ3LTQuMjRhNDUuNzQsNDUuNzQsMCwwLDEsMS42NS02Ljg0QzYuNSw3MC41MSw3LDY5LjIsNy41NCw2Ny45Yy4zNy0uODcuNzctMS43MiwxLjE4LTIuNTdhNTIuNzksNTIuNzksMCwwLDEsMi44MS00Ljk1LDU1LjYxLDU1LjYxLDAsMCwxLDUuMjctNi45MWMuMzItLjM2LjY2LS43MiwxLTEuMDgsMS0xLjA4LDIuMDctMi4xMiwzLjE3LTMuMTRzMi4yNS0yLDMuNDQtMi45NHEyLjM3LTEuOTEsNS0zLjYxYy44Ny0uNTcsMS43NS0xLjEzLDIuNjUtMS42Ni40NS0uMjcuOS0uNTQsMS4zNi0uOGwxLjg2LTF2NDUuMWgwdjEuMjVjMCwxLjIyLjY5LDEuODMsMi4wOSwxLjgzYTQsNCwwLDAsMCwxLjA3LS4xMyw1LjM5LDUuMzksMCwwLDAsLjczLS4yM1Y4NC4zM2gwbDAtMjVWMzcuNDloLS4zM2wxLjgtLjgyYy41My0uMjMsMS4wOC0uNDQsMS42Mi0uNjZzLjkzLS4zOSwxLjQtLjU3cTIuMy0uODgsNC42OC0xLjY0YTg0LjY2LDg0LjY2LDAsMCwxLDE4LjY4LTMuNTljMS4yNy0uMSwyLjU0LS4xNywzLjgzLS4yMmwxLjI0LDBWNTkuNDJsLS4wNiwyNC45MWgwdjEuMjVjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDUsNSwwLDAsMCwuNzMtLjIzVjg0LjMzaDBWMjkuOTRBODUuMDUsODUuMDUsMCwwLDEsOTkuNTYsMzMuOGMxLjM5LjQ0LDIuNzYuOTIsNC4xLDEuNDMuMi4wNy4zOS4xMy41OC4yMSwxLC4zOSwyLC44LDMsMS4yM2wuMjMuMTFjLjkxLjQsMS44Mi44MSwyLjcxLDEuMjRsLjA3LDBWODQuMzNoMHYxLjI1YS4yMi4yMiwwLDAsMCwwLC4wOHYuMTRoMGMuMDgsMS4wNy43NywxLjYxLDIuMDcsMS42MWE0LDQsMCwwLDAsMS4wNy0uMTMsNSw1LDAsMCwwLC43My0uMjNWODQuMzNoMGwtLjA2LTI0LjhWNDAuMDZsLjMzLjE4LDEuMzcuOGMuODkuNTMsMS43OCwxLjA5LDIuNjQsMS42NnEyLjU5LDEuNzEsNSwzLjYxYzEuMTkuOTQsMi4zMywxLjkzLDMuNDQsMi45NFMxMjksNTEuMzEsMTMwLDUyLjM5bDEsMS4wOGE1NS4wNiw1NS4wNiwwLDAsMSw0Ljc0LDYuMTJsLjUyLjc5YTUwLjY0LDUwLjY0LDAsMCwxLDIuODEsNC45NWMuNDIuODUuODEsMS43LDEuMTgsMi41Ny41NSwxLjMsMS4wNSwyLjYxLDEuNDgsMy45NWE0NS43MSw0NS43MSwwLDAsMSwxLjY0LDYuODQsNDIuNjIsNDIuNjIsMCwwLDEsLjQ4LDQuMjRjMCwuNjEsMCwxLjIzLjA2LDEuODV2LjhjMCwxLjIyLjcsMS44MywyLjA5LDEuODNhNCw0LDAsMCwwLDEuMDctLjEzLDQuNTgsNC41OCwwLDAsMCwuNzMtLjIzVjg0LjMzWiIvPjwvZz48L2c+PC9zdmc+ + mediatype: image/svg+xml + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: false + type: AllNamespaces + keywords: + - nmstate + - networking + - NetworkManager + links: + - name: Kubernetes Nmstate Operator + url: https://github.com/nmstate/kubernetes-nmstate + maintainers: + - email: brad@redhat.com + name: Brad P. Crochet + maturity: alpha + provider: + name: NMState + selector: + matchLabels: + name: kubernetes-nmstate-operator + version: 0.0.1 diff --git a/deploy/crds/nmstate.io_v1beta1_nodenetworkconfigurationenactment_cr.yaml b/deploy/crds/nmstate.io_v1beta1_nodenetworkconfigurationenactment_cr.yaml deleted file mode 100644 index 86f30e99c2..0000000000 --- a/deploy/crds/nmstate.io_v1beta1_nodenetworkconfigurationenactment_cr.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: nmstate.io/v1beta1 -kind: NodeNetworkConfigurationEnactment -metadata: - creationTimestamp: "2019-12-04T10:55:12Z" - generation: 1 - name: node01.test-policy - ownerReferences: - - apiVersion: nmstate.io/v1 - kind: NodeNetworkConfigurationPolicy - name: test-policy - uid: d7e35a96-6094-4b2e-a899-9ee6a5eef157 - resourceVersion: "4682" - selfLink: /apis/nmstate.io/v1beta1/nodenetworkconfigurationenactments/node01.test-policy - uid: 2f255a93-c2b5-43a5-a401-7184150fa9f1 -status: - conditions: - - lastHearbeatTime: "2019-12-04T10:55:32Z" - lastTransitionTime: "2019-12-04T10:55:32Z" - reason: SuccessfullyConfigured - status: "False" - type: Progressing - - lastHearbeatTime: "2019-12-04T10:55:32Z" - lastTransitionTime: "2019-12-04T10:55:32Z" - reason: SuccessfullyConfigured - status: "False" - type: Failing - - lastHearbeatTime: "2019-12-04T10:55:32Z" - lastTransitionTime: "2019-12-04T10:55:32Z" - message: successfully reconciled - reason: SuccessfullyConfigured - status: "True" - type: Available diff --git a/deploy/crds/nmstate.io_v1beta1_nodenetworkstate_cr.yaml b/deploy/crds/nmstate.io_v1beta1_nodenetworkstate_cr.yaml deleted file mode 100644 index c667c505e1..0000000000 --- a/deploy/crds/nmstate.io_v1beta1_nodenetworkstate_cr.yaml +++ /dev/null @@ -1,188 +0,0 @@ -apiVersion: nmstate.io/v1beta1 -kind: NodeNetworkState -metadata: - creationTimestamp: "2019-12-03T08:31:04Z" - generation: 1 - name: node01 - ownerReferences: - - apiVersion: v1 - kind: Node - name: node01 - uid: d3c4563b-ece3-49a3-b0b6-81d12b112e89 - resourceVersion: "728" - selfLink: /apis/nmstate.io/v1beta1/nodenetworkstates/node01 - uid: d8b24483-3162-44ce-a335-666844569562 -status: - currentState: - dns-resolver: - config: - search: [] - server: [] - running: - search: [] - server: - - 192.168.66.2 - interfaces: - - bridge: - options: - group-forward-mask: 0 - mac-ageing-time: 300 - multicast-snooping: true - stp: - enabled: false - forward-delay: 15 - hello-time: 2 - max-age: 20 - priority: 32768 - port: [] - ipv4: - address: - - ip: 10.244.0.1 - prefix-length: 24 - dhcp: false - enabled: true - ipv6: - address: - - ip: fe80::5ccc:abff:fe0a:db1e - prefix-length: 64 - autoconf: false - dhcp: false - enabled: true - mac-address: 5E:CC:AB:0A:DB:1E - mtu: 1450 - name: cni0 - state: up - type: linux-bridge - - bridge: - options: - group-forward-mask: 0 - mac-ageing-time: 300 - multicast-snooping: true - stp: - enabled: false - forward-delay: 15 - hello-time: 2 - max-age: 20 - priority: 32768 - port: [] - ipv4: - address: - - ip: 172.17.0.1 - prefix-length: 16 - dhcp: false - enabled: true - ipv6: - autoconf: false - dhcp: false - enabled: false - mac-address: 02:42:DD:B5:49:60 - mtu: 1500 - name: docker0 - state: up - type: linux-bridge - - ipv4: - address: - - ip: 192.168.66.101 - prefix-length: 24 - auto-dns: true - auto-gateway: true - auto-routes: true - dhcp: true - enabled: true - ipv6: - address: - - ip: fe80::5055:ff:fed1:5501 - prefix-length: 64 - autoconf: false - dhcp: false - enabled: true - mac-address: 52:55:00:D1:55:01 - mtu: 1500 - name: eth0 - state: up - type: ethernet - - ipv4: - enabled: false - ipv6: - enabled: false - mac-address: 52:55:00:D1:56:00 - mtu: 1500 - name: eth1 - state: down - type: ethernet - - ipv4: - enabled: false - ipv6: - enabled: false - mac-address: 52:55:00:D1:56:01 - mtu: 1500 - name: eth2 - state: down - type: ethernet - - ipv4: - enabled: false - ipv6: - enabled: false - mac-address: 8A:58:1B:E1:ED:CA - mtu: 1450 - name: flannel.1 - state: down - type: vxlan - vxlan: - base-iface: eth0 - destination-port: 8472 - id: 1 - remote: "" - - ipv4: - enabled: false - ipv6: - enabled: false - mtu: 65536 - name: lo - state: down - type: unknown - route-rules: - config: [] - routes: - config: [] - running: - - destination: 10.244.0.0/24 - metric: 0 - next-hop-address: "" - next-hop-interface: cni0 - table-id: 254 - - destination: 172.17.0.0/16 - metric: 0 - next-hop-address: "" - next-hop-interface: docker0 - table-id: 254 - - destination: 0.0.0.0/0 - metric: 100 - next-hop-address: 192.168.66.2 - next-hop-interface: eth0 - table-id: 254 - - destination: 192.168.66.0/24 - metric: 100 - next-hop-address: "" - next-hop-interface: eth0 - table-id: 254 - - destination: fe80::/64 - metric: 256 - next-hop-address: "" - next-hop-interface: cni0 - table-id: 254 - - destination: fe80::/64 - metric: 100 - next-hop-address: "" - next-hop-interface: eth0 - table-id: 254 - - destination: ff00::/8 - metric: 256 - next-hop-address: "" - next-hop-interface: cni0 - table-id: 255 - - destination: ff00::/8 - metric: 256 - next-hop-address: "" - next-hop-interface: eth0 - table-id: 255 diff --git a/deploy/crds/nmstate.io_v1_nmstate_cr.yaml b/deploy/examples/nmstate.io_v1_nmstate_cr.yaml similarity index 100% rename from deploy/crds/nmstate.io_v1_nmstate_cr.yaml rename to deploy/examples/nmstate.io_v1_nmstate_cr.yaml diff --git a/deploy/crds/nmstate.io_v1_nodenetworkconfigurationpolicy_cr.yaml b/deploy/examples/nmstate.io_v1_nodenetworkconfigurationpolicy_cr.yaml similarity index 100% rename from deploy/crds/nmstate.io_v1_nodenetworkconfigurationpolicy_cr.yaml rename to deploy/examples/nmstate.io_v1_nodenetworkconfigurationpolicy_cr.yaml diff --git a/deploy/operator/role.yaml b/deploy/operator/role.yaml index 1fc938f804..4dc3c06bf4 100644 --- a/deploy/operator/role.yaml +++ b/deploy/operator/role.yaml @@ -12,7 +12,6 @@ rules: - configmaps - namespaces - serviceaccounts - - statefulsets verbs: - '*' - apiGroups: diff --git a/hack/render-manifests.go b/hack/render-manifests.go index 72aebfb4e5..748142ff5b 100644 --- a/hack/render-manifests.go +++ b/hack/render-manifests.go @@ -66,6 +66,11 @@ func main() { exitWithError(err, "failed parsing top dir operator manifests at %s", *inputDir) } + tmpl, err = tmpl.ParseGlob(path.Join(*inputDir, "examples/*.yaml")) + if err != nil { + exitWithError(err, "failed parsing sub dir example manifests at %s", *inputDir) + } + tmpl, err = tmpl.ParseGlob(path.Join(*inputDir, "openshift/*.yaml")) if err != nil { exitWithError(err, "failed parsing sub dir openshift manifests at %s", *inputDir)