├── .dockerignore ├── .gitignore ├── .golangci.yml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── OWNERS ├── README.md ├── RELEASE.md ├── SECURITY.md ├── SECURITY_CONTACTS ├── apis └── v1alpha1 │ ├── clusterprofile_types.go │ ├── groupversion_info.go │ └── zz_generated.deepcopy.go ├── client ├── clientset │ └── versioned │ │ ├── clientset.go │ │ ├── fake │ │ ├── clientset_generated.go │ │ ├── doc.go │ │ └── register.go │ │ ├── scheme │ │ ├── doc.go │ │ └── register.go │ │ └── typed │ │ └── apis │ │ └── v1alpha1 │ │ ├── apis_client.go │ │ ├── clusterprofile.go │ │ ├── doc.go │ │ ├── fake │ │ ├── doc.go │ │ ├── fake_apis_client.go │ │ └── fake_clusterprofile.go │ │ └── generated_expansion.go ├── informers │ └── externalversions │ │ ├── apis │ │ ├── interface.go │ │ └── v1alpha1 │ │ │ ├── clusterprofile.go │ │ │ └── interface.go │ │ ├── factory.go │ │ ├── generic.go │ │ └── internalinterfaces │ │ └── factory_interfaces.go └── listers │ └── apis │ └── v1alpha1 │ ├── clusterprofile.go │ └── expansion_generated.go ├── code-of-conduct.md ├── config └── crd │ └── bases │ └── multicluster.x-k8s.io_clusterprofiles.yaml ├── go.mod ├── go.sum ├── hack ├── boilerplate.go.txt ├── tools.go └── update-codegen.sh └── test └── integration ├── clusterprofile_test.go └── suite_test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file 2 | # Ignore build and test binaries. 3 | bin/ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | bin/* 8 | Dockerfile.cross 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Go workspace file 17 | go.work 18 | 19 | # Kubernetes Generated files - skip generated files, except for vendored files 20 | !vendor/**/zz_generated.* 21 | 22 | # editor and IDE paraphernalia 23 | .idea 24 | .vscode 25 | *.swp 26 | *.swo 27 | *~ 28 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | allow-parallel-runners: true 3 | 4 | issues: 5 | # don't skip warning about doc comments 6 | # don't exclude the default set of lint 7 | exclude-use-default: false 8 | # restore some of the defaults 9 | # (fill in the rest as needed) 10 | exclude-rules: 11 | - path: "api/*" 12 | linters: 13 | - lll 14 | - path: "internal/*" 15 | linters: 16 | - dupl 17 | - lll 18 | linters: 19 | disable-all: true 20 | enable: 21 | - dupl 22 | - errcheck 23 | - exportloopref 24 | - goconst 25 | - gocyclo 26 | - gofmt 27 | - goimports 28 | - gosimple 29 | - govet 30 | - ineffassign 31 | - lll 32 | - misspell 33 | - nakedret 34 | - prealloc 35 | - staticcheck 36 | - typecheck 37 | - unconvert 38 | - unparam 39 | - unused 40 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt: 4 | 5 | _As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._ 6 | 7 | ## Getting Started 8 | 9 | We have full documentation on how to get started contributing here: 10 | 11 | 14 | 15 | - [Contributor License Agreement](https://git.k8s.io/community/CLA.md) - Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests 16 | - [Kubernetes Contributor Guide](https://k8s.dev/guide) - Main contributor documentation, or you can just jump directly to the [contributing page](https://k8s.dev/docs/guide/contributing/) 17 | - [Contributor Cheat Sheet](https://k8s.dev/cheatsheet) - Common resources for existing developers 18 | 19 | ## Mentorship 20 | 21 | - [Mentoring Initiatives](https://k8s.dev/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers! 22 | 23 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Image URL to use all building/pushing image targets 2 | IMG ?= controller:latest 3 | # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. 4 | ENVTEST_K8S_VERSION = 1.31.0 5 | 6 | # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) 7 | ifeq (,$(shell go env GOBIN)) 8 | GOBIN=$(shell go env GOPATH)/bin 9 | else 10 | GOBIN=$(shell go env GOBIN) 11 | endif 12 | GOHOSTOS ?=$(shell go env GOHOSTOS) 13 | GOHOSTARCH ?=$(shell go env GOHOSTARCH) 14 | 15 | # CONTAINER_TOOL defines the container tool to be used for building images. 16 | # Be aware that the target commands are only tested with Docker which is 17 | # scaffolded by default. However, you might want to replace it to use other 18 | # tools. (i.e. podman) 19 | CONTAINER_TOOL ?= docker 20 | 21 | # Setting SHELL to bash allows bash commands to be executed by recipes. 22 | # Options are set to exit when a recipe line exits non-zero or a piped command fails. 23 | SHELL = /usr/bin/env bash -o pipefail 24 | .SHELLFLAGS = -ec 25 | 26 | .PHONY: all 27 | all: build 28 | 29 | ##@ General 30 | 31 | # The help target prints out all targets with their descriptions organized 32 | # beneath their categories. The categories are represented by '##@' and the 33 | # target descriptions by '##'. The awk command is responsible for reading the 34 | # entire set of makefiles included in this invocation, looking for lines of the 35 | # file as xyz: ## something, and then pretty-format the target and help. Then, 36 | # if there's a line with ##@ something, that gets pretty-printed as a category. 37 | # More info on the usage of ANSI control characters for terminal formatting: 38 | # https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters 39 | # More info on the awk command: 40 | # http://linuxcommand.org/lc3_adv_awk.php 41 | 42 | .PHONY: help 43 | help: ## Display this help. 44 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 45 | 46 | ##@ Development 47 | 48 | .PHONY: manifests 49 | manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. 50 | $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases 51 | 52 | .PHONY: generate 53 | generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. 54 | $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." 55 | hack/update-codegen.sh 56 | 57 | .PHONY: fmt 58 | fmt: ## Run go fmt against code. 59 | go fmt ./... 60 | 61 | .PHONY: vet 62 | vet: ## Run go vet against code. 63 | go vet ./... 64 | 65 | .PHONY: test 66 | test: manifests generate fmt vet envtest ensure-kubebuilder-tools ## Run tests. 67 | KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out 68 | 69 | # Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors. 70 | .PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up. 71 | test-e2e: 72 | go test ./test/e2e/ -v -ginkgo.v 73 | 74 | .PHONY: lint 75 | lint: golangci-lint ## Run golangci-lint linter & yamllint 76 | $(GOLANGCI_LINT) run 77 | 78 | .PHONY: lint-fix 79 | lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes 80 | $(GOLANGCI_LINT) run --fix 81 | 82 | ##@ Build 83 | 84 | .PHONY: build 85 | build: manifests generate fmt vet ## Build manager binary. 86 | go build -o bin/manager cmd/main.go 87 | 88 | .PHONY: run 89 | run: manifests generate fmt vet ## Run a controller from your host. 90 | go run ./cmd/main.go 91 | 92 | # If you wish to build the manager image targeting other platforms you can use the --platform flag. 93 | # (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. 94 | # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ 95 | .PHONY: docker-build 96 | docker-build: ## Build docker image with the manager. 97 | $(CONTAINER_TOOL) build -t ${IMG} . 98 | 99 | .PHONY: docker-push 100 | docker-push: ## Push docker image with the manager. 101 | $(CONTAINER_TOOL) push ${IMG} 102 | 103 | # PLATFORMS defines the target platforms for the manager image be built to provide support to multiple 104 | # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: 105 | # - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ 106 | # - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ 107 | # - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) 108 | # To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. 109 | PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le 110 | .PHONY: docker-buildx 111 | docker-buildx: ## Build and push docker image for the manager for cross-platform support 112 | # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile 113 | sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross 114 | - $(CONTAINER_TOOL) buildx create --name project-v3-builder 115 | $(CONTAINER_TOOL) buildx use project-v3-builder 116 | - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . 117 | - $(CONTAINER_TOOL) buildx rm project-v3-builder 118 | rm Dockerfile.cross 119 | 120 | .PHONY: build-installer 121 | build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. 122 | mkdir -p dist 123 | cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} 124 | $(KUSTOMIZE) build config/default > dist/install.yaml 125 | 126 | ##@ Deployment 127 | 128 | ifndef ignore-not-found 129 | ignore-not-found = false 130 | endif 131 | 132 | .PHONY: install 133 | install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. 134 | $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - 135 | 136 | .PHONY: uninstall 137 | uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. 138 | $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - 139 | 140 | .PHONY: deploy 141 | deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. 142 | cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} 143 | $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - 144 | 145 | .PHONY: undeploy 146 | undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. 147 | $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - 148 | 149 | ##@ Dependencies 150 | 151 | ## Location to install dependencies to 152 | LOCALBIN ?= $(shell pwd)/bin 153 | $(LOCALBIN): 154 | mkdir -p $(LOCALBIN) 155 | 156 | ## Tool Binaries 157 | KUBECTL ?= kubectl 158 | KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION) 159 | CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION) 160 | ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION) 161 | GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION) 162 | 163 | ## Tool Versions 164 | KUSTOMIZE_VERSION ?= v5.3.0 165 | CONTROLLER_TOOLS_VERSION ?= v0.14.0 166 | ENVTEST_VERSION ?= release-0.17 167 | GOLANGCI_LINT_VERSION ?= v1.54.2 168 | KB_TOOLS_ARCHIVE_NAME :=kubebuilder-tools-$(ENVTEST_K8S_VERSION)-$(GOHOSTOS)-$(GOHOSTARCH).tar.gz 169 | KB_TOOLS_ARCHIVE_PATH := /tmp/$(KB_TOOLS_ARCHIVE_NAME) 170 | export KUBEBUILDER_ASSETS ?=/tmp/kubebuilder/bin 171 | 172 | .PHONY: kustomize 173 | kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. 174 | $(KUSTOMIZE): $(LOCALBIN) 175 | $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) 176 | 177 | .PHONY: controller-gen 178 | controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. 179 | $(CONTROLLER_GEN): $(LOCALBIN) 180 | $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) 181 | 182 | .PHONY: envtest 183 | envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. 184 | $(ENVTEST): $(LOCALBIN) 185 | $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) 186 | 187 | .PHONY: golangci-lint 188 | golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. 189 | $(GOLANGCI_LINT): $(LOCALBIN) 190 | $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION}) 191 | 192 | # download the kubebuilder-tools to get kube-apiserver binaries from it 193 | .PHONY: ensure-kubebuilder-tools 194 | ensure-kubebuilder-tools: 195 | ifeq "" "$(wildcard $(KUBEBUILDER_ASSETS))" 196 | $(info Downloading kube-apiserver into '$(KUBEBUILDER_ASSETS)') 197 | mkdir -p '$(KUBEBUILDER_ASSETS)' 198 | curl -s -f -L https://storage.googleapis.com/kubebuilder-tools/$(KB_TOOLS_ARCHIVE_NAME) -o '$(KB_TOOLS_ARCHIVE_PATH)' 199 | tar -C '$(KUBEBUILDER_ASSETS)' --strip-components=2 -zvxf '$(KB_TOOLS_ARCHIVE_PATH)' 200 | else 201 | $(info Using existing kube-apiserver from "$(KUBEBUILDER_ASSETS)") 202 | endif 203 | 204 | # go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist 205 | # $1 - target path with name of binary (ideally with version) 206 | # $2 - package url which can be installed 207 | # $3 - specific version of package 208 | define go-install-tool 209 | @[ -f $(1) ] || { \ 210 | set -e; \ 211 | package=$(2)@$(3) ;\ 212 | echo "Downloading $${package}" ;\ 213 | GOBIN=$(LOCALBIN) go install $${package} ;\ 214 | mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\ 215 | } 216 | endef 217 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://go.k8s.io/owners 2 | 3 | approvers: 4 | - dixudx 5 | - mikeshng 6 | - RainbowMango 7 | - ryanzhang-oss 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cluster Inventory API 2 | 3 | The Cluster Inventory API is a part of [SIG Multicluster](https://github.com/kubernetes/community/tree/master/sig-multicluster), 4 | and this repository serves as the foundation for developing a standardized, 5 | robust framework for multi-cluster management in a cloud-native environment. 6 | 7 | The Cluster Inventory API aims to provide a consistent and automated approach for applications, 8 | frameworks, and toolsets to discover and interact with multiple Kubernetes clusters. 9 | The concept of Cluster Inventory is akin to service discovery in a microservices architecture. 10 | It allows multi-cluster applications to dynamically discover available clusters and respond to various cluster lifecycle events. 11 | Such events include auto-scaling, upgrades, failures, and connectivity issues. 12 | This automated inventory management not only facilitates operational efficiency 13 | but also supports the integration of diverse multi-cluster management solutions. 14 | See the initial proposal in the [documentation](https://docs.google.com/document/d/1sUWbe81BTclQ4Uax3flnCoKtEWngH-JA9MyCqljJCBM/) 15 | for more details. 16 | 17 | ## Cluster Profile API 18 | 19 | Within the broader Cluster Inventory, the first major component we are introducing is the 20 | [ClusterProfile API](https://github.com/kubernetes/enhancements/blob/master/keps/sig-multicluster/4322-cluster-inventory/README.md). 21 | A Cluster Profile is essentially an individual member of the Cluster Inventory that details the properties and status of a cluster. 22 | This API proposes a universal, standardized interface that defines how cluster information should be presented 23 | and interacted with across different platforms and implementations. 24 | 25 | ### Motivation and Goals 26 | 27 | The `ClusterProfile API` is designed to establish a shared interface for cluster inventory, 28 | laying the groundwork for multi-cluster tooling by providing a foundational component. 29 | Here are several key benefits and purposes of adopting the ClusterProfile API: 30 | 31 | - **Standardization**: By defining a standard for status reporting and cluster properties, 32 | the API facilitates a common understanding that can be shared across various tools and platforms. 33 | - **Ease of Integration**: Consumers of the API, such as multi-cluster workload schedulers and GitOps tools (e.g., ArgoCD, Kueue), 34 | can integrate without needing to navigate the specific implementation details of different cluster management projects. 35 | - **Vendor Neutrality**: The API provides a vendor-neutral integration point, 36 | allowing operations tools and external consumers to define and manage clusters across different cloud environments uniformly. 37 | 38 | ## Community, discussion, contribution, and support 39 | 40 | Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). 41 | 42 | You can reach the maintainers of this project at: 43 | 44 | - [Slack](https://kubernetes.slack.com/messages/sig-multicluster) 45 | - [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-multicluster) 46 | - [SIG Multicluster](https://github.com/kubernetes/community/blob/master/sig-multicluster/README.md) 47 | 48 | ### Code of conduct 49 | 50 | Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). 51 | 52 | [owners]: https://git.k8s.io/community/contributors/guide/owners.md 53 | [Creative Commons 4.0]: https://git.k8s.io/website/LICENSE 54 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release Process 2 | 3 | The Kubernetes Template Project is released on an as-needed basis. The process is as follows: 4 | 5 | 1. An issue is proposing a new release with a changelog since the last release 6 | 1. All [OWNERS](OWNERS) must LGTM this release 7 | 1. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION` 8 | 1. The release issue is closed 9 | 1. An announcement email is sent to `dev@kubernetes.io` with the subject `[ANNOUNCE] kubernetes-template-project $VERSION is released` 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Security Announcements 4 | 5 | Join the [kubernetes-security-announce] group for security and vulnerability announcements. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Instructions for reporting a vulnerability can be found on the 10 | [Kubernetes Security and Disclosure Information] page. 11 | 12 | ## Supported Versions 13 | 14 | Information about supported Kubernetes versions can be found on the 15 | [Kubernetes version and version skew support policy] page on the Kubernetes website. 16 | 17 | [kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce 18 | [Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions 19 | [Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability 20 | -------------------------------------------------------------------------------- /SECURITY_CONTACTS: -------------------------------------------------------------------------------- 1 | # Defined below are the security contacts for this repo. 2 | # 3 | # They are the contact point for the Security Response Committee to reach out 4 | # to for triaging and handling of incoming issues. 5 | # 6 | # The below names agree to abide by the 7 | # [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) 8 | # and will be removed and replaced if they violate that agreement. 9 | # 10 | # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE 11 | # INSTRUCTIONS AT https://kubernetes.io/security/ 12 | 13 | dixudx 14 | mikeshng 15 | RainbowMango 16 | 17 | -------------------------------------------------------------------------------- /apis/v1alpha1/clusterprofile_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // ClusterProfileSpec defines the desired state of ClusterProfile. 24 | type ClusterProfileSpec struct { 25 | // DisplayName defines a human-readable name of the ClusterProfile 26 | // +optional 27 | DisplayName string `json:"displayName,omitempty"` 28 | 29 | // ClusterManager defines which cluster manager owns this ClusterProfile resource 30 | // +required 31 | ClusterManager ClusterManager `json:"clusterManager"` 32 | } 33 | 34 | // ClusterManager defines which cluster manager owns this ClusterProfile resource. 35 | // A cluster manager is a system that centralizes the administration, coordination, 36 | // and operation of multiple clusters across various infrastructures. 37 | // Examples of cluster managers include Open Cluster Management, AZ Fleet, Karmada, and Clusternet. 38 | // 39 | // This field is immutable. 40 | // It's recommended that each cluster manager instance should set a different values to this field. 41 | // In addition, it's recommended that a predefined label with key "x-k8s.io/cluster-manager" 42 | // should be added by the cluster manager upon creation. See constant LabelClusterManagerKey. 43 | // The value of the label should be the same as the name of the cluster manager. 44 | // The purpose of this label is to make filter clusters from different cluster managers easier. 45 | // 46 | // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ClusterManager is immutable" 47 | type ClusterManager struct { 48 | // Name defines the name of the cluster manager 49 | // +required 50 | Name string `json:"name"` 51 | } 52 | 53 | // ClusterProfileStatus defines the observed state of ClusterProfile. 54 | type ClusterProfileStatus struct { 55 | // Conditions contains the different condition statuses for this cluster. 56 | // +optional 57 | Conditions []metav1.Condition `json:"conditions"` 58 | 59 | // Version defines the version information of the cluster. 60 | // +optional 61 | Version ClusterVersion `json:"version,omitempty"` 62 | 63 | // Properties defines cluster characteristics through a list of Property objects. 64 | // Each Property can be one of: 65 | // 1. A ClusterProperty resource (as defined in KEP-2149) 66 | // 2. Custom information from cluster manager implementations 67 | // Property names support both: 68 | // - Standard names from ClusterProperty resources 69 | // - Custom names defined by cluster managers 70 | // +optional 71 | Properties []Property `json:"properties,omitempty"` 72 | } 73 | 74 | // ClusterVersion represents version information about the cluster. 75 | type ClusterVersion struct { 76 | // Kubernetes is the kubernetes version of the cluster. 77 | // +optional 78 | Kubernetes string `json:"kubernetes,omitempty"` 79 | } 80 | 81 | // Property defines the data structure to represent a property of a cluster. 82 | // It contains a name/value pair and the last observed time of the property on the cluster. 83 | // This property can store various configurable details and metrics of a cluster, 84 | // which may include information such as the entry point of the cluster, types of nodes, location, etc. according to KEP 4322. 85 | type Property struct { 86 | // Name is the name of a property resource on cluster. It's a well-known 87 | // or customized name to identify the property. 88 | // +kubebuilder:validation:MaxLength=253 89 | // +kubebuilder:validation:MinLength=1 90 | // +required 91 | Name string `json:"name"` 92 | 93 | // Value is a property-dependent string 94 | // +kubebuilder:validation:MaxLength=1024 95 | // +kubebuilder:validation:MinLength=1 96 | // +required 97 | Value string `json:"value"` 98 | 99 | // LastObservedTime is the last time the property was observed on the corresponding cluster. 100 | // The value is the timestamp when the property was observed not the time when the property was updated in the cluster-profile. 101 | // +kubebuilder:validation:Type=string 102 | // +kubebuilder:validation:Format=date-time 103 | // +optional 104 | LastObservedTime metav1.Time `json:"lastObservedTime,omitempty"` 105 | } 106 | 107 | // Predefined healthy conditions indicate the cluster is in a good state or not. 108 | // The condition and states conforms to metav1.Condition format. 109 | // States are True/False/Unknown. 110 | const ( 111 | // ClusterConditionControlPlaneHealthy means the controlplane of the cluster is in a healthy state. 112 | // If the control plane is not healthy, then the status condition will be "False". 113 | ClusterConditionControlPlaneHealthy string = "ControlPlaneHealthy" 114 | ) 115 | 116 | const ( 117 | // LabelClusterManagerKey is used to indicate the name of the cluster manager that a ClusterProfile belongs to. 118 | // The value of the label MUST be the same as the name of the cluster manager. 119 | // The purpose of this label is to make filter clusters from different cluster managers easier. 120 | LabelClusterManagerKey = "x-k8s.io/cluster-manager" 121 | 122 | // LabelClusterSetKey is used on a namespace to indicate the clusterset that a ClusterProfile belongs to. 123 | // If a cluster inventory represents a ClusterSet, 124 | // all its ClusterProfile objects MUST be part of the same clusterSet and namespace must be used as the grouping mechanism. 125 | // The namespace MUST have LabelClusterSet and the value as the name of the clusterSet. 126 | LabelClusterSetKey = "multicluster.x-k8s.io/clusterset" 127 | ) 128 | 129 | //+genclient 130 | //+kubebuilder:object:root=true 131 | //+kubebuilder:subresource:status 132 | //+kubebuilder:resource:scope=Namespaced 133 | 134 | // ClusterProfile represents a single cluster in a multi-cluster deployment. 135 | type ClusterProfile struct { 136 | metav1.TypeMeta `json:",inline"` 137 | metav1.ObjectMeta `json:"metadata,omitempty"` 138 | 139 | // +required 140 | Spec ClusterProfileSpec `json:"spec"` 141 | 142 | // +optional 143 | Status ClusterProfileStatus `json:"status,omitempty"` 144 | } 145 | 146 | //+kubebuilder:object:root=true 147 | 148 | // ClusterProfileList contains a list of ClusterProfile. 149 | type ClusterProfileList struct { 150 | metav1.TypeMeta `json:",inline"` 151 | metav1.ListMeta `json:"metadata,omitempty"` 152 | Items []ClusterProfile `json:"items"` 153 | } 154 | 155 | func init() { 156 | SchemeBuilder.Register(&ClusterProfile{}, &ClusterProfileList{}) 157 | } 158 | -------------------------------------------------------------------------------- /apis/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1alpha1 contains API Schema definitions for the multicluster.x-k8s.io v1alpha1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=multicluster.x-k8s.io 20 | package v1alpha1 21 | 22 | import ( 23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | "k8s.io/apimachinery/pkg/runtime" 25 | "k8s.io/apimachinery/pkg/runtime/schema" 26 | "sigs.k8s.io/controller-runtime/pkg/scheme" 27 | ) 28 | 29 | const ( 30 | // Group is the API group. 31 | Group = "multicluster.x-k8s.io" 32 | // Version is the API version. 33 | Version = "v1alpha1" 34 | // Kind is the resource kind. 35 | Kind = "ClusterProfile" 36 | resource = "clusterprofiles" 37 | ) 38 | 39 | var ( 40 | // GroupVersion is group version used to register these objects 41 | GroupVersion = schema.GroupVersion{Group: Group, Version: Version} 42 | 43 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 44 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 45 | 46 | // SchemeGroupVersion generated code relies on this name 47 | // Deprecated 48 | SchemeGroupVersion = GroupVersion 49 | 50 | // SchemeGroupVersionKind is the group, version and kind for the ClusterProfile CR. 51 | SchemeGroupVersionKind = schema.GroupVersionKind{ 52 | Group: Group, 53 | Version: Version, 54 | Kind: Kind, 55 | } 56 | 57 | // SchemeGroupVersionResource is the group, version and resource for the ClusterProfile CR. 58 | SchemeGroupVersionResource = schema.GroupVersionResource{ 59 | Group: Group, 60 | Version: Version, 61 | Resource: resource, 62 | } 63 | 64 | // AddToScheme adds the types in this group-version to the given scheme. 65 | AddToScheme = SchemeBuilder.AddToScheme 66 | ) 67 | 68 | // Resource generated code relies on this being here, but it logically belongs to the group 69 | // DEPRECATED 70 | func Resource(resource string) schema.GroupResource { 71 | return schema.GroupResource{Group: GroupVersion.Group, Resource: resource} 72 | } 73 | 74 | // Adds the list of known types to api.Scheme. 75 | func addKnownTypes(scheme *runtime.Scheme) error { 76 | scheme.AddKnownTypes(GroupVersion, 77 | &ClusterProfile{}, 78 | &ClusterProfileList{}, 79 | ) 80 | metav1.AddToGroupVersion(scheme, GroupVersion) 81 | return nil 82 | } 83 | -------------------------------------------------------------------------------- /apis/v1alpha1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | 3 | /* 4 | Copyright 2024 The Kubernetes Authors. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | // Code generated by controller-gen. DO NOT EDIT. 20 | 21 | package v1alpha1 22 | 23 | import ( 24 | "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | "k8s.io/apimachinery/pkg/runtime" 26 | ) 27 | 28 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 29 | func (in *ClusterManager) DeepCopyInto(out *ClusterManager) { 30 | *out = *in 31 | } 32 | 33 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterManager. 34 | func (in *ClusterManager) DeepCopy() *ClusterManager { 35 | if in == nil { 36 | return nil 37 | } 38 | out := new(ClusterManager) 39 | in.DeepCopyInto(out) 40 | return out 41 | } 42 | 43 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 44 | func (in *ClusterProfile) DeepCopyInto(out *ClusterProfile) { 45 | *out = *in 46 | out.TypeMeta = in.TypeMeta 47 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 48 | out.Spec = in.Spec 49 | in.Status.DeepCopyInto(&out.Status) 50 | } 51 | 52 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProfile. 53 | func (in *ClusterProfile) DeepCopy() *ClusterProfile { 54 | if in == nil { 55 | return nil 56 | } 57 | out := new(ClusterProfile) 58 | in.DeepCopyInto(out) 59 | return out 60 | } 61 | 62 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 63 | func (in *ClusterProfile) DeepCopyObject() runtime.Object { 64 | if c := in.DeepCopy(); c != nil { 65 | return c 66 | } 67 | return nil 68 | } 69 | 70 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 71 | func (in *ClusterProfileList) DeepCopyInto(out *ClusterProfileList) { 72 | *out = *in 73 | out.TypeMeta = in.TypeMeta 74 | in.ListMeta.DeepCopyInto(&out.ListMeta) 75 | if in.Items != nil { 76 | in, out := &in.Items, &out.Items 77 | *out = make([]ClusterProfile, len(*in)) 78 | for i := range *in { 79 | (*in)[i].DeepCopyInto(&(*out)[i]) 80 | } 81 | } 82 | } 83 | 84 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProfileList. 85 | func (in *ClusterProfileList) DeepCopy() *ClusterProfileList { 86 | if in == nil { 87 | return nil 88 | } 89 | out := new(ClusterProfileList) 90 | in.DeepCopyInto(out) 91 | return out 92 | } 93 | 94 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 95 | func (in *ClusterProfileList) DeepCopyObject() runtime.Object { 96 | if c := in.DeepCopy(); c != nil { 97 | return c 98 | } 99 | return nil 100 | } 101 | 102 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 103 | func (in *ClusterProfileSpec) DeepCopyInto(out *ClusterProfileSpec) { 104 | *out = *in 105 | out.ClusterManager = in.ClusterManager 106 | } 107 | 108 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProfileSpec. 109 | func (in *ClusterProfileSpec) DeepCopy() *ClusterProfileSpec { 110 | if in == nil { 111 | return nil 112 | } 113 | out := new(ClusterProfileSpec) 114 | in.DeepCopyInto(out) 115 | return out 116 | } 117 | 118 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 119 | func (in *ClusterProfileStatus) DeepCopyInto(out *ClusterProfileStatus) { 120 | *out = *in 121 | if in.Conditions != nil { 122 | in, out := &in.Conditions, &out.Conditions 123 | *out = make([]v1.Condition, len(*in)) 124 | for i := range *in { 125 | (*in)[i].DeepCopyInto(&(*out)[i]) 126 | } 127 | } 128 | out.Version = in.Version 129 | if in.Properties != nil { 130 | in, out := &in.Properties, &out.Properties 131 | *out = make([]Property, len(*in)) 132 | for i := range *in { 133 | (*in)[i].DeepCopyInto(&(*out)[i]) 134 | } 135 | } 136 | } 137 | 138 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProfileStatus. 139 | func (in *ClusterProfileStatus) DeepCopy() *ClusterProfileStatus { 140 | if in == nil { 141 | return nil 142 | } 143 | out := new(ClusterProfileStatus) 144 | in.DeepCopyInto(out) 145 | return out 146 | } 147 | 148 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 149 | func (in *ClusterVersion) DeepCopyInto(out *ClusterVersion) { 150 | *out = *in 151 | } 152 | 153 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVersion. 154 | func (in *ClusterVersion) DeepCopy() *ClusterVersion { 155 | if in == nil { 156 | return nil 157 | } 158 | out := new(ClusterVersion) 159 | in.DeepCopyInto(out) 160 | return out 161 | } 162 | 163 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 164 | func (in *Property) DeepCopyInto(out *Property) { 165 | *out = *in 166 | in.LastObservedTime.DeepCopyInto(&out.LastObservedTime) 167 | } 168 | 169 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Property. 170 | func (in *Property) DeepCopy() *Property { 171 | if in == nil { 172 | return nil 173 | } 174 | out := new(Property) 175 | in.DeepCopyInto(out) 176 | return out 177 | } 178 | -------------------------------------------------------------------------------- /client/clientset/versioned/clientset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package versioned 19 | 20 | import ( 21 | "fmt" 22 | "net/http" 23 | 24 | discovery "k8s.io/client-go/discovery" 25 | rest "k8s.io/client-go/rest" 26 | flowcontrol "k8s.io/client-go/util/flowcontrol" 27 | apisv1alpha1 "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/typed/apis/v1alpha1" 28 | ) 29 | 30 | type Interface interface { 31 | Discovery() discovery.DiscoveryInterface 32 | ApisV1alpha1() apisv1alpha1.ApisV1alpha1Interface 33 | } 34 | 35 | // Clientset contains the clients for groups. 36 | type Clientset struct { 37 | *discovery.DiscoveryClient 38 | apisV1alpha1 *apisv1alpha1.ApisV1alpha1Client 39 | } 40 | 41 | // ApisV1alpha1 retrieves the ApisV1alpha1Client 42 | func (c *Clientset) ApisV1alpha1() apisv1alpha1.ApisV1alpha1Interface { 43 | return c.apisV1alpha1 44 | } 45 | 46 | // Discovery retrieves the DiscoveryClient 47 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 48 | if c == nil { 49 | return nil 50 | } 51 | return c.DiscoveryClient 52 | } 53 | 54 | // NewForConfig creates a new Clientset for the given config. 55 | // If config's RateLimiter is not set and QPS and Burst are acceptable, 56 | // NewForConfig will generate a rate-limiter in configShallowCopy. 57 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 58 | // where httpClient was generated with rest.HTTPClientFor(c). 59 | func NewForConfig(c *rest.Config) (*Clientset, error) { 60 | configShallowCopy := *c 61 | 62 | if configShallowCopy.UserAgent == "" { 63 | configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() 64 | } 65 | 66 | // share the transport between all clients 67 | httpClient, err := rest.HTTPClientFor(&configShallowCopy) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | return NewForConfigAndClient(&configShallowCopy, httpClient) 73 | } 74 | 75 | // NewForConfigAndClient creates a new Clientset for the given config and http client. 76 | // Note the http client provided takes precedence over the configured transport values. 77 | // If config's RateLimiter is not set and QPS and Burst are acceptable, 78 | // NewForConfigAndClient will generate a rate-limiter in configShallowCopy. 79 | func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { 80 | configShallowCopy := *c 81 | if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { 82 | if configShallowCopy.Burst <= 0 { 83 | return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") 84 | } 85 | configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) 86 | } 87 | 88 | var cs Clientset 89 | var err error 90 | cs.apisV1alpha1, err = apisv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) 91 | if err != nil { 92 | return nil, err 93 | } 94 | 95 | cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) 96 | if err != nil { 97 | return nil, err 98 | } 99 | return &cs, nil 100 | } 101 | 102 | // NewForConfigOrDie creates a new Clientset for the given config and 103 | // panics if there is an error in the config. 104 | func NewForConfigOrDie(c *rest.Config) *Clientset { 105 | cs, err := NewForConfig(c) 106 | if err != nil { 107 | panic(err) 108 | } 109 | return cs 110 | } 111 | 112 | // New creates a new Clientset for the given RESTClient. 113 | func New(c rest.Interface) *Clientset { 114 | var cs Clientset 115 | cs.apisV1alpha1 = apisv1alpha1.New(c) 116 | 117 | cs.DiscoveryClient = discovery.NewDiscoveryClient(c) 118 | return &cs 119 | } 120 | -------------------------------------------------------------------------------- /client/clientset/versioned/fake/clientset_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | "k8s.io/apimachinery/pkg/runtime" 22 | "k8s.io/apimachinery/pkg/watch" 23 | "k8s.io/client-go/discovery" 24 | fakediscovery "k8s.io/client-go/discovery/fake" 25 | "k8s.io/client-go/testing" 26 | clientset "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned" 27 | apisv1alpha1 "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/typed/apis/v1alpha1" 28 | fakeapisv1alpha1 "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/typed/apis/v1alpha1/fake" 29 | ) 30 | 31 | // NewSimpleClientset returns a clientset that will respond with the provided objects. 32 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, 33 | // without applying any validations and/or defaults. It shouldn't be considered a replacement 34 | // for a real clientset and is mostly useful in simple unit tests. 35 | func NewSimpleClientset(objects ...runtime.Object) *Clientset { 36 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) 37 | for _, obj := range objects { 38 | if err := o.Add(obj); err != nil { 39 | panic(err) 40 | } 41 | } 42 | 43 | cs := &Clientset{tracker: o} 44 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} 45 | cs.AddReactor("*", "*", testing.ObjectReaction(o)) 46 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { 47 | gvr := action.GetResource() 48 | ns := action.GetNamespace() 49 | watch, err := o.Watch(gvr, ns) 50 | if err != nil { 51 | return false, nil, err 52 | } 53 | return true, watch, nil 54 | }) 55 | 56 | return cs 57 | } 58 | 59 | // Clientset implements clientset.Interface. Meant to be embedded into a 60 | // struct to get a default implementation. This makes faking out just the method 61 | // you want to test easier. 62 | type Clientset struct { 63 | testing.Fake 64 | discovery *fakediscovery.FakeDiscovery 65 | tracker testing.ObjectTracker 66 | } 67 | 68 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 69 | return c.discovery 70 | } 71 | 72 | func (c *Clientset) Tracker() testing.ObjectTracker { 73 | return c.tracker 74 | } 75 | 76 | var ( 77 | _ clientset.Interface = &Clientset{} 78 | _ testing.FakeClient = &Clientset{} 79 | ) 80 | 81 | // ApisV1alpha1 retrieves the ApisV1alpha1Client 82 | func (c *Clientset) ApisV1alpha1() apisv1alpha1.ApisV1alpha1Interface { 83 | return &fakeapisv1alpha1.FakeApisV1alpha1{Fake: &c.Fake} 84 | } 85 | -------------------------------------------------------------------------------- /client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package has the automatically generated fake clientset. 19 | package fake 20 | -------------------------------------------------------------------------------- /client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | runtime "k8s.io/apimachinery/pkg/runtime" 23 | schema "k8s.io/apimachinery/pkg/runtime/schema" 24 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 25 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 26 | apisv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 27 | ) 28 | 29 | var scheme = runtime.NewScheme() 30 | var codecs = serializer.NewCodecFactory(scheme) 31 | 32 | var localSchemeBuilder = runtime.SchemeBuilder{ 33 | apisv1alpha1.AddToScheme, 34 | } 35 | 36 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 37 | // of clientsets, like in: 38 | // 39 | // import ( 40 | // "k8s.io/client-go/kubernetes" 41 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 42 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 43 | // ) 44 | // 45 | // kclientset, _ := kubernetes.NewForConfig(c) 46 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 47 | // 48 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 49 | // correctly. 50 | var AddToScheme = localSchemeBuilder.AddToScheme 51 | 52 | func init() { 53 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 54 | utilruntime.Must(AddToScheme(scheme)) 55 | } 56 | -------------------------------------------------------------------------------- /client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package contains the scheme of the automatically generated clientset. 19 | package scheme 20 | -------------------------------------------------------------------------------- /client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package scheme 19 | 20 | import ( 21 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | runtime "k8s.io/apimachinery/pkg/runtime" 23 | schema "k8s.io/apimachinery/pkg/runtime/schema" 24 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 25 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 26 | apisv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 27 | ) 28 | 29 | var Scheme = runtime.NewScheme() 30 | var Codecs = serializer.NewCodecFactory(Scheme) 31 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 32 | var localSchemeBuilder = runtime.SchemeBuilder{ 33 | apisv1alpha1.AddToScheme, 34 | } 35 | 36 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 37 | // of clientsets, like in: 38 | // 39 | // import ( 40 | // "k8s.io/client-go/kubernetes" 41 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 42 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 43 | // ) 44 | // 45 | // kclientset, _ := kubernetes.NewForConfig(c) 46 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 47 | // 48 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 49 | // correctly. 50 | var AddToScheme = localSchemeBuilder.AddToScheme 51 | 52 | func init() { 53 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 54 | utilruntime.Must(AddToScheme(Scheme)) 55 | } 56 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/apis_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | "net/http" 22 | 23 | rest "k8s.io/client-go/rest" 24 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 25 | "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/scheme" 26 | ) 27 | 28 | type ApisV1alpha1Interface interface { 29 | RESTClient() rest.Interface 30 | ClusterProfilesGetter 31 | } 32 | 33 | // ApisV1alpha1Client is used to interact with features provided by the apis group. 34 | type ApisV1alpha1Client struct { 35 | restClient rest.Interface 36 | } 37 | 38 | func (c *ApisV1alpha1Client) ClusterProfiles(namespace string) ClusterProfileInterface { 39 | return newClusterProfiles(c, namespace) 40 | } 41 | 42 | // NewForConfig creates a new ApisV1alpha1Client for the given config. 43 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 44 | // where httpClient was generated with rest.HTTPClientFor(c). 45 | func NewForConfig(c *rest.Config) (*ApisV1alpha1Client, error) { 46 | config := *c 47 | if err := setConfigDefaults(&config); err != nil { 48 | return nil, err 49 | } 50 | httpClient, err := rest.HTTPClientFor(&config) 51 | if err != nil { 52 | return nil, err 53 | } 54 | return NewForConfigAndClient(&config, httpClient) 55 | } 56 | 57 | // NewForConfigAndClient creates a new ApisV1alpha1Client for the given config and http client. 58 | // Note the http client provided takes precedence over the configured transport values. 59 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ApisV1alpha1Client, error) { 60 | config := *c 61 | if err := setConfigDefaults(&config); err != nil { 62 | return nil, err 63 | } 64 | client, err := rest.RESTClientForConfigAndClient(&config, h) 65 | if err != nil { 66 | return nil, err 67 | } 68 | return &ApisV1alpha1Client{client}, nil 69 | } 70 | 71 | // NewForConfigOrDie creates a new ApisV1alpha1Client for the given config and 72 | // panics if there is an error in the config. 73 | func NewForConfigOrDie(c *rest.Config) *ApisV1alpha1Client { 74 | client, err := NewForConfig(c) 75 | if err != nil { 76 | panic(err) 77 | } 78 | return client 79 | } 80 | 81 | // New creates a new ApisV1alpha1Client for the given RESTClient. 82 | func New(c rest.Interface) *ApisV1alpha1Client { 83 | return &ApisV1alpha1Client{c} 84 | } 85 | 86 | func setConfigDefaults(config *rest.Config) error { 87 | gv := v1alpha1.SchemeGroupVersion 88 | config.GroupVersion = &gv 89 | config.APIPath = "/apis" 90 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() 91 | 92 | if config.UserAgent == "" { 93 | config.UserAgent = rest.DefaultKubernetesUserAgent() 94 | } 95 | 96 | return nil 97 | } 98 | 99 | // RESTClient returns a RESTClient that is used to communicate 100 | // with API server by this client implementation. 101 | func (c *ApisV1alpha1Client) RESTClient() rest.Interface { 102 | if c == nil { 103 | return nil 104 | } 105 | return c.restClient 106 | } 107 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/clusterprofile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | "context" 22 | "time" 23 | 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | types "k8s.io/apimachinery/pkg/types" 26 | watch "k8s.io/apimachinery/pkg/watch" 27 | rest "k8s.io/client-go/rest" 28 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 29 | scheme "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/scheme" 30 | ) 31 | 32 | // ClusterProfilesGetter has a method to return a ClusterProfileInterface. 33 | // A group's client should implement this interface. 34 | type ClusterProfilesGetter interface { 35 | ClusterProfiles(namespace string) ClusterProfileInterface 36 | } 37 | 38 | // ClusterProfileInterface has methods to work with ClusterProfile resources. 39 | type ClusterProfileInterface interface { 40 | Create(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.CreateOptions) (*v1alpha1.ClusterProfile, error) 41 | Update(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (*v1alpha1.ClusterProfile, error) 42 | UpdateStatus(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (*v1alpha1.ClusterProfile, error) 43 | Delete(ctx context.Context, name string, opts v1.DeleteOptions) error 44 | DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error 45 | Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterProfile, error) 46 | List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterProfileList, error) 47 | Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) 48 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProfile, err error) 49 | ClusterProfileExpansion 50 | } 51 | 52 | // clusterProfiles implements ClusterProfileInterface 53 | type clusterProfiles struct { 54 | client rest.Interface 55 | ns string 56 | } 57 | 58 | // newClusterProfiles returns a ClusterProfiles 59 | func newClusterProfiles(c *ApisV1alpha1Client, namespace string) *clusterProfiles { 60 | return &clusterProfiles{ 61 | client: c.RESTClient(), 62 | ns: namespace, 63 | } 64 | } 65 | 66 | // Get takes name of the clusterProfile, and returns the corresponding clusterProfile object, and an error if there is any. 67 | func (c *clusterProfiles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterProfile, err error) { 68 | result = &v1alpha1.ClusterProfile{} 69 | err = c.client.Get(). 70 | Namespace(c.ns). 71 | Resource("clusterprofiles"). 72 | Name(name). 73 | VersionedParams(&options, scheme.ParameterCodec). 74 | Do(ctx). 75 | Into(result) 76 | return 77 | } 78 | 79 | // List takes label and field selectors, and returns the list of ClusterProfiles that match those selectors. 80 | func (c *clusterProfiles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterProfileList, err error) { 81 | var timeout time.Duration 82 | if opts.TimeoutSeconds != nil { 83 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 84 | } 85 | result = &v1alpha1.ClusterProfileList{} 86 | err = c.client.Get(). 87 | Namespace(c.ns). 88 | Resource("clusterprofiles"). 89 | VersionedParams(&opts, scheme.ParameterCodec). 90 | Timeout(timeout). 91 | Do(ctx). 92 | Into(result) 93 | return 94 | } 95 | 96 | // Watch returns a watch.Interface that watches the requested clusterProfiles. 97 | func (c *clusterProfiles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 98 | var timeout time.Duration 99 | if opts.TimeoutSeconds != nil { 100 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 101 | } 102 | opts.Watch = true 103 | return c.client.Get(). 104 | Namespace(c.ns). 105 | Resource("clusterprofiles"). 106 | VersionedParams(&opts, scheme.ParameterCodec). 107 | Timeout(timeout). 108 | Watch(ctx) 109 | } 110 | 111 | // Create takes the representation of a clusterProfile and creates it. Returns the server's representation of the clusterProfile, and an error, if there is any. 112 | func (c *clusterProfiles) Create(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.CreateOptions) (result *v1alpha1.ClusterProfile, err error) { 113 | result = &v1alpha1.ClusterProfile{} 114 | err = c.client.Post(). 115 | Namespace(c.ns). 116 | Resource("clusterprofiles"). 117 | VersionedParams(&opts, scheme.ParameterCodec). 118 | Body(clusterProfile). 119 | Do(ctx). 120 | Into(result) 121 | return 122 | } 123 | 124 | // Update takes the representation of a clusterProfile and updates it. Returns the server's representation of the clusterProfile, and an error, if there is any. 125 | func (c *clusterProfiles) Update(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (result *v1alpha1.ClusterProfile, err error) { 126 | result = &v1alpha1.ClusterProfile{} 127 | err = c.client.Put(). 128 | Namespace(c.ns). 129 | Resource("clusterprofiles"). 130 | Name(clusterProfile.Name). 131 | VersionedParams(&opts, scheme.ParameterCodec). 132 | Body(clusterProfile). 133 | Do(ctx). 134 | Into(result) 135 | return 136 | } 137 | 138 | // UpdateStatus was generated because the type contains a Status member. 139 | // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). 140 | func (c *clusterProfiles) UpdateStatus(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (result *v1alpha1.ClusterProfile, err error) { 141 | result = &v1alpha1.ClusterProfile{} 142 | err = c.client.Put(). 143 | Namespace(c.ns). 144 | Resource("clusterprofiles"). 145 | Name(clusterProfile.Name). 146 | SubResource("status"). 147 | VersionedParams(&opts, scheme.ParameterCodec). 148 | Body(clusterProfile). 149 | Do(ctx). 150 | Into(result) 151 | return 152 | } 153 | 154 | // Delete takes name of the clusterProfile and deletes it. Returns an error if one occurs. 155 | func (c *clusterProfiles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 156 | return c.client.Delete(). 157 | Namespace(c.ns). 158 | Resource("clusterprofiles"). 159 | Name(name). 160 | Body(&opts). 161 | Do(ctx). 162 | Error() 163 | } 164 | 165 | // DeleteCollection deletes a collection of objects. 166 | func (c *clusterProfiles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 167 | var timeout time.Duration 168 | if listOpts.TimeoutSeconds != nil { 169 | timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second 170 | } 171 | return c.client.Delete(). 172 | Namespace(c.ns). 173 | Resource("clusterprofiles"). 174 | VersionedParams(&listOpts, scheme.ParameterCodec). 175 | Timeout(timeout). 176 | Body(&opts). 177 | Do(ctx). 178 | Error() 179 | } 180 | 181 | // Patch applies the patch and returns the patched clusterProfile. 182 | func (c *clusterProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProfile, err error) { 183 | result = &v1alpha1.ClusterProfile{} 184 | err = c.client.Patch(pt). 185 | Namespace(c.ns). 186 | Resource("clusterprofiles"). 187 | Name(name). 188 | SubResource(subresources...). 189 | VersionedParams(&opts, scheme.ParameterCodec). 190 | Body(data). 191 | Do(ctx). 192 | Into(result) 193 | return 194 | } 195 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // This package has the automatically generated typed clients. 19 | package v1alpha1 20 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | // Package fake has the automatically generated clients. 19 | package fake 20 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/fake/fake_apis_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | rest "k8s.io/client-go/rest" 22 | testing "k8s.io/client-go/testing" 23 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned/typed/apis/v1alpha1" 24 | ) 25 | 26 | type FakeApisV1alpha1 struct { 27 | *testing.Fake 28 | } 29 | 30 | func (c *FakeApisV1alpha1) ClusterProfiles(namespace string) v1alpha1.ClusterProfileInterface { 31 | return &FakeClusterProfiles{c, namespace} 32 | } 33 | 34 | // RESTClient returns a RESTClient that is used to communicate 35 | // with API server by this client implementation. 36 | func (c *FakeApisV1alpha1) RESTClient() rest.Interface { 37 | var ret *rest.RESTClient 38 | return ret 39 | } 40 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/fake/fake_clusterprofile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package fake 19 | 20 | import ( 21 | "context" 22 | 23 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | labels "k8s.io/apimachinery/pkg/labels" 25 | types "k8s.io/apimachinery/pkg/types" 26 | watch "k8s.io/apimachinery/pkg/watch" 27 | testing "k8s.io/client-go/testing" 28 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 29 | ) 30 | 31 | // FakeClusterProfiles implements ClusterProfileInterface 32 | type FakeClusterProfiles struct { 33 | Fake *FakeApisV1alpha1 34 | ns string 35 | } 36 | 37 | var clusterprofilesResource = v1alpha1.SchemeGroupVersion.WithResource("clusterprofiles") 38 | 39 | var clusterprofilesKind = v1alpha1.SchemeGroupVersion.WithKind("ClusterProfile") 40 | 41 | // Get takes name of the clusterProfile, and returns the corresponding clusterProfile object, and an error if there is any. 42 | func (c *FakeClusterProfiles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterProfile, err error) { 43 | obj, err := c.Fake. 44 | Invokes(testing.NewGetAction(clusterprofilesResource, c.ns, name), &v1alpha1.ClusterProfile{}) 45 | 46 | if obj == nil { 47 | return nil, err 48 | } 49 | return obj.(*v1alpha1.ClusterProfile), err 50 | } 51 | 52 | // List takes label and field selectors, and returns the list of ClusterProfiles that match those selectors. 53 | func (c *FakeClusterProfiles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterProfileList, err error) { 54 | obj, err := c.Fake. 55 | Invokes(testing.NewListAction(clusterprofilesResource, clusterprofilesKind, c.ns, opts), &v1alpha1.ClusterProfileList{}) 56 | 57 | if obj == nil { 58 | return nil, err 59 | } 60 | 61 | label, _, _ := testing.ExtractFromListOptions(opts) 62 | if label == nil { 63 | label = labels.Everything() 64 | } 65 | list := &v1alpha1.ClusterProfileList{ListMeta: obj.(*v1alpha1.ClusterProfileList).ListMeta} 66 | for _, item := range obj.(*v1alpha1.ClusterProfileList).Items { 67 | if label.Matches(labels.Set(item.Labels)) { 68 | list.Items = append(list.Items, item) 69 | } 70 | } 71 | return list, err 72 | } 73 | 74 | // Watch returns a watch.Interface that watches the requested clusterProfiles. 75 | func (c *FakeClusterProfiles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 76 | return c.Fake. 77 | InvokesWatch(testing.NewWatchAction(clusterprofilesResource, c.ns, opts)) 78 | 79 | } 80 | 81 | // Create takes the representation of a clusterProfile and creates it. Returns the server's representation of the clusterProfile, and an error, if there is any. 82 | func (c *FakeClusterProfiles) Create(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.CreateOptions) (result *v1alpha1.ClusterProfile, err error) { 83 | obj, err := c.Fake. 84 | Invokes(testing.NewCreateAction(clusterprofilesResource, c.ns, clusterProfile), &v1alpha1.ClusterProfile{}) 85 | 86 | if obj == nil { 87 | return nil, err 88 | } 89 | return obj.(*v1alpha1.ClusterProfile), err 90 | } 91 | 92 | // Update takes the representation of a clusterProfile and updates it. Returns the server's representation of the clusterProfile, and an error, if there is any. 93 | func (c *FakeClusterProfiles) Update(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (result *v1alpha1.ClusterProfile, err error) { 94 | obj, err := c.Fake. 95 | Invokes(testing.NewUpdateAction(clusterprofilesResource, c.ns, clusterProfile), &v1alpha1.ClusterProfile{}) 96 | 97 | if obj == nil { 98 | return nil, err 99 | } 100 | return obj.(*v1alpha1.ClusterProfile), err 101 | } 102 | 103 | // UpdateStatus was generated because the type contains a Status member. 104 | // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). 105 | func (c *FakeClusterProfiles) UpdateStatus(ctx context.Context, clusterProfile *v1alpha1.ClusterProfile, opts v1.UpdateOptions) (*v1alpha1.ClusterProfile, error) { 106 | obj, err := c.Fake. 107 | Invokes(testing.NewUpdateSubresourceAction(clusterprofilesResource, "status", c.ns, clusterProfile), &v1alpha1.ClusterProfile{}) 108 | 109 | if obj == nil { 110 | return nil, err 111 | } 112 | return obj.(*v1alpha1.ClusterProfile), err 113 | } 114 | 115 | // Delete takes name of the clusterProfile and deletes it. Returns an error if one occurs. 116 | func (c *FakeClusterProfiles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 117 | _, err := c.Fake. 118 | Invokes(testing.NewDeleteActionWithOptions(clusterprofilesResource, c.ns, name, opts), &v1alpha1.ClusterProfile{}) 119 | 120 | return err 121 | } 122 | 123 | // DeleteCollection deletes a collection of objects. 124 | func (c *FakeClusterProfiles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 125 | action := testing.NewDeleteCollectionAction(clusterprofilesResource, c.ns, listOpts) 126 | 127 | _, err := c.Fake.Invokes(action, &v1alpha1.ClusterProfileList{}) 128 | return err 129 | } 130 | 131 | // Patch applies the patch and returns the patched clusterProfile. 132 | func (c *FakeClusterProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterProfile, err error) { 133 | obj, err := c.Fake. 134 | Invokes(testing.NewPatchSubresourceAction(clusterprofilesResource, c.ns, name, pt, data, subresources...), &v1alpha1.ClusterProfile{}) 135 | 136 | if obj == nil { 137 | return nil, err 138 | } 139 | return obj.(*v1alpha1.ClusterProfile), err 140 | } 141 | -------------------------------------------------------------------------------- /client/clientset/versioned/typed/apis/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by client-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | type ClusterProfileExpansion interface{} 21 | -------------------------------------------------------------------------------- /client/informers/externalversions/apis/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package apis 19 | 20 | import ( 21 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/apis/v1alpha1" 22 | internalinterfaces "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to each of this group's versions. 26 | type Interface interface { 27 | // V1alpha1 provides access to shared informers for resources in V1alpha1. 28 | V1alpha1() v1alpha1.Interface 29 | } 30 | 31 | type group struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // V1alpha1 returns a new v1alpha1.Interface. 43 | func (g *group) V1alpha1() v1alpha1.Interface { 44 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) 45 | } 46 | -------------------------------------------------------------------------------- /client/informers/externalversions/apis/v1alpha1/clusterprofile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | "context" 22 | time "time" 23 | 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | watch "k8s.io/apimachinery/pkg/watch" 27 | cache "k8s.io/client-go/tools/cache" 28 | apisv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 29 | versioned "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned" 30 | internalinterfaces "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/internalinterfaces" 31 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/client/listers/apis/v1alpha1" 32 | ) 33 | 34 | // ClusterProfileInformer provides access to a shared informer and lister for 35 | // ClusterProfiles. 36 | type ClusterProfileInformer interface { 37 | Informer() cache.SharedIndexInformer 38 | Lister() v1alpha1.ClusterProfileLister 39 | } 40 | 41 | type clusterProfileInformer struct { 42 | factory internalinterfaces.SharedInformerFactory 43 | tweakListOptions internalinterfaces.TweakListOptionsFunc 44 | namespace string 45 | } 46 | 47 | // NewClusterProfileInformer constructs a new informer for ClusterProfile type. 48 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 49 | // one. This reduces memory footprint and number of connections to the server. 50 | func NewClusterProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { 51 | return NewFilteredClusterProfileInformer(client, namespace, resyncPeriod, indexers, nil) 52 | } 53 | 54 | // NewFilteredClusterProfileInformer constructs a new informer for ClusterProfile type. 55 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 56 | // one. This reduces memory footprint and number of connections to the server. 57 | func NewFilteredClusterProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { 58 | return cache.NewSharedIndexInformer( 59 | &cache.ListWatch{ 60 | ListFunc: func(options v1.ListOptions) (runtime.Object, error) { 61 | if tweakListOptions != nil { 62 | tweakListOptions(&options) 63 | } 64 | return client.ApisV1alpha1().ClusterProfiles(namespace).List(context.TODO(), options) 65 | }, 66 | WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { 67 | if tweakListOptions != nil { 68 | tweakListOptions(&options) 69 | } 70 | return client.ApisV1alpha1().ClusterProfiles(namespace).Watch(context.TODO(), options) 71 | }, 72 | }, 73 | &apisv1alpha1.ClusterProfile{}, 74 | resyncPeriod, 75 | indexers, 76 | ) 77 | } 78 | 79 | func (f *clusterProfileInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { 80 | return NewFilteredClusterProfileInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) 81 | } 82 | 83 | func (f *clusterProfileInformer) Informer() cache.SharedIndexInformer { 84 | return f.factory.InformerFor(&apisv1alpha1.ClusterProfile{}, f.defaultInformer) 85 | } 86 | 87 | func (f *clusterProfileInformer) Lister() v1alpha1.ClusterProfileLister { 88 | return v1alpha1.NewClusterProfileLister(f.Informer().GetIndexer()) 89 | } 90 | -------------------------------------------------------------------------------- /client/informers/externalversions/apis/v1alpha1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | internalinterfaces "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/internalinterfaces" 22 | ) 23 | 24 | // Interface provides access to all the informers in this group version. 25 | type Interface interface { 26 | // ClusterProfiles returns a ClusterProfileInformer. 27 | ClusterProfiles() ClusterProfileInformer 28 | } 29 | 30 | type version struct { 31 | factory internalinterfaces.SharedInformerFactory 32 | namespace string 33 | tweakListOptions internalinterfaces.TweakListOptionsFunc 34 | } 35 | 36 | // New returns a new Interface. 37 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 38 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 39 | } 40 | 41 | // ClusterProfiles returns a ClusterProfileInformer. 42 | func (v *version) ClusterProfiles() ClusterProfileInformer { 43 | return &clusterProfileInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 44 | } 45 | -------------------------------------------------------------------------------- /client/informers/externalversions/factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package externalversions 19 | 20 | import ( 21 | reflect "reflect" 22 | sync "sync" 23 | time "time" 24 | 25 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | runtime "k8s.io/apimachinery/pkg/runtime" 27 | schema "k8s.io/apimachinery/pkg/runtime/schema" 28 | cache "k8s.io/client-go/tools/cache" 29 | versioned "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned" 30 | apis "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/apis" 31 | internalinterfaces "sigs.k8s.io/cluster-inventory-api/client/informers/externalversions/internalinterfaces" 32 | ) 33 | 34 | // SharedInformerOption defines the functional option type for SharedInformerFactory. 35 | type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory 36 | 37 | type sharedInformerFactory struct { 38 | client versioned.Interface 39 | namespace string 40 | tweakListOptions internalinterfaces.TweakListOptionsFunc 41 | lock sync.Mutex 42 | defaultResync time.Duration 43 | customResync map[reflect.Type]time.Duration 44 | transform cache.TransformFunc 45 | 46 | informers map[reflect.Type]cache.SharedIndexInformer 47 | // startedInformers is used for tracking which informers have been started. 48 | // This allows Start() to be called multiple times safely. 49 | startedInformers map[reflect.Type]bool 50 | // wg tracks how many goroutines were started. 51 | wg sync.WaitGroup 52 | // shuttingDown is true when Shutdown has been called. It may still be running 53 | // because it needs to wait for goroutines. 54 | shuttingDown bool 55 | } 56 | 57 | // WithCustomResyncConfig sets a custom resync period for the specified informer types. 58 | func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { 59 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 60 | for k, v := range resyncConfig { 61 | factory.customResync[reflect.TypeOf(k)] = v 62 | } 63 | return factory 64 | } 65 | } 66 | 67 | // WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. 68 | func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { 69 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 70 | factory.tweakListOptions = tweakListOptions 71 | return factory 72 | } 73 | } 74 | 75 | // WithNamespace limits the SharedInformerFactory to the specified namespace. 76 | func WithNamespace(namespace string) SharedInformerOption { 77 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 78 | factory.namespace = namespace 79 | return factory 80 | } 81 | } 82 | 83 | // WithTransform sets a transform on all informers. 84 | func WithTransform(transform cache.TransformFunc) SharedInformerOption { 85 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 86 | factory.transform = transform 87 | return factory 88 | } 89 | } 90 | 91 | // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. 92 | func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { 93 | return NewSharedInformerFactoryWithOptions(client, defaultResync) 94 | } 95 | 96 | // NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. 97 | // Listers obtained via this SharedInformerFactory will be subject to the same filters 98 | // as specified here. 99 | // Deprecated: Please use NewSharedInformerFactoryWithOptions instead 100 | func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { 101 | return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) 102 | } 103 | 104 | // NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. 105 | func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { 106 | factory := &sharedInformerFactory{ 107 | client: client, 108 | namespace: v1.NamespaceAll, 109 | defaultResync: defaultResync, 110 | informers: make(map[reflect.Type]cache.SharedIndexInformer), 111 | startedInformers: make(map[reflect.Type]bool), 112 | customResync: make(map[reflect.Type]time.Duration), 113 | } 114 | 115 | // Apply all options 116 | for _, opt := range options { 117 | factory = opt(factory) 118 | } 119 | 120 | return factory 121 | } 122 | 123 | func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { 124 | f.lock.Lock() 125 | defer f.lock.Unlock() 126 | 127 | if f.shuttingDown { 128 | return 129 | } 130 | 131 | for informerType, informer := range f.informers { 132 | if !f.startedInformers[informerType] { 133 | f.wg.Add(1) 134 | // We need a new variable in each loop iteration, 135 | // otherwise the goroutine would use the loop variable 136 | // and that keeps changing. 137 | informer := informer 138 | go func() { 139 | defer f.wg.Done() 140 | informer.Run(stopCh) 141 | }() 142 | f.startedInformers[informerType] = true 143 | } 144 | } 145 | } 146 | 147 | func (f *sharedInformerFactory) Shutdown() { 148 | f.lock.Lock() 149 | f.shuttingDown = true 150 | f.lock.Unlock() 151 | 152 | // Will return immediately if there is nothing to wait for. 153 | f.wg.Wait() 154 | } 155 | 156 | func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { 157 | informers := func() map[reflect.Type]cache.SharedIndexInformer { 158 | f.lock.Lock() 159 | defer f.lock.Unlock() 160 | 161 | informers := map[reflect.Type]cache.SharedIndexInformer{} 162 | for informerType, informer := range f.informers { 163 | if f.startedInformers[informerType] { 164 | informers[informerType] = informer 165 | } 166 | } 167 | return informers 168 | }() 169 | 170 | res := map[reflect.Type]bool{} 171 | for informType, informer := range informers { 172 | res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) 173 | } 174 | return res 175 | } 176 | 177 | // InformerFor returns the SharedIndexInformer for obj using an internal 178 | // client. 179 | func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { 180 | f.lock.Lock() 181 | defer f.lock.Unlock() 182 | 183 | informerType := reflect.TypeOf(obj) 184 | informer, exists := f.informers[informerType] 185 | if exists { 186 | return informer 187 | } 188 | 189 | resyncPeriod, exists := f.customResync[informerType] 190 | if !exists { 191 | resyncPeriod = f.defaultResync 192 | } 193 | 194 | informer = newFunc(f.client, resyncPeriod) 195 | informer.SetTransform(f.transform) 196 | f.informers[informerType] = informer 197 | 198 | return informer 199 | } 200 | 201 | // SharedInformerFactory provides shared informers for resources in all known 202 | // API group versions. 203 | // 204 | // It is typically used like this: 205 | // 206 | // ctx, cancel := context.Background() 207 | // defer cancel() 208 | // factory := NewSharedInformerFactory(client, resyncPeriod) 209 | // defer factory.WaitForStop() // Returns immediately if nothing was started. 210 | // genericInformer := factory.ForResource(resource) 211 | // typedInformer := factory.SomeAPIGroup().V1().SomeType() 212 | // factory.Start(ctx.Done()) // Start processing these informers. 213 | // synced := factory.WaitForCacheSync(ctx.Done()) 214 | // for v, ok := range synced { 215 | // if !ok { 216 | // fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) 217 | // return 218 | // } 219 | // } 220 | // 221 | // // Creating informers can also be created after Start, but then 222 | // // Start must be called again: 223 | // anotherGenericInformer := factory.ForResource(resource) 224 | // factory.Start(ctx.Done()) 225 | type SharedInformerFactory interface { 226 | internalinterfaces.SharedInformerFactory 227 | 228 | // Start initializes all requested informers. They are handled in goroutines 229 | // which run until the stop channel gets closed. 230 | Start(stopCh <-chan struct{}) 231 | 232 | // Shutdown marks a factory as shutting down. At that point no new 233 | // informers can be started anymore and Start will return without 234 | // doing anything. 235 | // 236 | // In addition, Shutdown blocks until all goroutines have terminated. For that 237 | // to happen, the close channel(s) that they were started with must be closed, 238 | // either before Shutdown gets called or while it is waiting. 239 | // 240 | // Shutdown may be called multiple times, even concurrently. All such calls will 241 | // block until all goroutines have terminated. 242 | Shutdown() 243 | 244 | // WaitForCacheSync blocks until all started informers' caches were synced 245 | // or the stop channel gets closed. 246 | WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool 247 | 248 | // ForResource gives generic access to a shared informer of the matching type. 249 | ForResource(resource schema.GroupVersionResource) (GenericInformer, error) 250 | 251 | // InformerFor returns the SharedIndexInformer for obj using an internal 252 | // client. 253 | InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer 254 | 255 | Apis() apis.Interface 256 | } 257 | 258 | func (f *sharedInformerFactory) Apis() apis.Interface { 259 | return apis.New(f, f.namespace, f.tweakListOptions) 260 | } 261 | -------------------------------------------------------------------------------- /client/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package externalversions 19 | 20 | import ( 21 | "fmt" 22 | 23 | schema "k8s.io/apimachinery/pkg/runtime/schema" 24 | cache "k8s.io/client-go/tools/cache" 25 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 26 | ) 27 | 28 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 29 | // sharedInformers based on type 30 | type GenericInformer interface { 31 | Informer() cache.SharedIndexInformer 32 | Lister() cache.GenericLister 33 | } 34 | 35 | type genericInformer struct { 36 | informer cache.SharedIndexInformer 37 | resource schema.GroupResource 38 | } 39 | 40 | // Informer returns the SharedIndexInformer. 41 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 42 | return f.informer 43 | } 44 | 45 | // Lister returns the GenericLister. 46 | func (f *genericInformer) Lister() cache.GenericLister { 47 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 48 | } 49 | 50 | // ForResource gives generic access to a shared informer of the matching type 51 | // TODO extend this to unknown resources with a client pool 52 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 53 | switch resource { 54 | // Group=apis, Version=v1alpha1 55 | case v1alpha1.SchemeGroupVersion.WithResource("clusterprofiles"): 56 | return &genericInformer{resource: resource.GroupResource(), informer: f.Apis().V1alpha1().ClusterProfiles().Informer()}, nil 57 | 58 | } 59 | 60 | return nil, fmt.Errorf("no informer found for %v", resource) 61 | } 62 | -------------------------------------------------------------------------------- /client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by informer-gen. DO NOT EDIT. 17 | 18 | package internalinterfaces 19 | 20 | import ( 21 | time "time" 22 | 23 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | runtime "k8s.io/apimachinery/pkg/runtime" 25 | cache "k8s.io/client-go/tools/cache" 26 | versioned "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned" 27 | ) 28 | 29 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 30 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 31 | 32 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 33 | type SharedInformerFactory interface { 34 | Start(stopCh <-chan struct{}) 35 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 36 | } 37 | 38 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 39 | type TweakListOptionsFunc func(*v1.ListOptions) 40 | -------------------------------------------------------------------------------- /client/listers/apis/v1alpha1/clusterprofile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by lister-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | import ( 21 | "k8s.io/apimachinery/pkg/api/errors" 22 | "k8s.io/apimachinery/pkg/labels" 23 | "k8s.io/client-go/tools/cache" 24 | v1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 25 | ) 26 | 27 | // ClusterProfileLister helps list ClusterProfiles. 28 | // All objects returned here must be treated as read-only. 29 | type ClusterProfileLister interface { 30 | // List lists all ClusterProfiles in the indexer. 31 | // Objects returned here must be treated as read-only. 32 | List(selector labels.Selector) (ret []*v1alpha1.ClusterProfile, err error) 33 | // ClusterProfiles returns an object that can list and get ClusterProfiles. 34 | ClusterProfiles(namespace string) ClusterProfileNamespaceLister 35 | ClusterProfileListerExpansion 36 | } 37 | 38 | // clusterProfileLister implements the ClusterProfileLister interface. 39 | type clusterProfileLister struct { 40 | indexer cache.Indexer 41 | } 42 | 43 | // NewClusterProfileLister returns a new ClusterProfileLister. 44 | func NewClusterProfileLister(indexer cache.Indexer) ClusterProfileLister { 45 | return &clusterProfileLister{indexer: indexer} 46 | } 47 | 48 | // List lists all ClusterProfiles in the indexer. 49 | func (s *clusterProfileLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterProfile, err error) { 50 | err = cache.ListAll(s.indexer, selector, func(m interface{}) { 51 | ret = append(ret, m.(*v1alpha1.ClusterProfile)) 52 | }) 53 | return ret, err 54 | } 55 | 56 | // ClusterProfiles returns an object that can list and get ClusterProfiles. 57 | func (s *clusterProfileLister) ClusterProfiles(namespace string) ClusterProfileNamespaceLister { 58 | return clusterProfileNamespaceLister{indexer: s.indexer, namespace: namespace} 59 | } 60 | 61 | // ClusterProfileNamespaceLister helps list and get ClusterProfiles. 62 | // All objects returned here must be treated as read-only. 63 | type ClusterProfileNamespaceLister interface { 64 | // List lists all ClusterProfiles in the indexer for a given namespace. 65 | // Objects returned here must be treated as read-only. 66 | List(selector labels.Selector) (ret []*v1alpha1.ClusterProfile, err error) 67 | // Get retrieves the ClusterProfile from the indexer for a given namespace and name. 68 | // Objects returned here must be treated as read-only. 69 | Get(name string) (*v1alpha1.ClusterProfile, error) 70 | ClusterProfileNamespaceListerExpansion 71 | } 72 | 73 | // clusterProfileNamespaceLister implements the ClusterProfileNamespaceLister 74 | // interface. 75 | type clusterProfileNamespaceLister struct { 76 | indexer cache.Indexer 77 | namespace string 78 | } 79 | 80 | // List lists all ClusterProfiles in the indexer for a given namespace. 81 | func (s clusterProfileNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterProfile, err error) { 82 | err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { 83 | ret = append(ret, m.(*v1alpha1.ClusterProfile)) 84 | }) 85 | return ret, err 86 | } 87 | 88 | // Get retrieves the ClusterProfile from the indexer for a given namespace and name. 89 | func (s clusterProfileNamespaceLister) Get(name string) (*v1alpha1.ClusterProfile, error) { 90 | obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) 91 | if err != nil { 92 | return nil, err 93 | } 94 | if !exists { 95 | return nil, errors.NewNotFound(v1alpha1.Resource("clusterprofile"), name) 96 | } 97 | return obj.(*v1alpha1.ClusterProfile), nil 98 | } 99 | -------------------------------------------------------------------------------- /client/listers/apis/v1alpha1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | // Code generated by lister-gen. DO NOT EDIT. 17 | 18 | package v1alpha1 19 | 20 | // ClusterProfileListerExpansion allows custom methods to be added to 21 | // ClusterProfileLister. 22 | type ClusterProfileListerExpansion interface{} 23 | 24 | // ClusterProfileNamespaceListerExpansion allows custom methods to be added to 25 | // ClusterProfileNamespaceLister. 26 | type ClusterProfileNamespaceListerExpansion interface{} 27 | -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Community Code of Conduct 2 | 3 | Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) 4 | -------------------------------------------------------------------------------- /config/crd/bases/multicluster.x-k8s.io_clusterprofiles.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.14.0 7 | name: clusterprofiles.multicluster.x-k8s.io 8 | spec: 9 | group: multicluster.x-k8s.io 10 | names: 11 | kind: ClusterProfile 12 | listKind: ClusterProfileList 13 | plural: clusterprofiles 14 | singular: clusterprofile 15 | scope: Namespaced 16 | versions: 17 | - name: v1alpha1 18 | schema: 19 | openAPIV3Schema: 20 | description: ClusterProfile represents a single cluster in a multi-cluster 21 | deployment. 22 | properties: 23 | apiVersion: 24 | description: |- 25 | APIVersion defines the versioned schema of this representation of an object. 26 | Servers should convert recognized schemas to the latest internal value, and 27 | may reject unrecognized values. 28 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 29 | type: string 30 | kind: 31 | description: |- 32 | Kind is a string value representing the REST resource this object represents. 33 | Servers may infer this from the endpoint the client submits requests to. 34 | Cannot be updated. 35 | In CamelCase. 36 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 37 | type: string 38 | metadata: 39 | type: object 40 | spec: 41 | description: ClusterProfileSpec defines the desired state of ClusterProfile. 42 | properties: 43 | clusterManager: 44 | description: ClusterManager defines which cluster manager owns this 45 | ClusterProfile resource 46 | properties: 47 | name: 48 | description: Name defines the name of the cluster manager 49 | type: string 50 | required: 51 | - name 52 | type: object 53 | x-kubernetes-validations: 54 | - message: ClusterManager is immutable 55 | rule: self == oldSelf 56 | displayName: 57 | description: DisplayName defines a human-readable name of the ClusterProfile 58 | type: string 59 | required: 60 | - clusterManager 61 | type: object 62 | status: 63 | description: ClusterProfileStatus defines the observed state of ClusterProfile. 64 | properties: 65 | conditions: 66 | description: Conditions contains the different condition statuses 67 | for this cluster. 68 | items: 69 | description: "Condition contains details for one aspect of the current 70 | state of this API Resource.\n---\nThis struct is intended for 71 | direct use as an array at the field path .status.conditions. For 72 | example,\n\n\n\ttype FooStatus struct{\n\t // Represents the 73 | observations of a foo's current state.\n\t // Known .status.conditions.type 74 | are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // 75 | +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t 76 | \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" 77 | patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t 78 | \ // other fields\n\t}" 79 | properties: 80 | lastTransitionTime: 81 | description: |- 82 | lastTransitionTime is the last time the condition transitioned from one status to another. 83 | This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. 84 | format: date-time 85 | type: string 86 | message: 87 | description: |- 88 | message is a human readable message indicating details about the transition. 89 | This may be an empty string. 90 | maxLength: 32768 91 | type: string 92 | observedGeneration: 93 | description: |- 94 | observedGeneration represents the .metadata.generation that the condition was set based upon. 95 | For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date 96 | with respect to the current state of the instance. 97 | format: int64 98 | minimum: 0 99 | type: integer 100 | reason: 101 | description: |- 102 | reason contains a programmatic identifier indicating the reason for the condition's last transition. 103 | Producers of specific condition types may define expected values and meanings for this field, 104 | and whether the values are considered a guaranteed API. 105 | The value should be a CamelCase string. 106 | This field may not be empty. 107 | maxLength: 1024 108 | minLength: 1 109 | pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ 110 | type: string 111 | status: 112 | description: status of the condition, one of True, False, Unknown. 113 | enum: 114 | - "True" 115 | - "False" 116 | - Unknown 117 | type: string 118 | type: 119 | description: |- 120 | type of condition in CamelCase or in foo.example.com/CamelCase. 121 | --- 122 | Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be 123 | useful (see .node.status.conditions), the ability to deconflict is important. 124 | The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 125 | maxLength: 316 126 | pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ 127 | type: string 128 | required: 129 | - lastTransitionTime 130 | - message 131 | - reason 132 | - status 133 | - type 134 | type: object 135 | type: array 136 | properties: 137 | description: |- 138 | Properties defines cluster characteristics through a list of Property objects. 139 | Each Property can be one of: 140 | 1. A ClusterProperty resource (as defined in KEP-2149) 141 | 2. Custom information from cluster manager implementations 142 | Property names support both: 143 | - Standard names from ClusterProperty resources 144 | - Custom names defined by cluster managers 145 | items: 146 | description: |- 147 | Property defines the data structure to represent a property of a cluster. 148 | It contains a name/value pair and the last observed time of the property on the cluster. 149 | This property can store various configurable details and metrics of a cluster, 150 | which may include information such as the entry point of the cluster, types of nodes, location, etc. according to KEP 4322. 151 | properties: 152 | lastObservedTime: 153 | description: |- 154 | LastObservedTime is the last time the property was observed on the corresponding cluster. 155 | The value is the timestamp when the property was observed not the time when the property was updated in the cluster-profile. 156 | format: date-time 157 | type: string 158 | name: 159 | description: |- 160 | Name is the name of a property resource on cluster. It's a well-known 161 | or customized name to identify the property. 162 | maxLength: 253 163 | minLength: 1 164 | type: string 165 | value: 166 | description: Value is a property-dependent string 167 | maxLength: 1024 168 | minLength: 1 169 | type: string 170 | required: 171 | - name 172 | - value 173 | type: object 174 | type: array 175 | version: 176 | description: Version defines the version information of the cluster. 177 | properties: 178 | kubernetes: 179 | description: Kubernetes is the kubernetes version of the cluster. 180 | type: string 181 | type: object 182 | type: object 183 | required: 184 | - spec 185 | type: object 186 | served: true 187 | storage: true 188 | subresources: 189 | status: {} 190 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module sigs.k8s.io/cluster-inventory-api 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/onsi/ginkgo v1.16.5 7 | github.com/onsi/gomega v1.36.1 8 | k8s.io/api v0.32.3 9 | k8s.io/apimachinery v0.32.3 10 | k8s.io/client-go v0.32.3 11 | k8s.io/code-generator v0.32.1 12 | sigs.k8s.io/controller-runtime v0.20.3 13 | ) 14 | 15 | require ( 16 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 17 | github.com/emicklei/go-restful/v3 v3.12.2 // indirect 18 | github.com/evanphx/json-patch/v5 v5.9.11 // indirect 19 | github.com/fsnotify/fsnotify v1.7.0 // indirect 20 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 21 | github.com/go-logr/logr v1.4.2 // indirect 22 | github.com/go-openapi/jsonpointer v0.21.1 // indirect 23 | github.com/go-openapi/jsonreference v0.21.0 // indirect 24 | github.com/go-openapi/swag v0.23.1 // indirect 25 | github.com/gogo/protobuf v1.3.2 // indirect 26 | github.com/golang/protobuf v1.5.4 // indirect 27 | github.com/google/gnostic-models v0.6.9 // indirect 28 | github.com/google/go-cmp v0.7.0 // indirect 29 | github.com/google/gofuzz v1.2.0 // indirect 30 | github.com/google/uuid v1.6.0 // indirect 31 | github.com/josharian/intern v1.0.0 // indirect 32 | github.com/json-iterator/go v1.1.12 // indirect 33 | github.com/mailru/easyjson v0.9.0 // indirect 34 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 35 | github.com/modern-go/reflect2 v1.0.2 // indirect 36 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 37 | github.com/nxadm/tail v1.4.8 // indirect 38 | github.com/pkg/errors v0.9.1 // indirect 39 | github.com/spf13/pflag v1.0.5 // indirect 40 | github.com/x448/float16 v0.8.4 // indirect 41 | golang.org/x/mod v0.21.0 // indirect 42 | golang.org/x/net v0.37.0 // indirect 43 | golang.org/x/oauth2 v0.28.0 // indirect 44 | golang.org/x/sync v0.12.0 // indirect 45 | golang.org/x/sys v0.31.0 // indirect 46 | golang.org/x/term v0.30.0 // indirect 47 | golang.org/x/text v0.23.0 // indirect 48 | golang.org/x/time v0.11.0 // indirect 49 | golang.org/x/tools v0.26.0 // indirect 50 | google.golang.org/protobuf v1.36.5 // indirect 51 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 52 | gopkg.in/inf.v0 v0.9.1 // indirect 53 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect 54 | gopkg.in/yaml.v3 v3.0.1 // indirect 55 | k8s.io/apiextensions-apiserver v0.32.1 // indirect 56 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect 57 | k8s.io/klog/v2 v2.130.1 // indirect 58 | k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 // indirect 59 | k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect 60 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect 61 | sigs.k8s.io/randfill v1.0.0 // indirect 62 | sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect 63 | sigs.k8s.io/yaml v1.4.0 // indirect 64 | ) 65 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 2 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 3 | github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 4 | github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 8 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 | github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= 10 | github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 11 | github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= 12 | github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= 13 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 14 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 15 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= 16 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 17 | github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= 18 | github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= 19 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 20 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 21 | github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= 22 | github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= 23 | github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= 24 | github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= 25 | github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= 26 | github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= 27 | github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= 28 | github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= 29 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= 30 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 31 | github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= 32 | github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= 33 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 34 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 35 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 36 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 37 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 38 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 39 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 40 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 41 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 42 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 43 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 44 | github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= 45 | github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= 46 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 47 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 48 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 49 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 50 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 51 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 52 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 53 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 54 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 55 | github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= 56 | github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= 57 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 58 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 59 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 60 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 61 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 62 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 63 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 64 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 65 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 66 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 67 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 68 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 69 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 70 | github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= 71 | github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= 72 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 73 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 74 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 75 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 76 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 77 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= 78 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 79 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 80 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 81 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 82 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 83 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 84 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= 85 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= 86 | github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= 87 | github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= 88 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 89 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 90 | github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= 91 | github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= 92 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 93 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 94 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 95 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 96 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 97 | github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= 98 | github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= 99 | github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= 100 | github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= 101 | github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= 102 | github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= 103 | github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= 104 | github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 105 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 106 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 107 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 108 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 109 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 110 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 111 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 112 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 113 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 114 | github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 115 | github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= 116 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 117 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 118 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 119 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 120 | go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= 121 | go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= 122 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 123 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 124 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 125 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 126 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 127 | golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= 128 | golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 129 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 130 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 131 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 132 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 133 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 134 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 135 | golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= 136 | golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 137 | golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= 138 | golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= 139 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 140 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 141 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 142 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 143 | golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= 144 | golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 145 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 146 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 147 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 148 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 149 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 150 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 151 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 152 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 153 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 154 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 155 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 156 | golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= 157 | golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 158 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 159 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 160 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 161 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 162 | golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= 163 | golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 164 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 165 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 166 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 167 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 168 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 169 | golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= 170 | golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= 171 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 172 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 173 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 174 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 175 | gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= 176 | gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= 177 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 178 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 179 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 180 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 181 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 182 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 183 | google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= 184 | google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 185 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 186 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 187 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 188 | gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= 189 | gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= 190 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 191 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 192 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 193 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 194 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 195 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 196 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 197 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 198 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 199 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 200 | k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls= 201 | k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k= 202 | k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw= 203 | k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto= 204 | k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U= 205 | k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= 206 | k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU= 207 | k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY= 208 | k8s.io/code-generator v0.32.1 h1:4lw1kFNDuFYXquTkB7Sl5EwPMUP2yyW9hh6BnFfRZFY= 209 | k8s.io/code-generator v0.32.1/go.mod h1:zaILfm00CVyP/6/pJMJ3zxRepXkxyDfUV5SNG4CjZI4= 210 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= 211 | k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= 212 | k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= 213 | k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= 214 | k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 h1:t0huyHnz6HsokckRxAF1bY0cqPFwzINKCL7yltEjZQc= 215 | k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= 216 | k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= 217 | k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 218 | sigs.k8s.io/controller-runtime v0.20.3 h1:I6Ln8JfQjHH7JbtCD2HCYHoIzajoRxPNuvhvcDbZgkI= 219 | sigs.k8s.io/controller-runtime v0.20.3/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= 220 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= 221 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= 222 | sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= 223 | sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= 224 | sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= 225 | sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= 226 | sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= 227 | sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= 228 | sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= 229 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ -------------------------------------------------------------------------------- /hack/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2024 The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import _ "k8s.io/code-generator" 24 | -------------------------------------------------------------------------------- /hack/update-codegen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2024 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | set -o errexit 22 | set -o nounset 23 | set -o pipefail 24 | 25 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 26 | CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} 27 | 28 | source "${CODEGEN_PKG}/kube_codegen.sh" 29 | 30 | THIS_PKG="sigs.k8s.io/cluster-inventory-api" 31 | 32 | kube::codegen::gen_helpers \ 33 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 34 | "${SCRIPT_ROOT}" 35 | 36 | kube::codegen::gen_client \ 37 | --with-watch \ 38 | --output-dir "${SCRIPT_ROOT}/client" \ 39 | --output-pkg "${THIS_PKG}/client" \ 40 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 41 | --one-input-api apis \ 42 | "${SCRIPT_ROOT}" 43 | -------------------------------------------------------------------------------- /test/integration/clusterprofile_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package integration 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | 23 | "github.com/onsi/ginkgo" 24 | "github.com/onsi/gomega" 25 | 26 | "k8s.io/apimachinery/pkg/api/meta" 27 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 | "k8s.io/apimachinery/pkg/util/rand" 29 | 30 | cpv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1" 31 | ) 32 | 33 | var _ = ginkgo.Describe("ClusterProfileAPI test", func() { 34 | var clusterName string 35 | var clusterManagerName string 36 | 37 | ginkgo.BeforeEach(func() { 38 | clusterName = fmt.Sprintf("cluster-%s", rand.String(5)) 39 | clusterManagerName = fmt.Sprintf("cluster-manager-%s", rand.String(5)) 40 | }) 41 | 42 | ginkgo.It("Should create a ClusterProfile", func() { 43 | clusterProfile := &cpv1alpha1.ClusterProfile{ 44 | ObjectMeta: metav1.ObjectMeta{ 45 | Name: clusterName, 46 | Labels: map[string]string{cpv1alpha1.LabelClusterManagerKey: clusterManagerName}, 47 | }, 48 | Spec: cpv1alpha1.ClusterProfileSpec{ 49 | DisplayName: clusterName, 50 | ClusterManager: cpv1alpha1.ClusterManager{ 51 | Name: clusterManagerName, 52 | }, 53 | }, 54 | } 55 | 56 | _, err := clusterProfileClient.ApisV1alpha1().ClusterProfiles(testNamespace).Create( 57 | context.TODO(), 58 | clusterProfile, 59 | metav1.CreateOptions{}, 60 | ) 61 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 62 | }) 63 | 64 | ginkgo.It("Should update the ClusterProfile status", func() { 65 | clusterProfile := &cpv1alpha1.ClusterProfile{ 66 | ObjectMeta: metav1.ObjectMeta{ 67 | Name: clusterName, 68 | Labels: map[string]string{cpv1alpha1.LabelClusterManagerKey: clusterManagerName}, 69 | }, 70 | Spec: cpv1alpha1.ClusterProfileSpec{ 71 | DisplayName: clusterName, 72 | ClusterManager: cpv1alpha1.ClusterManager{ 73 | Name: clusterManagerName, 74 | }, 75 | }, 76 | } 77 | 78 | clusterProfile, err := clusterProfileClient.ApisV1alpha1().ClusterProfiles(testNamespace).Create( 79 | context.TODO(), 80 | clusterProfile, 81 | metav1.CreateOptions{}, 82 | ) 83 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 84 | 85 | newClusterProfile := clusterProfile.DeepCopy() 86 | newClusterProfile.Status.Version.Kubernetes = "1.29.0" 87 | newClusterProfile.Status.Properties = []cpv1alpha1.Property{{Name: "n1", Value: "v1"}} 88 | meta.SetStatusCondition(&newClusterProfile.Status.Conditions, metav1.Condition{ 89 | Type: cpv1alpha1.ClusterConditionControlPlaneHealthy, 90 | Status: metav1.ConditionTrue, 91 | Reason: "Reason", 92 | Message: "Message", 93 | }) 94 | 95 | _, err = clusterProfileClient.ApisV1alpha1().ClusterProfiles(testNamespace).UpdateStatus( 96 | context.TODO(), 97 | newClusterProfile, 98 | metav1.UpdateOptions{}, 99 | ) 100 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 101 | }) 102 | }) 103 | -------------------------------------------------------------------------------- /test/integration/suite_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package integration 18 | 19 | import ( 20 | "context" 21 | "path/filepath" 22 | "testing" 23 | 24 | corev1 "k8s.io/api/core/v1" 25 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | "k8s.io/apimachinery/pkg/util/rand" 27 | 28 | "github.com/onsi/ginkgo" 29 | "github.com/onsi/gomega" 30 | 31 | "k8s.io/client-go/kubernetes" 32 | "sigs.k8s.io/controller-runtime/pkg/envtest" 33 | 34 | cpclientset "sigs.k8s.io/cluster-inventory-api/client/clientset/versioned" 35 | ) 36 | 37 | var testEnv *envtest.Environment 38 | var testNamespace string 39 | var kubernetesClient kubernetes.Interface 40 | var clusterProfileClient cpclientset.Interface 41 | 42 | func TestIntegration(t *testing.T) { 43 | gomega.RegisterFailHandler(ginkgo.Fail) 44 | ginkgo.RunSpecs(t, "API Validation Integration Suite") 45 | } 46 | 47 | var _ = ginkgo.BeforeSuite(func(done ginkgo.Done) { 48 | ginkgo.By("bootstrapping test environment") 49 | 50 | // start a kube-apiserver 51 | testEnv = &envtest.Environment{ 52 | ErrorIfCRDPathMissing: true, 53 | CRDDirectoryPaths: []string{ 54 | filepath.Join("../../", "config", "crd", "bases"), 55 | }, 56 | } 57 | 58 | cfg, err := testEnv.Start() 59 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 60 | gomega.Expect(cfg).ToNot(gomega.BeNil()) 61 | 62 | clusterProfileClient, err = cpclientset.NewForConfig(cfg) 63 | gomega.Expect(err).NotTo(gomega.HaveOccurred()) 64 | kubernetesClient, err = kubernetes.NewForConfig(cfg) 65 | gomega.Expect(err).NotTo(gomega.HaveOccurred()) 66 | 67 | testNamespace = "cluster-profile-api-test-" + rand.String(5) 68 | _, err = kubernetesClient.CoreV1().Namespaces(). 69 | Create(context.TODO(), &corev1.Namespace{ 70 | ObjectMeta: metav1.ObjectMeta{ 71 | Name: testNamespace, 72 | }, 73 | }, metav1.CreateOptions{}) 74 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 75 | 76 | close(done) 77 | }, 300) 78 | 79 | var _ = ginkgo.AfterSuite(func() { 80 | ginkgo.By("tearing down the test environment") 81 | 82 | // Skip if client wasn't instantiated 83 | if kubernetesClient != nil { 84 | err := kubernetesClient.CoreV1().Namespaces(). 85 | Delete(context.TODO(), testNamespace, metav1.DeleteOptions{}) 86 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 87 | 88 | err = testEnv.Stop() 89 | gomega.Expect(err).ToNot(gomega.HaveOccurred()) 90 | } 91 | }) 92 | --------------------------------------------------------------------------------