├── .gitignore ├── .golangci.yml ├── .mdlrc ├── CONTRIBUTING.md ├── GETTING-STARTED.md ├── LICENSE ├── MAINTAINERS.md ├── Makefile ├── README.md ├── api ├── apis.go └── v1alpha1 │ ├── condition_consts.go │ ├── condition_types.go │ ├── contentlibraryprovider_types.go │ ├── contentsource_types.go │ ├── contentsourcebinding_types.go │ ├── doc.go │ ├── groupversion_info.go │ ├── install │ └── install.go │ ├── virtualmachine_types.go │ ├── virtualmachineclass_types.go │ ├── virtualmachineclassbinding_types.go │ ├── virtualmachineimage_types.go │ ├── virtualmachinepublishrequest_types.go │ ├── virtualmachineservice_types.go │ ├── virtualmachinesetresourcepolicy_types.go │ ├── virtualmachinetempl_types.go │ ├── webconsolerequest_types.go │ └── zz_generated.deepcopy.go ├── cspell.config.yaml ├── go.mod ├── go.sum └── hack ├── boilerplate └── boilerplate.go.txt ├── samples ├── Makefile ├── README.md ├── controller │ └── list.go ├── go.mod └── go.sum └── tools ├── Makefile ├── README.md ├── go.mod ├── go.sum └── tools.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | bin 8 | .DS_Store 9 | vendor 10 | 11 | # Test binary, build with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Kubernetes Generated files - skip generated files, except for vendored files 18 | 19 | #!vendor/**/zz_generated.* 20 | 21 | # editor and IDE paraphernalia 22 | .idea 23 | *.swp 24 | *.swo 25 | *~ 26 | 27 | # generated config files 28 | config/ 29 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | deadline: 5m 3 | skip-files: 4 | - ".*generated.*\\.go" 5 | 6 | linters-settings: 7 | goimports: 8 | local-prefixes: github.com/vmware-tanzu 9 | importas: 10 | no-unaliased: true 11 | alias: 12 | - pkg: k8s.io/api/core/v1 13 | alias: corev1 14 | - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 15 | alias: metav1 16 | 17 | linters: 18 | disable-all: true 19 | enable: 20 | - asciicheck 21 | - bodyclose 22 | - deadcode 23 | - depguard 24 | - dogsled 25 | - errcheck 26 | - exportloopref 27 | - goconst 28 | - gocritic 29 | - gocyclo 30 | - godot 31 | - gofmt 32 | - goimports 33 | - goprintffuncname 34 | - gosec 35 | - gosimple 36 | - govet 37 | - importas 38 | - ineffassign 39 | - nakedret 40 | - nilerr 41 | - nolintlint 42 | - prealloc 43 | - revive 44 | - rowserrcheck 45 | - staticcheck 46 | - structcheck 47 | - stylecheck 48 | - typecheck 49 | - unconvert 50 | - unparam 51 | - varcheck 52 | 53 | issues: 54 | max-same-issues: 0 55 | max-issues-per-linter: 0 56 | # Disable the default golangci exclusions so no issues are skipped. 57 | # This will help reviewers to focus on reviewing the most relevant changes in 58 | # the PRs and avoid nitpicking. 59 | exclude-use-default: false 60 | exclude: 61 | # TODO: Remove the following exclusions over time once we have fixed those. 62 | - "ST1000: at least one file in a package should have a package comment" 63 | # List of regexps of issue texts to exclude, empty list by default. 64 | exclude-rules: 65 | - linters: 66 | - revive 67 | text: ".*should have comment.* or be unexported" 68 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD013" -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to vm-operator-api 2 | 3 | It's still early days for vm-operator-api, but we would love to connect with people who are as passionate about Kubernetes and Virtual Machines as we are! 4 | 5 | Please raise issues and feel free to open PRs. 6 | 7 | Any suggestions on usability, readability, clarity or architecture are all welcome. 8 | 9 | Given that vm-operator-api is currently the API surface to a larger project, please be aware that we must consider the wider impact of any API changes. -------------------------------------------------------------------------------- /GETTING-STARTED.md: -------------------------------------------------------------------------------- 1 | # Get Started with vm-operator-api 2 | 3 | This guide will walk you through the process of integrating vm-operator-api into your project 4 | 5 | ## Prerequisites 6 | 7 | The vm-operator-api project currently requires a ESXi cluster in vSphere 7 with Kubernetes. 8 | 9 | What this means in functional terms is that you can manage workloads in a given Workload Namespace using a Kubernetes client connected directly to the an embedded Kubernetes API Server running in the vSphere cluster. With the correct privileges, you can create CRD objects in your vSphere cluster which are reconciled into vSphere objects - everything from a single VM (`VirtualMachine`) to a full virtualized Kubernetes Cluster (`TanzuKubernetesCluster`) 10 | 11 | The vm-operator-api APIs currently allow you to monitor VirtualMachine objects that exist in the target namespace and before long, it will also allow you to create and manage them. 12 | 13 | ## Step 1: Verify client access 14 | 15 | Check your client access by viewing VirtualMachines in the target cluster 16 | 17 | ```bash 18 | kubectl get VirtualMachines --all 19 | ``` 20 | 21 | ## Step 2: Build and Test the sample code 22 | 23 | ```bash 24 | cd hack/samples 25 | make all 26 | bin/list-ctrl 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # vm-operator-api Maintainers 2 | 3 | ## Maintainers 4 | 5 | | Maintainer | GitHub ID | Affiliation | 6 | | --------------- | --------- | ----------- | 7 | | Bryan Venteicher | [bryanv](https://github.com/bryanv) | [VMware](https://www.github.com/vmware/) | 8 | | Derek Beard | [derekbeard](https://github.com/derekbeard) | [VMware](https://www.github.com/vmware/) | 9 | | Zach Shepherd |[zjs](https://github.com/zjs)| [VMware](https://www.github.com/vmware/) | 10 | | Ben Corrie | [corrieb](https://github.com/corrieb) | [VMware](https://www.github.com/vmware/) | 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # If you update this file, please follow 2 | # https://suva.sh/posts/well-documented-makefiles 3 | 4 | # Ensure Make is run with bash shell as some syntax below is bash-specific 5 | SHELL := /usr/bin/env bash 6 | 7 | .DEFAULT_GOAL := help 8 | 9 | # Active module mode, as we use go modules to manage dependencies 10 | export GO111MODULE := on 11 | 12 | # Directories 13 | BIN_DIR := bin 14 | TOOLS_DIR := hack/tools 15 | TOOLS_BIN_DIR := $(TOOLS_DIR)/bin 16 | export PATH := $(abspath $(BIN_DIR)):$(abspath $(TOOLS_BIN_DIR)):$(PATH) 17 | 18 | # Tooling binaries 19 | CONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen 20 | GOLANGCI_LINT := $(TOOLS_BIN_DIR)/golangci-lint 21 | 22 | # Allow overriding manifest generation destination directory 23 | MANIFEST_ROOT ?= config 24 | CRD_ROOT ?= $(MANIFEST_ROOT)/crd/bases 25 | 26 | .PHONY: all 27 | all: lint tools generate ## Runs tests and generates all components 28 | 29 | ## -------------------------------------- 30 | ##@ Help 31 | ## -------------------------------------- 32 | 33 | help: ## Display this help 34 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-18s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 35 | 36 | ## -------------------------------------- 37 | ##@ Tooling 38 | ## -------------------------------------- 39 | 40 | TOOLING_BINARIES := $(CONTROLLER_GEN) $(GOLANGCI_LINT) 41 | tools: $(TOOLING_BINARIES) ## Build tooling binaries 42 | .PHONY: $(TOOLING_BINARIES) 43 | $(TOOLING_BINARIES): 44 | make -C $(TOOLS_DIR) $(@F) 45 | 46 | ## -------------------------------------- 47 | ##@ Generate 48 | ## -------------------------------------- 49 | 50 | .PHONY: modules 51 | modules: ## Validates the modules 52 | go mod tidy 53 | 54 | .PHONY: modules-download 55 | modules-download: ## Downloads and caches the modules 56 | go mod download 57 | 58 | .PHONY: generate 59 | generate: ## Run all code generation targets 60 | $(MAKE) generate-go 61 | $(MAKE) generate-manifests 62 | 63 | .PHONY: generate-go 64 | generate-go: $(CONTROLLER_GEN) ## Runs Go related generate targets 65 | $(CONTROLLER_GEN) \ 66 | paths=./api/... \ 67 | object:headerFile="$(abspath hack/boilerplate/boilerplate.go.txt)" 68 | ifneq (0,$(GENERATE_CODE)) 69 | go generate ./... 70 | endif 71 | 72 | .PHONY: generate-manifests 73 | generate-manifests: $(CONTROLLER_GEN) ## Generate manifests e.g. CRD, RBAC etc. 74 | $(CONTROLLER_GEN) \ 75 | paths=./api/... \ 76 | crd:crdVersions=v1 \ 77 | output:crd:dir=$(CRD_ROOT) \ 78 | output:none 79 | 80 | ## -------------------------------------- 81 | ##@ Linting 82 | ## -------------------------------------- 83 | 84 | .PHONY: lint 85 | lint: ## Run all the lint targets 86 | $(MAKE) lint-go-full 87 | $(MAKE) lint-markdown 88 | $(MAKE) lint-spell 89 | # $(MAKE) lint-shell 90 | 91 | GOLANGCI_LINT_FLAGS ?= --fast=true 92 | .PHONY: lint-go 93 | lint-go: $(GOLANGCI_LINT) ## Lint codebase 94 | $(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_FLAGS) 95 | 96 | .PHONY: lint-go-full 97 | lint-go-full: GOLANGCI_LINT_FLAGS = --fast=false 98 | lint-go-full: lint-go ## Run slower linters to detect possible issues 99 | 100 | .PHONY: lint-markdown 101 | lint-markdown: ## Lint the project's markdown 102 | docker run --rm -v $$(pwd):/mnt mivok/markdownlint -c /mnt/.mdlrc /mnt 103 | 104 | .PHONY: lint-shell 105 | lint-shell: ## Lint the project's shell scripts 106 | docker run --rm -v "$$(pwd)":/mnt:ro koalaman/shellcheck:stable $$(ls hack/*.sh) 107 | 108 | .PHONY: lint-spell 109 | CSPELL_ARGS := lint './**/*' 110 | lint-spell: ## Lint the project's spelling 111 | ifneq (,$(shell command -v cspell)) 112 | cspell $(CSPELL_ARGS) 113 | else 114 | docker run --rm -v "$$(pwd)":/workdir:ro ghcr.io/streetsidesoftware/cspell:6.12.0 $(CSPELL_ARGS) 115 | endif 116 | 117 | 118 | ## -------------------------------------- 119 | ##@ Cleanup 120 | ## -------------------------------------- 121 | 122 | .PHONY: clean 123 | clean: # Clean all generated or compiled files 124 | $(MAKE) clean-bin 125 | $(MAKE) clean-crd 126 | $(MAKE) modules 127 | 128 | .PHONY: clean-bin 129 | clean-bin: ## Remove all generated tooling binaries 130 | rm -rf hack/tools/bin 131 | rm -rf hack/samples/bin 132 | 133 | .PHONY: clean-crd 134 | clean-crd: ## Remove all generated crds 135 | rm -rf config/crd 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VM Operator API 2 | 3 | --- 4 | 5 | :warning: **Relocated** 6 | 7 | The VM Operator API repository has been deprecated and relocated into the [`./api` package](https://github.com/vmware-tanzu/vm-operator/tree/main/api) of the [VM Operator project](https://github.com/vmware-tanzu/vm-operator/). Please file any new pull requests, issues, etc. in the new location. Thank you! 8 | 9 | --- 10 | -------------------------------------------------------------------------------- /api/apis.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Generate deepcopy for apis 5 | // go:generate go run k8s.io/code-generator/cmd/deepcopy-gen -O zz_generated.deepcopy -i ./... 6 | 7 | // Package apis contains Kubernetes API groups. 8 | package apis 9 | 10 | import ( 11 | "k8s.io/apimachinery/pkg/runtime" 12 | ) 13 | 14 | // AddToSchemes may be used to add all resources defined in the project to a Scheme. 15 | var AddToSchemes runtime.SchemeBuilder 16 | 17 | // AddToScheme adds all Resources to the Scheme. 18 | func AddToScheme(s *runtime.Scheme) error { 19 | return AddToSchemes.AddToScheme(s) 20 | } 21 | -------------------------------------------------------------------------------- /api/v1alpha1/condition_consts.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | // Common ConditionTypes used by VM Operator API objects. 7 | const ( 8 | // ReadyCondition defines the Ready condition type that summarizes the operational state of a VM Operator API object. 9 | ReadyCondition ConditionType = "Ready" 10 | ) 11 | 12 | // Conditions and condition Reasons for the VirtualMachine object. 13 | 14 | const ( 15 | // VirtualMachinePrereqReadyCondition documents that all of a VirtualMachine's prerequisites declared in the spec 16 | // (e.g. VirtualMachineClass) are satisfied. 17 | VirtualMachinePrereqReadyCondition ConditionType = "VirtualMachinePrereqReady" 18 | 19 | // VirtualMachineClassBindingNotFoundReason (Severity=Error) documents a missing VirtualMachineClassBinding for the 20 | // VirtualMachineClass specified in the VirtualMachineSpec. 21 | VirtualMachineClassBindingNotFoundReason = "VirtualMachineClassBindingNotFound" 22 | 23 | // VirtualMachineClassNotFoundReason (Severity=Error) documents that the VirtualMachineClass specified in the VirtualMachineSpec 24 | // is not available. 25 | VirtualMachineClassNotFoundReason = "VirtualMachineClassNotFound" 26 | 27 | // ContentSourceBindingNotFoundReason (Severity=Error) documents a missing ContentSourceBinding for the 28 | // VirtualMachineImage specified in the VirtualMachineSpec. 29 | ContentSourceBindingNotFoundReason = "ContentSourceBindingNotFound" 30 | 31 | // ContentLibraryProviderNotFoundReason (Severity=Error) documents that the ContentLibraryProvider corresponding to a VirtualMachineImage 32 | // is not available. 33 | ContentLibraryProviderNotFoundReason = "ContentLibraryProviderNotFound" 34 | 35 | // VirtualMachineImageNotFoundReason (Severity=Error) documents that the VirtualMachineImage specified in the VirtualMachineSpec 36 | // is not available. 37 | VirtualMachineImageNotFoundReason = "VirtualMachineImageNotFound" 38 | 39 | // VirtualMachineImageNotReadyReason (Severity=Error) documents that the VirtualMachineImage specified in the VirtualMachineSpec 40 | // is not ready. 41 | VirtualMachineImageNotReadyReason = "VirtualMachineImageNotReady" 42 | ) 43 | 44 | const ( 45 | // GuestCustomizationCondition exposes the status of guest customization from within the guest OS, when available. 46 | GuestCustomizationCondition ConditionType = "GuestCustomization" 47 | 48 | // GuestCustomizationIdleReason (Severity=Info) documents that guest customizations were not applied for the VirtualMachine. 49 | GuestCustomizationIdleReason = "GuestCustomizationIdle" 50 | 51 | // GuestCustomizationPendingReason (Severity=Info) documents that guest customization is still pending within the guest OS. 52 | GuestCustomizationPendingReason = "GuestCustomizationPending" 53 | 54 | // GuestCustomizationRunningReason (Severity=Info) documents that the guest customization is now running on the guest OS. 55 | GuestCustomizationRunningReason = "GuestCustomizationRunning" 56 | 57 | // GuestCustomizationSucceededReason (Severity=Info) documents that the guest customization succeeded within the guest OS. 58 | GuestCustomizationSucceededReason = "GuestCustomizationSucceeded" 59 | 60 | // GuestCustomizationFailedReason (Severity=Error) documents that the guest customization failed within the guest OS. 61 | GuestCustomizationFailedReason = "GuestCustomizationFailed" 62 | ) 63 | 64 | const ( 65 | // VirtualMachineToolsCondition exposes the status of VMware Tools running in the guest OS, when available. 66 | VirtualMachineToolsCondition ConditionType = "VirtualMachineTools" 67 | 68 | // VirtualMachineToolsNotRunningReason (Severity=Error) documents that VMware Tools is not running. 69 | VirtualMachineToolsNotRunningReason = "VirtualMachineToolsNotRunning" 70 | 71 | // VirtualMachineToolsRunningReason (Severity=Info) documents that VMware Tools is running. 72 | VirtualMachineToolsRunningReason = "VirtualMachineToolsRunning" 73 | ) 74 | 75 | // Common Condition.Reason used by VM Operator API objects. 76 | const ( 77 | // DeletingReason (Severity=Info) documents a condition not in Status=True because the underlying object it is currently being deleted. 78 | DeletingReason = "Deleting" 79 | 80 | // DeletionFailedReason (Severity=Warning) documents a condition not in Status=True because the underlying object 81 | // encountered problems during deletion. This is a warning because the reconciler will retry deletion. 82 | DeletionFailedReason = "DeletionFailed" 83 | 84 | // DeletedReason (Severity=Info) documents a condition not in Status=True because the underlying object was deleted. 85 | DeletedReason = "Deleted" 86 | ) 87 | 88 | // Conditions related to the VirtualMachineImages. 89 | const ( 90 | // Deprecated 91 | // VirtualMachineImageOSTypeSupportedCondition denotes that the OS type in the VirtualMachineImage object is 92 | // supported by VMService. A VirtualMachineImageOsTypeSupportedCondition is marked true: 93 | // - If OS Type is of Linux Family 94 | // - If OS Type is supported by hosts in the cluster. 95 | VirtualMachineImageOSTypeSupportedCondition ConditionType = "VirtualMachineImageOSTypeSupported" 96 | 97 | // VirtualMachineImageV1Alpha1CompatibleCondition denotes image compatibility with VMService. VMService expects 98 | // VirtualMachineImage to be prepared by VMware specifically for VMService v1alpha1. 99 | VirtualMachineImageV1Alpha1CompatibleCondition ConditionType = "VirtualMachineImageV1Alpha1Compatible" 100 | 101 | // VirtualMachineImageSyncedCondition denotes that the image is synced with the vSphere content library item 102 | // that contains the source of this image's information. 103 | VirtualMachineImageSyncedCondition ConditionType = "VirtualMachineImageSynced" 104 | 105 | // VirtualMachineImageProviderReadyCondition denotes readiness of the VirtualMachineImage provider. 106 | VirtualMachineImageProviderReadyCondition ConditionType = "VirtualMachineImageProviderReady" 107 | ) 108 | 109 | // Condition.Reason for Conditions related to VirtualMachineImages. 110 | const ( 111 | // Deprecated 112 | // VirtualMachineImageOSTypeNotSupportedReason (Severity=Error) documents that OS Type is VirtualMachineImage is 113 | // not supported. 114 | VirtualMachineImageOSTypeNotSupportedReason = "VirtualMachineImageOSTypeNotSupported" 115 | 116 | // VirtualMachineImageV1Alpha1NotCompatibleReason (Severity=Error) documents that the VirtualMachineImage 117 | // is not prepared for VMService consumption. 118 | VirtualMachineImageV1Alpha1NotCompatibleReason = "VirtualMachineImageV1Alpha1NotCompatible" 119 | 120 | // VirtualMachineImageNotSyncedReason (Severity=Error) documents that the VirtualMachineImage is not synced with 121 | // the vSphere content library item that contains the source of this image's information. 122 | VirtualMachineImageNotSyncedReason = "VirtualMachineImageNotSynced" 123 | 124 | // VirtualMachineImageProviderNotReadyReason (Severity=Error) documents that the VirtualMachineImage provider 125 | // is not in ready state. 126 | VirtualMachineImageProviderNotReadyReason = "VirtualMachineImageProviderNotReady" 127 | ) 128 | -------------------------------------------------------------------------------- /api/v1alpha1/condition_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 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 | corev1 "k8s.io/api/core/v1" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | // ConditionSeverity expresses the severity of a Condition Type failing. 25 | type ConditionSeverity string 26 | 27 | const ( 28 | // ConditionSeverityError specifies that a condition with `Status=False` is an error. 29 | ConditionSeverityError ConditionSeverity = "Error" 30 | 31 | // ConditionSeverityWarning specifies that a condition with `Status=False` is a warning. 32 | ConditionSeverityWarning ConditionSeverity = "Warning" 33 | 34 | // ConditionSeverityInfo specifies that a condition with `Status=False` is informative. 35 | ConditionSeverityInfo ConditionSeverity = "Info" 36 | 37 | // ConditionSeverityNone should apply only to conditions with `Status=True`. 38 | ConditionSeverityNone ConditionSeverity = "" 39 | ) 40 | 41 | // ConditionType is a valid value for Condition.Type. 42 | type ConditionType string 43 | 44 | // Condition defines an observation of a VM Operator API resource operational state. 45 | type Condition struct { 46 | // Type of condition in CamelCase or in foo.example.com/CamelCase. 47 | // Many .condition.type values are consistent across resources like Available, but because arbitrary conditions 48 | // can be useful (see .node.status.conditions), the ability to disambiguate is important. 49 | // +required 50 | Type ConditionType `json:"type"` 51 | 52 | // Status of the condition, one of True, False, Unknown. 53 | // +required 54 | Status corev1.ConditionStatus `json:"status"` 55 | 56 | // Severity provides an explicit classification of Reason code, so the users or machines can immediately 57 | // understand the current situation and act accordingly. 58 | // The Severity field MUST be set only when Status=False. 59 | // +optional 60 | Severity ConditionSeverity `json:"severity,omitempty"` 61 | 62 | // Last time the condition transitioned from one status to another. 63 | // This should be when the underlying condition changed. If that is not known, then using the time when 64 | // the API field changed is acceptable. 65 | // +required 66 | LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` 67 | 68 | // The reason for the condition's last transition in CamelCase. 69 | // The specific API may choose whether or not this field is considered a guaranteed API. 70 | // This field may not be empty. 71 | // +optional 72 | Reason string `json:"reason,omitempty"` 73 | 74 | // A human readable message indicating details about the transition. 75 | // This field may be empty. 76 | // +optional 77 | Message string `json:"message,omitempty"` 78 | } 79 | 80 | // Conditions provide observations of the operational state of a VM Operator API resource. 81 | type Conditions []Condition 82 | -------------------------------------------------------------------------------- /api/v1alpha1/contentlibraryprovider_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // ContentLibraryProviderSpec defines the desired state of ContentLibraryProvider. 11 | type ContentLibraryProviderSpec struct { 12 | // UUID describes the UUID of a vSphere content library. It is the unique identifier for a 13 | // vSphere content library. 14 | UUID string `json:"uuid,omitempty"` 15 | } 16 | 17 | // ContentLibraryProviderStatus defines the observed state of ContentLibraryProvider 18 | // Can include fields indicating when was the last time VM images were updated from a library. 19 | type ContentLibraryProviderStatus struct { 20 | } 21 | 22 | // +kubebuilder:object:root=true 23 | // +kubebuilder:resource:scope=Cluster 24 | // +kubebuilder:printcolumn:name="Content-Library-UUID",type="string",JSONPath=".spec.uuid",description="UUID of the vSphere content library" 25 | 26 | // ContentLibraryProvider is the Schema for the contentlibraryproviders API. 27 | type ContentLibraryProvider struct { 28 | metav1.TypeMeta `json:",inline"` 29 | metav1.ObjectMeta `json:"metadata,omitempty"` 30 | 31 | Spec ContentLibraryProviderSpec `json:"spec,omitempty"` 32 | Status ContentLibraryProviderStatus `json:"status,omitempty"` 33 | } 34 | 35 | // +kubebuilder:object:root=true 36 | 37 | // ContentLibraryProviderList contains a list of ContentLibraryProvider. 38 | type ContentLibraryProviderList struct { 39 | metav1.TypeMeta `json:",inline"` 40 | metav1.ListMeta `json:"metadata,omitempty"` 41 | Items []ContentLibraryProvider `json:"items"` 42 | } 43 | 44 | func init() { 45 | RegisterTypeWithScheme(&ContentLibraryProvider{}, &ContentLibraryProviderList{}) 46 | } 47 | -------------------------------------------------------------------------------- /api/v1alpha1/contentsource_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // ContentProviderReference contains the info to locate a content provider resource. 11 | type ContentProviderReference struct { 12 | // API version of the referent. 13 | APIVersion string `json:"apiVersion,omitempty"` 14 | // Kind is the type of resource being referenced. 15 | Kind string `json:"kind"` 16 | // Name is the name of resource being referenced. 17 | Name string `json:"name"` 18 | // Namespace of the resource being referenced. If empty, cluster scoped resource is assumed. 19 | Namespace string `json:"namespace,omitempty"` 20 | } 21 | 22 | // ContentSourceSpec defines the desired state of ContentSource. 23 | type ContentSourceSpec struct { 24 | // ProviderRef is a reference to a content provider object that describes a provider. 25 | ProviderRef ContentProviderReference `json:"providerRef,omitempty"` 26 | } 27 | 28 | // ContentSourceStatus defines the observed state of ContentSource. 29 | type ContentSourceStatus struct { 30 | } 31 | 32 | // +kubebuilder:object:root=true 33 | // +kubebuilder:resource:scope=Cluster 34 | 35 | // ContentSource is the Schema for the contentsources API. 36 | // A ContentSource represents the desired specification and the observed status of a ContentSource instance. 37 | type ContentSource struct { 38 | metav1.TypeMeta `json:",inline"` 39 | metav1.ObjectMeta `json:"metadata,omitempty"` 40 | 41 | Spec ContentSourceSpec `json:"spec,omitempty"` 42 | Status ContentSourceStatus `json:"status,omitempty"` 43 | } 44 | 45 | // +kubebuilder:object:root=true 46 | 47 | // ContentSourceList contains a list of ContentSource. 48 | type ContentSourceList struct { 49 | metav1.TypeMeta `json:",inline"` 50 | metav1.ListMeta `json:"metadata,omitempty"` 51 | Items []ContentSource `json:"items"` 52 | } 53 | 54 | func init() { 55 | RegisterTypeWithScheme(&ContentSource{}, &ContentSourceList{}) 56 | } 57 | -------------------------------------------------------------------------------- /api/v1alpha1/contentsourcebinding_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // ContentSourceReference contains info to locate a Kind ContentSource object. 11 | type ContentSourceReference struct { 12 | // API version of the referent. 13 | APIVersion string `json:"apiVersion,omitempty"` 14 | // Kind is the type of resource being referenced. 15 | Kind string `json:"kind,omitempty"` 16 | // Name is the name of resource being referenced. 17 | Name string `json:"name"` 18 | } 19 | 20 | // +kubebuilder:object:root=true 21 | // +kubebuilder:resource:scope=Namespaced 22 | 23 | // ContentSourceBinding is an object that represents a ContentSource to Namespace mapping. 24 | type ContentSourceBinding struct { 25 | metav1.TypeMeta `json:",inline"` 26 | metav1.ObjectMeta `json:"metadata,omitempty"` 27 | 28 | // ContentSourceRef is a reference to a ContentSource object. 29 | ContentSourceRef ContentSourceReference `json:"contentSourceRef,omitempty"` 30 | } 31 | 32 | // +kubebuilder:object:root=true 33 | 34 | // ContentSourceBindingList contains a list of ContentSourceBinding. 35 | type ContentSourceBindingList struct { 36 | metav1.TypeMeta `json:",inline"` 37 | metav1.ListMeta `json:"metadata,omitempty"` 38 | Items []ContentSourceBinding `json:"items"` 39 | } 40 | 41 | func init() { 42 | RegisterTypeWithScheme(&ContentSourceBinding{}, &ContentSourceBindingList{}) 43 | } 44 | -------------------------------------------------------------------------------- /api/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package v1alpha1 contains the VM Operator v1alpha1 APIs. 5 | // 6 | // +k8s:openapi-gen=true 7 | // +kubebuilder:object:generate=true 8 | // +groupName=vmoperator.vmware.com 9 | package v1alpha1 10 | -------------------------------------------------------------------------------- /api/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "k8s.io/apimachinery/pkg/runtime" 9 | "k8s.io/apimachinery/pkg/runtime/schema" 10 | ) 11 | 12 | // GroupName specifies the group name used to register the objects. 13 | const GroupName = "vmoperator.vmware.com" 14 | 15 | var ( 16 | // SchemeGroupVersion is group version used to register these objects. 17 | SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} 18 | 19 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme. 20 | SchemeBuilder = &runtime.SchemeBuilder{} 21 | 22 | // AddToScheme adds the types in this group-version to the given scheme. 23 | AddToScheme = SchemeBuilder.AddToScheme 24 | ) 25 | 26 | // Resource takes an unqualified resource and returns a Group qualified GroupResource. 27 | func Resource(resource string) schema.GroupResource { 28 | return SchemeGroupVersion.WithResource(resource).GroupResource() 29 | } 30 | 31 | // RegisterTypeWithScheme adds objects to the SchemeBuilder. 32 | func RegisterTypeWithScheme(object ...runtime.Object) { 33 | SchemeBuilder.Register(func(scheme *runtime.Scheme) error { 34 | scheme.AddKnownTypes(SchemeGroupVersion, object...) 35 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 36 | return nil 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /api/v1alpha1/install/install.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package install installs the API group, making it available as 5 | // an option to all of the API encoding/decoding machinery. 6 | package install 7 | 8 | import ( 9 | "k8s.io/apimachinery/pkg/runtime" 10 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 11 | 12 | "github.com/vmware-tanzu/vm-operator-api/api/v1alpha1" 13 | ) 14 | 15 | // Install registers the API group and adds types to a scheme. 16 | func Install(scheme *runtime.Scheme) { 17 | utilruntime.Must(v1alpha1.AddToScheme(scheme)) 18 | } 19 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachine_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | corev1 "k8s.io/api/core/v1" 8 | "k8s.io/apimachinery/pkg/api/resource" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/apimachinery/pkg/util/intstr" 11 | ) 12 | 13 | // See govmomi.vim25.types.VirtualMachinePowerState. 14 | const ( 15 | VirtualMachinePoweredOff VirtualMachinePowerState = "poweredOff" 16 | VirtualMachinePoweredOn VirtualMachinePowerState = "poweredOn" 17 | ) 18 | 19 | // VirtualMachinePowerState represents the power state of a VirtualMachine. 20 | // The value values are "poweredOn", and "poweredOff". 21 | // +kubebuilder:validation:Enum=poweredOff;poweredOn 22 | type VirtualMachinePowerState string 23 | 24 | // VMStatusPhase is used to indicate the phase of a VirtualMachine's lifecycle. 25 | type VMStatusPhase string 26 | 27 | const ( 28 | // Creating phase indicates that the VirtualMachine is being created by the backing infrastructure provider. 29 | Creating VMStatusPhase = "Creating" 30 | 31 | // Created phase indicates that the VirtualMachine has been already been created by the backing infrastructure 32 | // provider. 33 | Created VMStatusPhase = "Created" 34 | 35 | // Deleting phase indicates that the VirtualMachine is being deleted by the backing infrastructure provider. 36 | Deleting VMStatusPhase = "Deleting" 37 | 38 | // Deleted phase indicates that the VirtualMachine has been deleted by the backing infrastructure provider. 39 | Deleted VMStatusPhase = "Deleted" 40 | 41 | // Unknown phase indicates that the VirtualMachine status cannot be determined from the backing infrastructure 42 | // provider. 43 | Unknown VMStatusPhase = "Unknown" 44 | ) 45 | 46 | const ( 47 | // PauseAnnotation is an annotation that can be applied to any VirtualMachine object to prevent VM Operator from 48 | // reconciling the object with the vSphere infrastructure. VM Operator checks the presence of this annotation to 49 | // skip the reconcile of a VirtualMachine. 50 | // 51 | // This can be used when a Virtual Machine needs to be modified out-of-band of VM Operator on the infrastructure 52 | // directly (e.g., during a VADP based Restore operation). 53 | PauseAnnotation = GroupName + "/pause-reconcile" 54 | 55 | // NoDefaultNicAnnotation is an annotation that can be applied to prevent VM Operator from creating a default nic for 56 | // a VirtualMachine object with empty VirtualMachineNetworkInterfaces list. 57 | // 58 | // This can be used when users want to opt out a default network device when creating new VirtualMachines. 59 | // 60 | // When a VM without any VirtualMachineNetworkInterfaces is being created, VM Operator webhook checks the presence of 61 | // this annotation to skip adding a default nic. VM Operator won't add default NIC to any existing VMs or new VMs 62 | // with VirtualMachineNetworkInterfaces specified. This annotation is not required for such VMs. 63 | NoDefaultNicAnnotation = GroupName + "/no-default-nic" 64 | ) 65 | 66 | // VirtualMachinePort is unused and can be considered deprecated. 67 | type VirtualMachinePort struct { 68 | Port int `json:"port"` 69 | Ip string `json:"ip"` //nolint:revive,stylecheck 70 | Name string `json:"name"` 71 | Protocol corev1.Protocol `json:"protocol"` 72 | } 73 | 74 | // NetworkInterfaceProviderReference contains info to locate a network interface provider object. 75 | type NetworkInterfaceProviderReference struct { 76 | // APIGroup is the group for the resource being referenced. 77 | APIGroup string `json:"apiGroup"` 78 | // Kind is the type of resource being referenced 79 | Kind string `json:"kind"` 80 | // Name is the name of resource being referenced 81 | Name string `json:"name"` 82 | // API version of the referent. 83 | APIVersion string `json:"apiVersion,omitempty"` 84 | } 85 | 86 | // VirtualMachineNetworkInterface defines the properties of a network interface to attach to a VirtualMachine 87 | // instance. A VirtualMachineNetworkInterface describes network interface configuration that is used by the 88 | // VirtualMachine controller when integrating the VirtualMachine into a VirtualNetwork. Currently, only NSX-T 89 | // and vSphere Distributed Switch (VDS) type network integrations are supported using this VirtualMachineNetworkInterface 90 | // structure. 91 | type VirtualMachineNetworkInterface struct { 92 | // NetworkType describes the type of VirtualNetwork that is referenced by the NetworkName. Currently, the only 93 | // supported NetworkTypes are "nsx-t" and "vsphere-distributed". 94 | // +optional 95 | NetworkType string `json:"networkType,omitempty"` 96 | 97 | // NetworkName describes the name of an existing virtual network that this interface should be added to. 98 | // For "nsx-t" NetworkType, this is the name of a pre-existing NSX-T VirtualNetwork. If unspecified, 99 | // the default network for the namespace will be used. For "vsphere-distributed" NetworkType, the 100 | // NetworkName must be specified. 101 | // +optional 102 | NetworkName string `json:"networkName,omitempty"` 103 | 104 | // ProviderRef is reference to a network interface provider object that specifies the network interface configuration. 105 | // If unset, default configuration is assumed. 106 | // +optional 107 | ProviderRef *NetworkInterfaceProviderReference `json:"providerRef,omitempty"` 108 | 109 | // EthernetCardType describes an optional ethernet card that should be used by the VirtualNetworkInterface (vNIC) 110 | // associated with this network integration. The default is "vmxnet3". 111 | // +optional 112 | EthernetCardType string `json:"ethernetCardType,omitempty"` 113 | } 114 | 115 | // VirtualMachineMetadataTransport is used to indicate the transport used by VirtualMachineMetadata 116 | // Valid values are "ExtraConfig", "OvfEnv", "vAppConfig" and "CloudInit". 117 | // +kubebuilder:validation:Enum=ExtraConfig;OvfEnv;vAppConfig;CloudInit 118 | type VirtualMachineMetadataTransport string 119 | 120 | const ( 121 | // VirtualMachineMetadataExtraConfigTransport indicates that the data set in 122 | // the VirtualMachineMetadata Transport Resource, i.e., a ConfigMap or Secret, 123 | // will be extraConfig key value fields on the VM. 124 | // Only keys prefixed with "guestinfo." will be set. 125 | VirtualMachineMetadataExtraConfigTransport VirtualMachineMetadataTransport = "ExtraConfig" 126 | 127 | // VirtualMachineMetadataOvfEnvTransport indicates that the data set in 128 | // the VirtualMachineMetadata Transport Resource, i.e., a ConfigMap or Secret, 129 | // will be vApp properties on the VM, which will be exposed as OvfEnv to the Guest VM. 130 | // Only properties marked userConfigurable and already present in either 131 | // OVF Properties of a VirtualMachineImage or as vApp properties on an existing VM 132 | // or VMTX will be set, all others will be ignored. 133 | // 134 | // This transport uses Guest OS customization for networking. 135 | VirtualMachineMetadataOvfEnvTransport VirtualMachineMetadataTransport = "OvfEnv" 136 | 137 | // VirtualMachineMetadataVAppConfigTransport indicates that the data set in 138 | // the VirtualMachineMetadata Transport Resource, i.e., a ConfigMap or Secret, 139 | // will be vApp properties on the VM, which will be exposed as vAppConfig to the Guest VM. 140 | // Only properties marked userConfigurable and already present in either 141 | // OVF Properties of a VirtualMachineImage or as vApp properties on an existing VM 142 | // or VMTX will be set, all others will be ignored. 143 | // 144 | // Selecting this transport means the guest's network is not automatically 145 | // configured by vm-tools. This transport should only be selected if the image 146 | // exposes OVF/vApp properties that are used by the guest to bootstrap 147 | // its networking configuration. 148 | VirtualMachineMetadataVAppConfigTransport VirtualMachineMetadataTransport = "vAppConfig" 149 | 150 | // VirtualMachineMetadataCloudInitTransport indicates the data set in 151 | // the VirtualMachineMetadata Transport Resource, i.e., a ConfigMap or Secret, 152 | // in the "user-data" key is cloud-init userdata. 153 | // 154 | // Please note that, despite the name, VirtualMachineMetadata has no 155 | // relationship to cloud-init instance metadata. 156 | // 157 | // For more information, please refer to cloud-init's official documentation. 158 | VirtualMachineMetadataCloudInitTransport VirtualMachineMetadataTransport = "CloudInit" 159 | ) 160 | 161 | // VirtualMachineMetadata defines any metadata that should be passed to the VirtualMachine instance. A typical use 162 | // case is for this metadata to be used for Guest Customization, however the intended use of the metadata is 163 | // agnostic to the VirtualMachine controller. VirtualMachineMetadata is read from a configured ConfigMap or a Secret and then 164 | // propagated to the VirtualMachine instance using a desired "Transport" mechanism. 165 | type VirtualMachineMetadata struct { 166 | // ConfigMapName describes the name of the ConfigMap, in the same Namespace as the VirtualMachine, that should be 167 | // used for VirtualMachine metadata. The contents of the Data field of the ConfigMap is used as the VM Metadata. 168 | // The format of the contents of the VM Metadata are not parsed or interpreted by the VirtualMachine controller. 169 | // Please note, this field and SecretName are mutually exclusive. 170 | // +optional 171 | ConfigMapName string `json:"configMapName,omitempty"` 172 | 173 | // SecretName describes the name of the Secret, in the same Namespace as the VirtualMachine, that should be used 174 | // for VirtualMachine metadata. The contents of the Data field of the Secret is used as the VM Metadata. 175 | // The format of the contents of the VM Metadata are not parsed or interpreted by the VirtualMachine controller. 176 | // Please note, this field and ConfigMapName are mutually exclusive. 177 | // +optional 178 | SecretName string `json:"secretName,omitempty"` 179 | 180 | // Transport describes the name of a supported VirtualMachineMetadata transport protocol. Currently, the only supported 181 | // transport protocols are "ExtraConfig", "OvfEnv" and "CloudInit". 182 | Transport VirtualMachineMetadataTransport `json:"transport,omitempty"` 183 | } 184 | 185 | // VirtualMachineVolume describes a Volume that should be attached to a specific VirtualMachine. 186 | // Only one of PersistentVolumeClaim, VsphereVolume should be specified. 187 | type VirtualMachineVolume struct { 188 | // Name specifies the name of the VirtualMachineVolume. Each volume within the scope of a VirtualMachine must 189 | // have a unique name. 190 | Name string `json:"name"` 191 | 192 | // PersistentVolumeClaim represents a reference to a PersistentVolumeClaim 193 | // in the same namespace. The PersistentVolumeClaim must match one of the 194 | // following: 195 | // 196 | // * A volume provisioned (either statically or dynamically) by the 197 | // cluster's CSI provider. 198 | // 199 | // * An instance volume with a lifecycle coupled to the VM. 200 | // +optional 201 | PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty"` 202 | 203 | // VsphereVolume represents a reference to a VsphereVolumeSource in the same namespace. Only one of PersistentVolumeClaim or 204 | // VsphereVolume can be specified. This is enforced via a webhook 205 | // +optional 206 | VsphereVolume *VsphereVolumeSource `json:"vSphereVolume,omitempty"` 207 | } 208 | 209 | // PersistentVolumeClaimVolumeSource is a composite for the Kubernetes 210 | // corev1.PersistentVolumeClaimVolumeSource and instance storage options. 211 | type PersistentVolumeClaimVolumeSource struct { 212 | corev1.PersistentVolumeClaimVolumeSource `json:",inline" yaml:",inline"` 213 | 214 | // InstanceVolumeClaim is set if the PVC is backed by instance storage. 215 | // +optional 216 | InstanceVolumeClaim *InstanceVolumeClaimVolumeSource `json:"instanceVolumeClaim,omitempty"` 217 | } 218 | 219 | // InstanceVolumeClaimVolumeSource contains information about the instance 220 | // storage volume claimed as a PVC. 221 | type InstanceVolumeClaimVolumeSource struct { 222 | // StorageClass is the name of the Kubernetes StorageClass that provides 223 | // the backing storage for this instance storage volume. 224 | StorageClass string `json:"storageClass"` 225 | 226 | // Size is the size of the requested instance storage volume. 227 | Size resource.Quantity `json:"size"` 228 | } 229 | 230 | // VsphereVolumeSource describes a volume source that represent static disks that belong to a VirtualMachine. 231 | type VsphereVolumeSource struct { 232 | // A description of the virtual volume's resources and capacity 233 | // +optional 234 | Capacity corev1.ResourceList `json:"capacity,omitempty"` 235 | 236 | // Device key of vSphere disk. 237 | // +optional 238 | DeviceKey *int `json:"deviceKey,omitempty"` 239 | } 240 | 241 | // Probe describes a health check to be performed against a VirtualMachine to determine whether it is 242 | // alive or ready to receive traffic. Only one probe action can be specified. 243 | type Probe struct { 244 | // TCPSocket specifies an action involving a TCP port. 245 | // +optional 246 | TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"` 247 | 248 | // GuestHeartbeat specifies an action involving the guest heartbeat status. 249 | // +optional 250 | GuestHeartbeat *GuestHeartbeatAction `json:"guestHeartbeat,omitempty"` 251 | 252 | // TimeoutSeconds specifies a number of seconds after which the probe times out. 253 | // Defaults to 10 seconds. Minimum value is 1. 254 | // +optional 255 | // +kubebuilder:validation:Minimum:=1 256 | // +kubebuilder:validation:Maximum:=60 257 | TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"` 258 | 259 | // PeriodSeconds specifics how often (in seconds) to perform the probe. 260 | // Defaults to 10 seconds. Minimum value is 1. 261 | // +optional 262 | // +kubebuilder:validation:Minimum:=1 263 | PeriodSeconds int32 `json:"periodSeconds,omitempty"` 264 | } 265 | 266 | // TCPSocketAction describes an action based on opening a socket. 267 | type TCPSocketAction struct { 268 | // Port specifies a number or name of the port to access on the VirtualMachine. 269 | // If the format of port is a number, it must be in the range 1 to 65535. 270 | // If the format of name is a string, it must be an IANA_SVC_NAME. 271 | Port intstr.IntOrString `json:"port"` 272 | 273 | // Host is an optional host name to connect to. Host defaults to the VirtualMachine IP. 274 | // +optional 275 | Host string `json:"host,omitempty"` 276 | } 277 | 278 | // GuestHeartbeatStatus is the status type for a GuestHeartbeat. 279 | type GuestHeartbeatStatus string 280 | 281 | // See govmomi.vim25.types.ManagedEntityStatus. 282 | const ( 283 | // VMware Tools are not installed or not running. 284 | GrayHeartbeatStatus GuestHeartbeatStatus = "gray" 285 | // No heartbeat. Guest operating system may have stopped responding. 286 | RedHeartbeatStatus GuestHeartbeatStatus = "red" 287 | // Intermittent heartbeat. May be due to guest load. 288 | YellowHeartbeatStatus GuestHeartbeatStatus = "yellow" 289 | // Guest operating system is responding normally. 290 | GreenHeartbeatStatus GuestHeartbeatStatus = "green" 291 | ) 292 | 293 | // GuestHeartbeatAction describes an action based on the guest heartbeat. 294 | type GuestHeartbeatAction struct { 295 | // ThresholdStatus is the value that the guest heartbeat status must be at or above to be 296 | // considered successful. 297 | // +kubebuilder:validation:Optional 298 | // +kubebuilder:default=green 299 | // +kubebuilder:validation:Enum=yellow;green 300 | ThresholdStatus GuestHeartbeatStatus `json:"thresholdStatus,omitempty"` 301 | } 302 | 303 | // VirtualMachineSpec defines the desired state of a VirtualMachine. 304 | type VirtualMachineSpec struct { 305 | // ImageName describes the name of a VirtualMachineImage that is to be used as the base Operating System image of 306 | // the desired VirtualMachine instances. The VirtualMachineImage resources can be introspected to discover identifying 307 | // attributes that may help users to identify the desired image to use. 308 | ImageName string `json:"imageName"` 309 | 310 | // ClassName describes the name of a VirtualMachineClass that is to be used as the overlaid resource configuration 311 | // of VirtualMachine. A VirtualMachineClass is used to further customize the attributes of the VirtualMachine 312 | // instance. See VirtualMachineClass for more description. 313 | ClassName string `json:"className"` 314 | 315 | // PowerState describes the desired power state of a VirtualMachine. Valid power states are "poweredOff" and "poweredOn". 316 | PowerState VirtualMachinePowerState `json:"powerState"` 317 | 318 | // Ports is currently unused and can be considered deprecated. 319 | // +optional 320 | Ports []VirtualMachinePort `json:"ports,omitempty"` 321 | 322 | // VmMetadata describes any optional metadata that should be passed to the Guest OS. 323 | // +optional 324 | VmMetadata *VirtualMachineMetadata `json:"vmMetadata,omitempty"` //nolint:revive,stylecheck 325 | 326 | // StorageClass describes the name of a StorageClass that should be used to configure storage-related attributes of the VirtualMachine 327 | // instance. 328 | // +optional 329 | StorageClass string `json:"storageClass,omitempty"` 330 | 331 | // NetworkInterfaces describes a list of VirtualMachineNetworkInterfaces to be configured on the VirtualMachine instance. 332 | // Each of these VirtualMachineNetworkInterfaces describes external network integration configurations that are to be 333 | // used by the VirtualMachine controller when integrating the VirtualMachine into one or more external networks. 334 | // +optional 335 | NetworkInterfaces []VirtualMachineNetworkInterface `json:"networkInterfaces,omitempty"` 336 | 337 | // ResourcePolicyName describes the name of a VirtualMachineSetResourcePolicy to be used when creating the 338 | // VirtualMachine instance. 339 | // +optional 340 | ResourcePolicyName string `json:"resourcePolicyName"` 341 | 342 | // Volumes describes the list of VirtualMachineVolumes that are desired to be attached to the VirtualMachine. Each of 343 | // these volumes specifies a volume identity that the VirtualMachine controller will attempt to satisfy, potentially 344 | // with an external Volume Management service. 345 | // +optional 346 | // +patchMergeKey=name 347 | // +patchStrategy=merge 348 | Volumes []VirtualMachineVolume `json:"volumes,omitempty" patchStrategy:"merge" patchMergeKey:"name"` 349 | 350 | // ReadinessProbe describes a network probe that can be used to determine if the VirtualMachine is available and 351 | // responding to the probe. 352 | // +optional 353 | ReadinessProbe *Probe `json:"readinessProbe,omitempty"` 354 | 355 | // AdvancedOptions describes a set of optional, advanced options for configuring a VirtualMachine 356 | AdvancedOptions *VirtualMachineAdvancedOptions `json:"advancedOptions,omitempty"` 357 | } 358 | 359 | // VirtualMachineAdvancedOptions describes a set of optional, advanced options for configuring a VirtualMachine. 360 | type VirtualMachineAdvancedOptions struct { 361 | // DefaultProvisioningOptions specifies the provisioning type to be used by default for VirtualMachine volumes exclusively 362 | // owned by this VirtualMachine. This does not apply to PersistentVolumeClaim volumes that are created and managed externally. 363 | DefaultVolumeProvisioningOptions *VirtualMachineVolumeProvisioningOptions `json:"defaultVolumeProvisioningOptions,omitempty"` 364 | 365 | // ChangeBlockTracking specifies the enablement of incremental backup support for this VirtualMachine, which can be utilized 366 | // by external backup systems such as VMware Data Recovery. 367 | ChangeBlockTracking *bool `json:"changeBlockTracking,omitempty"` 368 | } 369 | 370 | // VirtualMachineVolumeProvisioningOptions specifies the provisioning options for a VirtualMachineVolume. 371 | type VirtualMachineVolumeProvisioningOptions struct { 372 | // ThinProvisioned specifies whether to use thin provisioning for the VirtualMachineVolume. 373 | // This means a sparse (allocate on demand) format with additional space optimizations. 374 | ThinProvisioned *bool `json:"thinProvisioned,omitempty"` 375 | 376 | // EagerZeroed specifies whether to use eager zero provisioning for the VirtualMachineVolume. 377 | // An eager zeroed thick disk has all space allocated and wiped clean of any previous contents 378 | // on the physical media at creation time. Such disks may take longer time during creation 379 | // compared to other disk formats. 380 | // EagerZeroed is only applicable if ThinProvisioned is false. This is validated by the webhook. 381 | EagerZeroed *bool `json:"eagerZeroed,omitempty"` 382 | } 383 | 384 | // VirtualMachineVolumeStatus defines the observed state of a VirtualMachineVolume instance. 385 | type VirtualMachineVolumeStatus struct { 386 | // Name is the name of the volume in a VirtualMachine. 387 | Name string `json:"name"` 388 | 389 | // Attached represents whether a volume has been successfully attached to the VirtualMachine or not. 390 | Attached bool `json:"attached"` 391 | 392 | // DiskUuid represents the underlying virtual disk UUID and is present when attachment succeeds. 393 | DiskUuid string `json:"diskUUID"` //nolint:revive,stylecheck 394 | 395 | // Error represents the last error seen when attaching or detaching a volume. Error will be empty if attachment succeeds. 396 | Error string `json:"error"` 397 | } 398 | 399 | // NetworkInterfaceStatus defines the observed state of network interfaces attached to the VirtualMachine 400 | // as seen by the Guest OS and VMware tools. 401 | type NetworkInterfaceStatus struct { 402 | // Connected represents whether the network interface is connected or not. 403 | Connected bool `json:"connected"` 404 | 405 | // MAC address of the network adapter 406 | MacAddress string `json:"macAddress,omitempty"` 407 | 408 | // IpAddresses represents zero, one or more IP addresses assigned to the network interface in CIDR notation. 409 | // For eg, "192.0.2.1/16". 410 | IpAddresses []string `json:"ipAddresses,omitempty"` //nolint:revive,stylecheck 411 | } 412 | 413 | // VirtualMachineStatus defines the observed state of a VirtualMachine instance. 414 | type VirtualMachineStatus struct { 415 | // Host describes the hostname or IP address of the infrastructure host that the VirtualMachine is executing on. 416 | // +optional 417 | Host string `json:"host,omitempty"` 418 | 419 | // PowerState describes the current power state of the VirtualMachine. 420 | // +optional 421 | PowerState VirtualMachinePowerState `json:"powerState,omitempty"` 422 | 423 | // Phase describes the current phase information of the VirtualMachine. 424 | // +optional 425 | Phase VMStatusPhase `json:"phase,omitempty"` 426 | 427 | // Conditions describes the current condition information of the VirtualMachine. 428 | // +optional 429 | Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` 430 | 431 | // VmIp describes the Primary IP address assigned to the guest operating system, if known. 432 | // Multiple IPs can be available for the VirtualMachine. Refer to networkInterfaces in the VirtualMachine 433 | // status for additional IPs 434 | // +optional 435 | VmIp string `json:"vmIp,omitempty"` //nolint:revive,stylecheck 436 | 437 | // UniqueID describes a unique identifier that is provided by the underlying infrastructure provider, such as 438 | // vSphere. 439 | // +optional 440 | UniqueID string `json:"uniqueID,omitempty"` 441 | 442 | // BiosUUID describes a unique identifier provided by the underlying infrastructure provider that is exposed to the 443 | // Guest OS BIOS as a unique hardware identifier. 444 | // +optional 445 | BiosUUID string `json:"biosUUID,omitempty"` 446 | 447 | // InstanceUUID describes the unique instance UUID provided by the underlying infrastructure provider, such as vSphere. 448 | // +optional 449 | InstanceUUID string `json:"instanceUUID,omitempty"` 450 | 451 | // Volumes describes a list of current status information for each Volume that is desired to be attached to the 452 | // VirtualMachine. 453 | // +optional 454 | Volumes []VirtualMachineVolumeStatus `json:"volumes,omitempty"` 455 | 456 | // ChangeBlockTracking describes the CBT enablement status on the VirtualMachine. 457 | // +optional 458 | ChangeBlockTracking *bool `json:"changeBlockTracking,omitempty"` 459 | 460 | // NetworkInterfaces describes a list of current status information for each network interface that is desired to 461 | // be attached to the VirtualMachine. 462 | // +optional 463 | NetworkInterfaces []NetworkInterfaceStatus `json:"networkInterfaces,omitempty"` 464 | 465 | // Zone describes the availability zone where the VirtualMachine has been scheduled. 466 | // Please note this field may be empty when the cluster is not zone-aware. 467 | // +optional 468 | Zone string `json:"zone,omitempty"` 469 | } 470 | 471 | func (vm *VirtualMachine) GetConditions() Conditions { 472 | return vm.Status.Conditions 473 | } 474 | 475 | func (vm *VirtualMachine) SetConditions(conditions Conditions) { 476 | vm.Status.Conditions = conditions 477 | } 478 | 479 | // +kubebuilder:object:root=true 480 | // +kubebuilder:resource:scope=Namespaced,shortName=vm 481 | // +kubebuilder:storageversion 482 | // +kubebuilder:subresource:status 483 | // +kubebuilder:printcolumn:name="Power-State",type="string",JSONPath=".status.powerState" 484 | // +kubebuilder:printcolumn:name="Class",type="string",priority=1,JSONPath=".spec.className" 485 | // +kubebuilder:printcolumn:name="Image",type="string",priority=1,JSONPath=".spec.imageName" 486 | // +kubebuilder:printcolumn:name="Primary-IP",type="string",priority=1,JSONPath=".status.vmIp" 487 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 488 | 489 | // VirtualMachine is the Schema for the virtualmachines API. 490 | // A VirtualMachine represents the desired specification and the observed status of a VirtualMachine instance. A 491 | // VirtualMachine is realized by the VirtualMachine controller on a backing Virtual Infrastructure provider such as 492 | // vSphere. 493 | type VirtualMachine struct { 494 | metav1.TypeMeta `json:",inline"` 495 | metav1.ObjectMeta `json:"metadata,omitempty"` 496 | 497 | Spec VirtualMachineSpec `json:"spec,omitempty"` 498 | Status VirtualMachineStatus `json:"status,omitempty"` 499 | } 500 | 501 | func (vm VirtualMachine) NamespacedName() string { 502 | return vm.Namespace + "/" + vm.Name 503 | } 504 | 505 | // VirtualMachineList contains a list of VirtualMachine. 506 | // 507 | // +kubebuilder:object:root=true 508 | type VirtualMachineList struct { 509 | metav1.TypeMeta `json:",inline"` 510 | metav1.ListMeta `json:"metadata,omitempty"` 511 | Items []VirtualMachine `json:"items"` 512 | } 513 | 514 | func init() { 515 | RegisterTypeWithScheme(&VirtualMachine{}, &VirtualMachineList{}) 516 | } 517 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachineclass_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | "k8s.io/apimachinery/pkg/api/resource" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | ) 10 | 11 | // VirtualMachineConfigSpec contains additional virtual machine 12 | // configuration settings including hardware specifications for the VirtualMachine. 13 | // We only support XML for now, but that may change in the future. 14 | type VirtualMachineConfigSpec struct { 15 | // XML contains a vim.vm.ConfigSpec object that has been serialized to XML 16 | // and base64-encoded. 17 | // +optional 18 | XML string `json:"xml,omitempty"` 19 | } 20 | 21 | // VGPUDevice contains the configuration corresponding to a vGPU device. 22 | type VGPUDevice struct { 23 | ProfileName string `json:"profileName"` 24 | } 25 | 26 | // DynamicDirectPathIODevice contains the configuration corresponding to a Dynamic DirectPath I/O device. 27 | type DynamicDirectPathIODevice struct { 28 | VendorID int `json:"vendorID"` 29 | DeviceID int `json:"deviceID"` 30 | // +optional 31 | CustomLabel string `json:"customLabel,omitempty"` 32 | } 33 | 34 | // InstanceStorage provides information used to configure instance 35 | // storage volumes for a VirtualMachine. 36 | type InstanceStorage struct { 37 | // StorageClass refers to the name of a StorageClass resource used to 38 | // provide the storage for the configured instance storage volumes. 39 | // The value of this field has no relationship to or bearing on the field 40 | // virtualMachine.spec.storageClass. Please note the referred StorageClass 41 | // must be available in the same namespace as the VirtualMachineClass that 42 | // uses it for configuring instance storage. 43 | StorageClass string `json:"storageClass,omitempty"` 44 | 45 | // Volumes describes instance storage volumes created for a VirtualMachine 46 | // instance that use this VirtualMachineClass. 47 | Volumes []InstanceStorageVolume `json:"volumes,omitempty"` 48 | } 49 | 50 | // InstanceStorageVolume contains information required to create an 51 | // instance storage volume on a VirtualMachine. 52 | type InstanceStorageVolume struct { 53 | Size resource.Quantity `json:"size"` 54 | } 55 | 56 | // VirtualDevices contains information about the virtual devices associated with a VirtualMachineClass. 57 | type VirtualDevices struct { 58 | // +optional 59 | VGPUDevices []VGPUDevice `json:"vgpuDevices,omitempty" patchStrategy:"merge" patchMergeKey:"profileName"` 60 | // +optional 61 | DynamicDirectPathIODevices []DynamicDirectPathIODevice `json:"dynamicDirectPathIODevices,omitempty"` 62 | } 63 | 64 | // VirtualMachineClassHardware describes a virtual hardware resource specification. 65 | type VirtualMachineClassHardware struct { 66 | Cpus int64 `json:"cpus,omitempty"` 67 | Memory resource.Quantity `json:"memory,omitempty"` 68 | // +optional 69 | Devices VirtualDevices `json:"devices,omitempty"` 70 | // +optional 71 | InstanceStorage InstanceStorage `json:"instanceStorage,omitempty"` 72 | } 73 | 74 | // VirtualMachineResourceSpec describes a virtual hardware policy specification. 75 | type VirtualMachineResourceSpec struct { 76 | Cpu resource.Quantity `json:"cpu,omitempty"` //nolint:stylecheck,revive 77 | Memory resource.Quantity `json:"memory,omitempty"` 78 | } 79 | 80 | // VirtualMachineClassResources describes the virtual hardware resource reservations and limits configuration to be used 81 | // by a VirtualMachineClass. 82 | type VirtualMachineClassResources struct { 83 | Requests VirtualMachineResourceSpec `json:"requests,omitempty"` 84 | Limits VirtualMachineResourceSpec `json:"limits,omitempty"` 85 | } 86 | 87 | // VirtualMachineClassPolicies describes the policy configuration to be used by a VirtualMachineClass. 88 | type VirtualMachineClassPolicies struct { 89 | Resources VirtualMachineClassResources `json:"resources,omitempty"` 90 | } 91 | 92 | // VirtualMachineClassSpec defines the desired state of VirtualMachineClass. 93 | type VirtualMachineClassSpec struct { 94 | // Hardware describes the configuration of the VirtualMachineClass attributes related to virtual hardware. The 95 | // configuration specified in this field is used to customize the virtual hardware characteristics of any VirtualMachine 96 | // associated with this VirtualMachineClass. 97 | Hardware VirtualMachineClassHardware `json:"hardware,omitempty"` 98 | 99 | // Policies describes the configuration of the VirtualMachineClass attributes related to virtual infrastructure 100 | // policy. The configuration specified in this field is used to customize various policies related to 101 | // infrastructure resource consumption. 102 | Policies VirtualMachineClassPolicies `json:"policies,omitempty"` 103 | 104 | // Description describes the configuration of the VirtualMachineClass which is not related to virtual hardware 105 | // or infrastructure policy. This field is used to address remaining specs about this VirtualMachineClass. 106 | // +optional 107 | Description string `json:"description,omitempty"` 108 | 109 | // ConfigSpec may specify additional virtual machine configuration settings including hardware specifications 110 | // for a VirtualMachine 111 | // +optional 112 | ConfigSpec *VirtualMachineConfigSpec `json:"configSpec,omitempty"` 113 | } 114 | 115 | // VirtualMachineClassStatus defines the observed state of VirtualMachineClass. VirtualMachineClasses are immutable, 116 | // non-dynamic resources, so this status is currently unused. 117 | type VirtualMachineClassStatus struct { 118 | } 119 | 120 | // +kubebuilder:object:root=true 121 | // +kubebuilder:resource:scope=Cluster,shortName=vmclass 122 | // +kubebuilder:storageversion 123 | // +kubebuilder:subresource:status 124 | // +kubebuilder:printcolumn:name="CPU",type="string",JSONPath=".spec.hardware.cpus" 125 | // +kubebuilder:printcolumn:name="Memory",type="string",JSONPath=".spec.hardware.memory" 126 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 127 | // +kubebuilder:printcolumn:name="VGPU-Devices-Profile-Names",type="string",priority=1,JSONPath=".spec.hardware.devices.vgpuDevices[*].profileName" 128 | // +kubebuilder:printcolumn:name="Passthrough-DeviceIDs",type="string",priority=1,JSONPath=".spec.hardware.devices.dynamicDirectPathIODevices[*].deviceID" 129 | 130 | // VirtualMachineClass is the Schema for the virtualmachineclasses API. 131 | // A VirtualMachineClass represents the desired specification and the observed status of a VirtualMachineClass 132 | // instance. A VirtualMachineClass represents a policy and configuration resource which defines a set of attributes to 133 | // be used in the configuration of a VirtualMachine instance. A VirtualMachine resource references a 134 | // VirtualMachineClass as a required input. 135 | type VirtualMachineClass struct { 136 | metav1.TypeMeta `json:",inline"` 137 | metav1.ObjectMeta `json:"metadata,omitempty"` 138 | 139 | Spec VirtualMachineClassSpec `json:"spec,omitempty"` 140 | Status VirtualMachineClassStatus `json:"status,omitempty"` 141 | } 142 | 143 | // +kubebuilder:object:root=true 144 | 145 | // VirtualMachineClassList contains a list of VirtualMachineClass. 146 | type VirtualMachineClassList struct { 147 | metav1.TypeMeta `json:",inline"` 148 | metav1.ListMeta `json:"metadata,omitempty"` 149 | Items []VirtualMachineClass `json:"items"` 150 | } 151 | 152 | func init() { 153 | RegisterTypeWithScheme(&VirtualMachineClass{}, &VirtualMachineClassList{}) 154 | } 155 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachineclassbinding_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // ClassReference contains info to locate a Kind VirtualMachineClass object. 11 | type ClassReference struct { 12 | // API version of the referent. 13 | APIVersion string `json:"apiVersion,omitempty"` 14 | // Kind is the type of resource being referenced. 15 | Kind string `json:"kind,omitempty"` 16 | // Name is the name of resource being referenced. 17 | Name string `json:"name"` 18 | } 19 | 20 | // +kubebuilder:object:root=true 21 | // +kubebuilder:resource:scope=Namespaced,shortName=vmclassbinding 22 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 23 | 24 | // VirtualMachineClassBinding is a binding object responsible for 25 | // defining a VirtualMachineClass and a Namespace associated with it. 26 | type VirtualMachineClassBinding struct { 27 | metav1.TypeMeta `json:",inline"` 28 | metav1.ObjectMeta `json:"metadata,omitempty"` 29 | 30 | // ClassReference is a reference to a VirtualMachineClass object 31 | ClassRef ClassReference `json:"classRef,omitempty"` 32 | } 33 | 34 | // +kubebuilder:object:root=true 35 | 36 | // VirtualMachineClassBindingList contains a list of VirtualMachineClassBinding. 37 | type VirtualMachineClassBindingList struct { 38 | metav1.TypeMeta `json:",inline"` 39 | metav1.ListMeta `json:"metadata,omitempty"` 40 | Items []VirtualMachineClassBinding `json:"items"` 41 | } 42 | 43 | func init() { 44 | RegisterTypeWithScheme(&VirtualMachineClassBinding{}, &VirtualMachineClassBindingList{}) 45 | } 46 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachineimage_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2021 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | corev1 "k8s.io/api/core/v1" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | ) 10 | 11 | // VirtualMachineImageProductInfo describes optional product-related information that can be added to an image 12 | // template. This information can be used by the image author to communicate details of the product contained in the 13 | // image. 14 | type VirtualMachineImageProductInfo struct { 15 | // Product typically describes the type of product contained in the image. 16 | // +optional 17 | Product string `json:"product,omitempty"` 18 | 19 | // Vendor typically describes the name of the vendor that is producing the image. 20 | // +optional 21 | Vendor string `json:"vendor,omitempty"` 22 | 23 | // Version typically describes a short-form version of the image. 24 | // +optional 25 | Version string `json:"version,omitempty"` 26 | 27 | // FullVersion typically describes a long-form version of the image. 28 | // +optional 29 | FullVersion string `json:"fullVersion,omitempty"` 30 | } 31 | 32 | // VirtualMachineImageOSInfo describes optional information related to the image operating system that can be added 33 | // to an image template. This information can be used by the image author to communicate details of the operating 34 | // system associated with the image. 35 | type VirtualMachineImageOSInfo struct { 36 | // Version typically describes the version of the guest operating system. 37 | // +optional 38 | Version string `json:"version,omitempty"` 39 | 40 | // Type typically describes the type of the guest operating system. 41 | // +optional 42 | Type string `json:"type,omitempty"` 43 | } 44 | 45 | // OvfProperty describes information related to a user configurable property element that is supported by 46 | // VirtualMachineImage and can be customized during VirtualMachine creation. 47 | type OvfProperty struct { 48 | // Key describes the key of the ovf property. 49 | Key string `json:"key"` 50 | 51 | // Type describes the type of the ovf property. 52 | Type string `json:"type"` 53 | 54 | // Default describes the default value of the ovf key. 55 | // +optional 56 | Default *string `json:"default,omitempty"` 57 | 58 | // Description contains the value of the OVF property's optional 59 | // "Description" element. 60 | // 61 | // +optional 62 | Description string `json:"description,omitempty"` 63 | 64 | // Label contains the value of the OVF property's optional 65 | // "Label" element. 66 | // 67 | // +optional 68 | Label string `json:"label,omitempty"` 69 | } 70 | 71 | // VirtualMachineImageSpec defines the desired state of VirtualMachineImage. 72 | type VirtualMachineImageSpec struct { 73 | // Type describes the type of the VirtualMachineImage. Currently, the only supported image is "OVF" 74 | Type string `json:"type"` 75 | 76 | // ImageSourceType describes the type of content source of the VirtualMachineImage. The only Content Source 77 | // supported currently is the vSphere Content Library. 78 | // +optional 79 | ImageSourceType string `json:"imageSourceType,omitempty"` 80 | 81 | // ImageID is a unique identifier exposed by the provider of this VirtualMachineImage. 82 | ImageID string `json:"imageID"` 83 | 84 | // ProviderRef is a reference to a content provider object that describes a provider. 85 | ProviderRef ContentProviderReference `json:"providerRef"` 86 | 87 | // ProductInfo describes the attributes of the VirtualMachineImage relating to the product contained in the 88 | // image. 89 | // +optional 90 | ProductInfo VirtualMachineImageProductInfo `json:"productInfo,omitempty"` 91 | 92 | // OSInfo describes the attributes of the VirtualMachineImage relating to the Operating System contained in the 93 | // image. 94 | // +optional 95 | OSInfo VirtualMachineImageOSInfo `json:"osInfo,omitempty"` 96 | 97 | // OVFEnv describes the user configurable customization parameters of the VirtualMachineImage. 98 | // +optional 99 | OVFEnv map[string]OvfProperty `json:"ovfEnv,omitempty"` 100 | 101 | // HardwareVersion describes the virtual hardware version of the image 102 | // +optional 103 | HardwareVersion int32 `json:"hwVersion,omitempty"` 104 | } 105 | 106 | // VirtualMachineImageStatus defines the observed state of VirtualMachineImage. 107 | type VirtualMachineImageStatus struct { 108 | // Deprecated 109 | Uuid string `json:"uuid,omitempty"` //nolint:revive,stylecheck 110 | 111 | // Deprecated 112 | InternalId string `json:"internalId"` //nolint:revive,stylecheck 113 | 114 | // Deprecated 115 | PowerState string `json:"powerState,omitempty"` 116 | 117 | // ImageName describes the display name of this VirtualMachineImage. 118 | // +optional 119 | ImageName string `json:"imageName,omitempty"` 120 | 121 | // ImageSupported indicates whether the VirtualMachineImage is supported by VMService. 122 | // A VirtualMachineImage is supported by VMService if the following conditions are true: 123 | // - VirtualMachineImageV1Alpha1CompatibleCondition 124 | // +optional 125 | ImageSupported *bool `json:"imageSupported,omitempty"` 126 | 127 | // Conditions describes the current condition information of the VirtualMachineImage object. e.g. if the OS type 128 | // is supported or image is supported by VMService 129 | // +optional 130 | Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` 131 | 132 | // ContentLibraryRef is a reference to the source ContentLibrary/ClusterContentLibrary resource. 133 | // +optional 134 | ContentLibraryRef *corev1.TypedLocalObjectReference `json:"contentLibraryRef,omitempty"` 135 | 136 | // ContentVersion describes the observed content version of this VirtualMachineImage that was last successfully 137 | // synced with the vSphere content library item. 138 | // +optional 139 | ContentVersion string `json:"contentVersion"` 140 | } 141 | 142 | func (vmImage *VirtualMachineImage) GetConditions() Conditions { 143 | return vmImage.Status.Conditions 144 | } 145 | 146 | func (vmImage *VirtualMachineImage) SetConditions(conditions Conditions) { 147 | vmImage.Status.Conditions = conditions 148 | } 149 | 150 | // +kubebuilder:object:root=true 151 | // +kubebuilder:resource:scope=Cluster,shortName=vmi;vmimage 152 | // +kubebuilder:storageversion 153 | // +kubebuilder:subresource:status 154 | // +kubebuilder:printcolumn:name="Provider-Name",type="string",JSONPath=".spec.providerRef.name" 155 | // +kubebuilder:printcolumn:name="Content-Library-Name",type="string",JSONPath=".status.contentLibraryRef.name" 156 | // +kubebuilder:printcolumn:name="Image-Name",type="string",JSONPath=".status.imageName" 157 | // +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.productInfo.version" 158 | // +kubebuilder:printcolumn:name="Os-Type",type="string",JSONPath=".spec.osInfo.type" 159 | // +kubebuilder:printcolumn:name="Format",type="string",JSONPath=".spec.type" 160 | // +kubebuilder:printcolumn:name="Image-Supported",type="boolean",priority=1,JSONPath=".status.imageSupported" 161 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 162 | 163 | // VirtualMachineImage is the Schema for the virtualmachineimages API 164 | // A VirtualMachineImage represents a VirtualMachine image (e.g. VM template) that can be used as the base image 165 | // for creating a VirtualMachine instance. The VirtualMachineImage is a required field of the VirtualMachine 166 | // spec. Currently, VirtualMachineImages are immutable to end users. 167 | type VirtualMachineImage struct { 168 | metav1.TypeMeta `json:",inline"` 169 | metav1.ObjectMeta `json:"metadata,omitempty"` 170 | 171 | Spec VirtualMachineImageSpec `json:"spec,omitempty"` 172 | Status VirtualMachineImageStatus `json:"status,omitempty"` 173 | } 174 | 175 | // +kubebuilder:object:root=true 176 | 177 | // VirtualMachineImageList contains a list of VirtualMachineImage. 178 | type VirtualMachineImageList struct { 179 | metav1.TypeMeta `json:",inline"` 180 | metav1.ListMeta `json:"metadata,omitempty"` 181 | Items []VirtualMachineImage `json:"items"` 182 | } 183 | 184 | func (clusterVirtualMachineImage *ClusterVirtualMachineImage) GetConditions() Conditions { 185 | return clusterVirtualMachineImage.Status.Conditions 186 | } 187 | 188 | func (clusterVirtualMachineImage *ClusterVirtualMachineImage) SetConditions(conditions Conditions) { 189 | clusterVirtualMachineImage.Status.Conditions = conditions 190 | } 191 | 192 | // +kubebuilder:object:root=true 193 | // +kubebuilder:resource:scope=Cluster,shortName=cvmi;cvmimage;clustervmimage 194 | // +kubebuilder:storageversion 195 | // +kubebuilder:subresource:status 196 | // +kubebuilder:printcolumn:name="Provider-Name",type="string",JSONPath=".spec.providerRef.name" 197 | // +kubebuilder:printcolumn:name="Content-Library-Name",type="string",JSONPath=".status.contentLibraryRef.name" 198 | // +kubebuilder:printcolumn:name="Image-Name",type="string",JSONPath=".status.imageName" 199 | // +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.productInfo.version" 200 | // +kubebuilder:printcolumn:name="Os-Type",type="string",JSONPath=".spec.osInfo.type" 201 | // +kubebuilder:printcolumn:name="Format",type="string",JSONPath=".spec.type" 202 | // +kubebuilder:printcolumn:name="Image-Supported",type="boolean",priority=1,JSONPath=".status.imageSupported" 203 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 204 | 205 | // ClusterVirtualMachineImage is the schema for the clustervirtualmachineimage API 206 | // A ClusterVirtualMachineImage represents the desired specification and the observed status of a 207 | // ClusterVirtualMachineImage instance. 208 | type ClusterVirtualMachineImage struct { 209 | metav1.TypeMeta `json:",inline"` 210 | metav1.ObjectMeta `json:"metadata,omitempty"` 211 | 212 | Spec VirtualMachineImageSpec `json:"spec,omitempty"` 213 | Status VirtualMachineImageStatus `json:"status,omitempty"` 214 | } 215 | 216 | // +kubebuilder:object:root=true 217 | 218 | // ClusterVirtualMachineImageList contains a list of ClusterVirtualMachineImage. 219 | type ClusterVirtualMachineImageList struct { 220 | metav1.TypeMeta `json:",inline"` 221 | metav1.ListMeta `json:"metadata,omitempty"` 222 | Items []ClusterVirtualMachineImage `json:"items"` 223 | } 224 | 225 | func init() { 226 | RegisterTypeWithScheme( 227 | &VirtualMachineImage{}, 228 | &VirtualMachineImageList{}, 229 | &ClusterVirtualMachineImage{}, 230 | &ClusterVirtualMachineImageList{}) 231 | } 232 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachinepublishrequest_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | "time" 8 | 9 | corev1 "k8s.io/api/core/v1" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | ) 12 | 13 | const ( 14 | // VirtualMachinePublishRequestConditionSuccess is the Success value for 15 | // conditions related to a VirtualMachinePublishRequest resource. 16 | VirtualMachinePublishRequestConditionSuccess = "Success" 17 | 18 | // VirtualMachinePublishRequestConditionSourceValid is the Type for a 19 | // VirtualMachinePublishRequest resource's status condition. 20 | // 21 | // The condition's status is set to true only when the information 22 | // that describes the source side of the publication has been validated. 23 | VirtualMachinePublishRequestConditionSourceValid = "SourceValid" 24 | 25 | // VirtualMachinePublishRequestConditionTargetValid is the Type for a 26 | // VirtualMachinePublishRequest resource's status condition. 27 | // 28 | // The condition's status is set to true only when the information 29 | // that describes the target side of the publication has been 30 | // validated. 31 | VirtualMachinePublishRequestConditionTargetValid = "TargetValid" 32 | 33 | // VirtualMachinePublishRequestConditionUploaded is the Type for a 34 | // VirtualMachinePublishRequest resource's status condition. 35 | // 36 | // The condition's status is set to true only when the VM being 37 | // published has been successfully uploaded. 38 | VirtualMachinePublishRequestConditionUploaded = "Uploaded" 39 | 40 | // VirtualMachinePublishRequestConditionImageAvailable is the Type for a 41 | // VirtualMachinePublishRequest resource's status condition. 42 | // 43 | // The condition's status is set to true only when a new 44 | // VirtualMachineImage resource has been realized from the published 45 | // VM. 46 | VirtualMachinePublishRequestConditionImageAvailable = "ImageAvailable" 47 | 48 | // VirtualMachinePublishRequestConditionComplete is the Type for a 49 | // VirtualMachinePublishRequest resource's status condition. 50 | // 51 | // The condition's status is set to true only when all other conditions 52 | // present on the resource have a truthy status. 53 | VirtualMachinePublishRequestConditionComplete = "Complete" 54 | ) 55 | 56 | // VirtualMachinePublishRequestSource is the source of a publication request, 57 | // typically a VirtualMachine resource. 58 | type VirtualMachinePublishRequestSource struct { 59 | // Name is the name of the referenced object. 60 | // 61 | // If omitted this value defaults to the name of the 62 | // VirtualMachinePublishRequest resource. 63 | // 64 | // +optional 65 | Name string `json:"name,omitempty"` 66 | 67 | // APIVersion is the API version of the referenced object. 68 | // 69 | // +kubebuilder:default=vmoperator.vmware.com/v1alpha1 70 | // +optional 71 | APIVersion string `json:"apiVersion,omitempty"` 72 | 73 | // Kind is the kind of referenced object. 74 | // 75 | // +kubebuilder:default=VirtualMachine 76 | // +optional 77 | Kind string `json:"kind,omitempty"` 78 | } 79 | 80 | // VirtualMachinePublishRequestTargetItem is the item part of a 81 | // publication request's target. 82 | type VirtualMachinePublishRequestTargetItem struct { 83 | // Name is the name of the published object. 84 | // 85 | // If the spec.target.location.apiVersion equals 86 | // imageregistry.vmware.com/v1alpha1 and the spec.target.location.kind 87 | // equals ContentLibrary, then this should be the name that will 88 | // show up in vCenter Content Library, not the custom resource name 89 | // in the namespace. 90 | // 91 | // If omitted then the controller will use spec.source.name + "-image". 92 | // 93 | // +optional 94 | Name string `json:"name,omitempty"` 95 | 96 | // Description is the description to assign to the published object. 97 | // 98 | // +optional 99 | Description string `json:"description,omitempty"` 100 | } 101 | 102 | // VirtualMachinePublishRequestTargetLocation is the location part of a 103 | // publication request's target. 104 | type VirtualMachinePublishRequestTargetLocation struct { 105 | // Name is the name of the referenced object. 106 | // 107 | // Please note an error will be returned if this field is not 108 | // set in a namespace that lacks a default publication target. 109 | // 110 | // A default publication target is a resource with an API version 111 | // equal to spec.target.location.apiVersion, a kind equal to 112 | // spec.target.location.kind, and has the label 113 | // "imageregistry.vmware.com/default". 114 | // 115 | // +optional 116 | Name string `json:"name,omitempty"` 117 | 118 | // APIVersion is the API version of the referenced object. 119 | // 120 | // +kubebuilder:default=imageregistry.vmware.com/v1alpha1 121 | // +optional 122 | APIVersion string `json:"apiVersion,omitempty"` 123 | 124 | // Kind is the kind of referenced object. 125 | // 126 | // +kubebuilder:default=ContentLibrary 127 | // +optional 128 | Kind string `json:"kind,omitempty"` 129 | } 130 | 131 | // VirtualMachinePublishRequestTarget is the target of a publication request, 132 | // typically a ContentLibrary resource. 133 | type VirtualMachinePublishRequestTarget struct { 134 | // Item contains information about the name of the object to which 135 | // the VM is published. 136 | // 137 | // Please note this value is optional and if omitted, the controller 138 | // will use spec.source.name + "-image" as the name of the published 139 | // item. 140 | // 141 | // +optional 142 | Item VirtualMachinePublishRequestTargetItem `json:"item,omitempty"` 143 | 144 | // Location contains information about the location to which to publish 145 | // the VM. 146 | // 147 | // +optional 148 | Location VirtualMachinePublishRequestTargetLocation `json:"location,omitempty"` 149 | } 150 | 151 | // VirtualMachinePublishRequestSpec defines the desired state of a 152 | // VirtualMachinePublishRequest. 153 | // 154 | // All the fields in this spec are optional. This is especially useful when a 155 | // DevOps persona wants to publish a VM without doing anything more than 156 | // applying a VirtualMachinePublishRequest resource that has the same name 157 | // as said VM in the same namespace as said VM. 158 | type VirtualMachinePublishRequestSpec struct { 159 | // Source is the source of the publication request, ex. a VirtualMachine 160 | // resource. 161 | // 162 | // If this value is omitted then the publication controller checks to 163 | // see if there is a resource with the same name as this 164 | // VirtualMachinePublishRequest resource, an API version equal to 165 | // spec.source.apiVersion, and a kind equal to spec.source.kind. If such 166 | // a resource exists, then it is the source of the publication. 167 | // 168 | // +optional 169 | Source VirtualMachinePublishRequestSource `json:"source,omitempty"` 170 | 171 | // Target is the target of the publication request, ex. item 172 | // information and a ContentLibrary resource. 173 | // 174 | // If this value is omitted, the controller uses spec.source.name + "-image" 175 | // as the name of the published item. Additionally, when omitted the 176 | // controller attempts to identify the target location by matching a 177 | // resource with an API version equal to spec.target.location.apiVersion, a 178 | // kind equal to spec.target.location.kind, w/ the label 179 | // "imageregistry.vmware.com/default". 180 | // 181 | // Please note that while optional, if a VirtualMachinePublishRequest sans 182 | // target information is applied to a namespace without a default 183 | // publication target, then the VirtualMachinePublishRequest resource 184 | // will be marked in error. 185 | // 186 | // +optional 187 | Target VirtualMachinePublishRequestTarget `json:"target,omitempty"` 188 | 189 | // TTLSecondsAfterFinished is the time-to-live duration for how long this 190 | // resource will be allowed to exist once the publication operation 191 | // completes. After the TTL expires, the resource will be automatically 192 | // deleted without the user having to take any direct action. 193 | // 194 | // If this field is unset then the request resource will not be 195 | // automatically deleted. If this field is set to zero then the request 196 | // resource is eligible for deletion immediately after it finishes. 197 | // 198 | // +optional 199 | TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty"` 200 | } 201 | 202 | // VirtualMachinePublishRequestStatus defines the observed state of a 203 | // VirtualMachinePublishRequest. 204 | type VirtualMachinePublishRequestStatus struct { 205 | // SourceRef is the reference to the source of the publication request, 206 | // ex. a VirtualMachine resource. 207 | // 208 | // +optional 209 | SourceRef *VirtualMachinePublishRequestSource `json:"sourceRef,omitempty"` 210 | 211 | // TargetRef is the reference to the target of the publication request, 212 | // ex. item information and a ContentLibrary resource. 213 | // 214 | // 215 | // +optional 216 | TargetRef *VirtualMachinePublishRequestTarget `json:"targetRef,omitempty"` 217 | 218 | // CompletionTime represents time when the request was completed. It is not 219 | // guaranteed to be set in happens-before order across separate operations. 220 | // It is represented in RFC3339 form and is in UTC. 221 | // 222 | // The value of this field should be equal to the value of the 223 | // LastTransitionTime for the status condition Type=Complete. 224 | // 225 | // +optional 226 | CompletionTime metav1.Time `json:"completionTime,omitempty"` 227 | 228 | // StartTime represents time when the request was acknowledged by the 229 | // controller. It is not guaranteed to be set in happens-before order 230 | // across separate operations. It is represented in RFC3339 form and is 231 | // in UTC. 232 | // 233 | // +optional 234 | StartTime metav1.Time `json:"startTime,omitempty"` 235 | 236 | // Attempts represents the number of times the request to publish the VM 237 | // has been attempted. 238 | // 239 | // +optional 240 | Attempts int64 `json:"attempts,omitempty"` 241 | 242 | // LastAttemptTime represents the time when the latest request was sent. 243 | // 244 | // +optional 245 | LastAttemptTime metav1.Time `json:"lastAttemptTime,omitempty"` 246 | 247 | // ImageName is the name of the VirtualMachineImage resource that is 248 | // eventually realized in the same namespace as the VM and publication 249 | // request after the publication operation completes. 250 | // 251 | // This field will not be set until the VirtualMachineImage resource 252 | // is realized. 253 | // 254 | // +optional 255 | ImageName string `json:"imageName,omitempty"` 256 | 257 | // Ready is set to true only when the VM has been published successfully 258 | // and the new VirtualMachineImage resource is ready. 259 | // 260 | // Readiness is determined by waiting until there is status condition 261 | // Type=Complete and ensuring it and all other status conditions present 262 | // have a Status=True. The conditions present will be: 263 | // 264 | // * SourceValid 265 | // * TargetValid 266 | // * Uploaded 267 | // * ImageAvailable 268 | // * Complete 269 | // 270 | // +optional 271 | Ready bool `json:"ready,omitempty"` 272 | 273 | // Conditions is a list of the latest, available observations of the 274 | // request's current state. 275 | // 276 | // +optional 277 | Conditions []Condition `json:"conditions,omitempty"` 278 | } 279 | 280 | func (vmpr VirtualMachinePublishRequest) getCondition( 281 | conditionType ConditionType, 282 | ) *Condition { 283 | 284 | for i := range vmpr.Status.Conditions { 285 | c := &vmpr.Status.Conditions[i] 286 | if c.Type == conditionType { 287 | return c 288 | } 289 | } 290 | 291 | return nil 292 | } 293 | 294 | // IsSourceValid returns true if there is a status condition of Type=SourceValid 295 | // and Status=True. 296 | func (vmpr VirtualMachinePublishRequest) IsSourceValid() bool { 297 | c := vmpr.getCondition(VirtualMachinePublishRequestConditionSourceValid) 298 | if c != nil && c.Status == corev1.ConditionTrue { 299 | return true 300 | } 301 | return false 302 | } 303 | 304 | // IsTargetValid returns true if there is a status condition of 305 | // Type=TargetValid and Status=True. 306 | func (vmpr VirtualMachinePublishRequest) IsTargetValid() bool { 307 | c := vmpr.getCondition(VirtualMachinePublishRequestConditionTargetValid) 308 | if c != nil && c.Status == corev1.ConditionTrue { 309 | return true 310 | } 311 | return false 312 | } 313 | 314 | // IsComplete returns true if there is a status condition of Type=Complete 315 | // and Status=True and the resource's status.completionTime is non-zero. 316 | // 317 | // It is recommended to use the MarkComplete function in order to mark 318 | // a VirtualMachinePublishRequest as complete since the function ensures 319 | // the status.completionTime field is properly set. 320 | // 321 | // This condition is set only when the operation has failed or the 322 | // VirtualMachineImage resource has been realized. 323 | func (vmpr VirtualMachinePublishRequest) IsComplete() bool { 324 | c := vmpr.getCondition(VirtualMachinePublishRequestConditionComplete) 325 | if c != nil && c.Status == corev1.ConditionTrue { 326 | return !vmpr.Status.CompletionTime.IsZero() 327 | } 328 | return false 329 | } 330 | 331 | // IsImageAvailable returns true if there is a status condition of 332 | // Type=ImageAvailable and Status=True. 333 | func (vmpr VirtualMachinePublishRequest) IsImageAvailable() bool { 334 | c := vmpr.getCondition(VirtualMachinePublishRequestConditionImageAvailable) 335 | if c != nil && c.Status == corev1.ConditionTrue { 336 | return true 337 | } 338 | return false 339 | } 340 | 341 | // IsUploaded returns true if there is a status condition of Type=Uploaded 342 | // and Status=True. 343 | // 344 | // This condition is set when the publication has finished uploading the 345 | // VM to the image registry and is waiting on the VirtualMachineImage 346 | // resource to be realized. 347 | func (vmpr VirtualMachinePublishRequest) IsUploaded() bool { 348 | c := vmpr.getCondition(VirtualMachinePublishRequestConditionUploaded) 349 | if c != nil && c.Status == corev1.ConditionTrue { 350 | return true 351 | } 352 | return false 353 | } 354 | 355 | func (vmpr *VirtualMachinePublishRequest) markCondition( 356 | conditionType ConditionType, 357 | status corev1.ConditionStatus, 358 | args ...string, 359 | ) { 360 | var ( 361 | message string 362 | reason string 363 | ) 364 | if len(args) > 0 { 365 | reason = args[0] 366 | } 367 | if len(args) > 1 { 368 | message = args[1] 369 | } 370 | if reason == "" && status == corev1.ConditionTrue { 371 | reason = VirtualMachinePublishRequestConditionSuccess 372 | } else { 373 | reason = string(status) 374 | } 375 | 376 | c := vmpr.getCondition(conditionType) 377 | if c != nil { 378 | c.Message = message 379 | c.Reason = reason 380 | c.Status = status 381 | // Only update the LastTransitionTime if something actually changed. 382 | if c.Message != message || c.Reason != reason || c.Status != status { 383 | c.LastTransitionTime = metav1.NewTime(time.Now().UTC()) 384 | } 385 | return 386 | } 387 | vmpr.Status.Conditions = append( 388 | vmpr.Status.Conditions, 389 | Condition{ 390 | Type: conditionType, 391 | Message: message, 392 | Reason: reason, 393 | Status: status, 394 | LastTransitionTime: metav1.NewTime(time.Now().UTC()), 395 | }, 396 | ) 397 | } 398 | 399 | // MarkComplete adds or updates the status condition Type=Complete 400 | // sets the condition's Status field to the provided value. 401 | // 402 | // This function also updates the status.completionTime field to 403 | // the current time in UTC. Please note this field is updated every 404 | // time this function is called. If this function is called with a 405 | // status of anything other than True, the value of status.completionTIme 406 | // is zeroed. 407 | // 408 | // This function also sets status.ready=true IFF the provided status 409 | // is True and all other conditions present in the resource have a 410 | // status=True. 411 | // 412 | // The variadic parameter args may be used to set the condition's 413 | // reason and message. If len(args) > 0 then args[0] is used as the 414 | // reason. If len(args) > 1 then args[1] is used as the message. 415 | // 416 | // If no reason is provided and status=True, then reason is set to 417 | // to "Success," otherwise string(status). 418 | // 419 | // If no message is provided then it is set to an empty string. 420 | func (vmpr *VirtualMachinePublishRequest) MarkComplete( 421 | status corev1.ConditionStatus, 422 | args ...string, 423 | ) { 424 | switch status { 425 | case corev1.ConditionTrue: 426 | vmpr.Status.CompletionTime = metav1.NewTime(time.Now().UTC()) 427 | case corev1.ConditionFalse, corev1.ConditionUnknown: 428 | vmpr.Status.CompletionTime = metav1.Time{} 429 | } 430 | 431 | vmpr.markCondition( 432 | VirtualMachinePublishRequestConditionComplete, 433 | status, 434 | args..., 435 | ) 436 | 437 | // At this point, if all conditions have a Status=True then 438 | // the VirtualMachinePublishRequest resource should be marked 439 | // ready. 440 | for _, c := range vmpr.Status.Conditions { 441 | if c.Status != corev1.ConditionTrue { 442 | vmpr.Status.Ready = false 443 | return 444 | } 445 | } 446 | vmpr.Status.Ready = true 447 | } 448 | 449 | // MarkSourceValid adds or updates a status condition of 450 | // Type=SourceValid and sets the condition's Status field to the 451 | // provided value. 452 | // 453 | // The variadic parameter args may be used to set the condition's 454 | // reason and message. If len(args) > 0 then args[0] is used as the 455 | // reason. If len(args) > 1 then args[1] is used as the message. 456 | // 457 | // If no reason is provided and status=True, then reason is set to 458 | // to "Success," otherwise string(status). 459 | // 460 | // If no message is provided then it is set to an empty string. 461 | func (vmpr *VirtualMachinePublishRequest) MarkSourceValid( 462 | status corev1.ConditionStatus, 463 | args ...string, 464 | ) { 465 | vmpr.markCondition( 466 | VirtualMachinePublishRequestConditionSourceValid, 467 | status, 468 | args..., 469 | ) 470 | } 471 | 472 | // MarkTargetValid adds or updates a status condition of 473 | // Type=TargetValid and sets the condition's Status field to the 474 | // provided value. 475 | // 476 | // The variadic parameter args may be used to set the condition's 477 | // reason and message. If len(args) > 0 then args[0] is used as the 478 | // reason. If len(args) > 1 then args[1] is used as the message. 479 | // 480 | // If no reason is provided and status=True, then reason is set to 481 | // to "Success," otherwise string(status). 482 | // 483 | // If no message is provided then it is set to an empty string. 484 | func (vmpr *VirtualMachinePublishRequest) MarkTargetValid( 485 | status corev1.ConditionStatus, 486 | args ...string, 487 | ) { 488 | vmpr.markCondition( 489 | VirtualMachinePublishRequestConditionTargetValid, 490 | status, 491 | args..., 492 | ) 493 | } 494 | 495 | // MarkImageAvailable adds or updates a status condition of 496 | // Type=ImageAvailable and sets the condition's Status field to the 497 | // provided value. 498 | // 499 | // The variadic parameter args may be used to set the condition's 500 | // reason and message. If len(args) > 0 then args[0] is used as the 501 | // reason. If len(args) > 1 then args[1] is used as the message. 502 | // 503 | // If no reason is provided and status=True, then reason is set to 504 | // to "Success," otherwise string(status). 505 | // 506 | // If no message is provided then it is set to an empty string. 507 | func (vmpr *VirtualMachinePublishRequest) MarkImageAvailable( 508 | status corev1.ConditionStatus, 509 | args ...string, 510 | ) { 511 | vmpr.markCondition( 512 | VirtualMachinePublishRequestConditionImageAvailable, 513 | status, 514 | args..., 515 | ) 516 | } 517 | 518 | // MarkUploaded adds or updates a status condition of Type=Uploaded and 519 | // sets the condition's Status field to the provided value. 520 | // 521 | // The variadic parameter args may be used to set the condition's 522 | // reason and message. If len(args) > 0 then args[0] is used as the 523 | // reason. If len(args) > 1 then args[1] is used as the message. 524 | // 525 | // If no reason is provided and status=True, then reason is set to 526 | // to "Success," otherwise string(status). 527 | // 528 | // If no message is provided then it is set to an empty string. 529 | func (vmpr *VirtualMachinePublishRequest) MarkUploaded( 530 | status corev1.ConditionStatus, 531 | args ...string, 532 | ) { 533 | vmpr.markCondition( 534 | VirtualMachinePublishRequestConditionUploaded, 535 | status, 536 | args..., 537 | ) 538 | } 539 | 540 | // +kubebuilder:object:root=true 541 | // +kubebuilder:resource:scope=Namespaced,shortName=vmpub 542 | // +kubebuilder:storageversion 543 | // +kubebuilder:subresource:status 544 | 545 | // VirtualMachinePublishRequest defines the information necessary to publish a 546 | // VirtualMachine as a VirtualMachineImage to an image registry. 547 | type VirtualMachinePublishRequest struct { 548 | metav1.TypeMeta `json:",inline"` 549 | metav1.ObjectMeta `json:"metadata,omitempty"` 550 | 551 | Spec VirtualMachinePublishRequestSpec `json:"spec,omitempty"` 552 | Status VirtualMachinePublishRequestStatus `json:"status,omitempty"` 553 | } 554 | 555 | // +kubebuilder:object:root=true 556 | 557 | // VirtualMachinePublishRequestList contains a list of 558 | // VirtualMachinePublishRequest resources. 559 | type VirtualMachinePublishRequestList struct { 560 | metav1.TypeMeta `json:",inline"` 561 | metav1.ListMeta `json:"metadata,omitempty"` 562 | Items []VirtualMachinePublishRequest `json:"items"` 563 | } 564 | 565 | func init() { 566 | RegisterTypeWithScheme( 567 | &VirtualMachinePublishRequest{}, 568 | &VirtualMachinePublishRequestList{}, 569 | ) 570 | } 571 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachineservice_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // VirtualMachineServiceType string describes ingress methods for a service. 11 | type VirtualMachineServiceType string 12 | 13 | // These types correspond to a subset of the core Service Types. 14 | const ( 15 | // VirtualMachineServiceTypeClusterIP means a service will only be accessible inside the 16 | // cluster, via the cluster IP. 17 | VirtualMachineServiceTypeClusterIP VirtualMachineServiceType = "ClusterIP" 18 | 19 | // VirtualMachineServiceTypeLoadBalancer means a service will be exposed via an 20 | // external load balancer (if the cloud provider supports it), in addition 21 | // to 'NodePort' type. 22 | VirtualMachineServiceTypeLoadBalancer VirtualMachineServiceType = "LoadBalancer" 23 | 24 | // VirtualMachineServiceTypeExternalName means a service consists of only a reference to 25 | // an external name that kubedns or equivalent will return as a CNAME 26 | // record, with no exposing or proxying of any VirtualMachines involved. 27 | VirtualMachineServiceTypeExternalName VirtualMachineServiceType = "ExternalName" 28 | ) 29 | 30 | // VirtualMachineServicePort describes the specification of a service port to be exposed by a VirtualMachineService. 31 | // This VirtualMachineServicePort specification includes attributes that define the external and internal 32 | // representation of the service port. 33 | type VirtualMachineServicePort struct { 34 | // Name describes the name to be used to identify this VirtualMachineServicePort 35 | Name string `json:"name"` 36 | 37 | // Protocol describes the Layer 4 transport protocol for this port. Supports "TCP", "UDP", and "SCTP". 38 | Protocol string `json:"protocol"` 39 | 40 | // Port describes the external port that will be exposed by the service. 41 | Port int32 `json:"port"` 42 | 43 | // TargetPort describes the internal port open on a VirtualMachine that should be mapped to the external Port. 44 | TargetPort int32 `json:"targetPort"` 45 | } 46 | 47 | // LoadBalancerStatus represents the status of a load balancer. 48 | type LoadBalancerStatus struct { 49 | // Ingress is a list containing ingress addresses for the load balancer. 50 | // Traffic intended for the service should be sent to any of these ingress points. 51 | // +optional 52 | Ingress []LoadBalancerIngress `json:"ingress,omitempty"` 53 | } 54 | 55 | // LoadBalancerIngress represents the status of a load balancer ingress point: 56 | // traffic intended for the service should be sent to an ingress point. 57 | // IP or Hostname may both be set in this structure. It is up to the consumer to determine which 58 | // field should be used when accessing this LoadBalancer. 59 | type LoadBalancerIngress struct { 60 | // IP is set for load balancer ingress points that are specified by an IP address. 61 | // +optional 62 | IP string `json:"ip,omitempty"` 63 | 64 | // Hostname is set for load balancer ingress points that are specified by a DNS address. 65 | // +optional 66 | Hostname string `json:"hostname,omitempty"` 67 | } 68 | 69 | // VirtualMachineServiceSpec defines the desired state of VirtualMachineService. Each VirtualMachineService exposes 70 | // a set of TargetPorts on a set of VirtualMachine instances as a network endpoint within or outside of the 71 | // Kubernetes cluster. The VirtualMachineService is loosely coupled to the VirtualMachines that are backing it through 72 | // the use of a Label Selector. In Kubernetes, a Label Selector enables matching of a resource using a set of 73 | // key-value pairs, aka Labels. By using a Label Selector, the VirtualMachineService can be generically defined to apply 74 | // to any VirtualMachine in the same namespace that has the appropriate set of labels. 75 | type VirtualMachineServiceSpec struct { 76 | // Type specifies a desired VirtualMachineServiceType for this VirtualMachineService. Supported types 77 | // are ClusterIP, LoadBalancer, ExternalName. 78 | Type VirtualMachineServiceType `json:"type"` 79 | 80 | // Ports specifies a list of VirtualMachineServicePort to expose with this VirtualMachineService. Each of these ports 81 | // will be an accessible network entry point to access this service by. 82 | Ports []VirtualMachineServicePort `json:"ports,omitempty"` 83 | 84 | // Selector specifies a map of key-value pairs, also known as a Label Selector, that is used to match this 85 | // VirtualMachineService with the set of VirtualMachines that should back this VirtualMachineService. 86 | // +optional 87 | Selector map[string]string `json:"selector,omitempty"` 88 | 89 | // Only applies to VirtualMachineService Type: LoadBalancer 90 | // LoadBalancer will get created with the IP specified in this field. 91 | // This feature depends on whether the underlying load balancer provider supports specifying 92 | // the loadBalancerIP when a load balancer is created. 93 | // This field will be ignored if the provider does not support the feature. 94 | // +optional 95 | LoadBalancerIP string `json:"loadBalancerIP,omitempty"` 96 | 97 | // LoadBalancerSourceRanges is an array of IP addresses in the format of 98 | // CIDRs, for example: 103.21.244.0/22 and 10.0.0.0/24. 99 | // If specified and supported by the load balancer provider, this will restrict 100 | // ingress traffic to the specified client IPs. This field will be ignored if the 101 | // provider does not support the feature. 102 | // +optional 103 | LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty"` 104 | 105 | // clusterIP is the IP address of the service and is usually assigned 106 | // randomly by the master. If an address is specified manually and is not in 107 | // use by others, it will be allocated to the service; otherwise, creation 108 | // of the service will fail. This field can not be changed through updates. 109 | // Valid values are "None", empty string (""), or a valid IP address. "None" 110 | // can be specified for headless services when proxying is not required. 111 | // Only applies to types ClusterIP and LoadBalancer. 112 | // Ignored if type is ExternalName. 113 | // More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies 114 | // +optional 115 | ClusterIP string `json:"clusterIp,omitempty"` 116 | 117 | // externalName is the external reference that kubedns or equivalent will 118 | // return as a CNAME record for this service. No proxying will be involved. 119 | // Must be a valid RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) 120 | // and requires Type to be ExternalName. 121 | // +optional 122 | ExternalName string `json:"externalName,omitempty"` 123 | } 124 | 125 | // VirtualMachineServiceStatus defines the observed state of VirtualMachineService. 126 | type VirtualMachineServiceStatus struct { 127 | // LoadBalancer contains the current status of the load balancer, 128 | // if one is present. 129 | // +optional 130 | LoadBalancer LoadBalancerStatus `json:"loadBalancer,omitempty"` 131 | } 132 | 133 | // +kubebuilder:object:root=true 134 | // +kubebuilder:resource:shortName=vmservice 135 | // +kubebuilder:storageversion 136 | // +kubebuilder:subresource:status 137 | // +kubebuilder:printcolumn:name="Type",type="string",JSONPath=".spec.type" 138 | // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" 139 | 140 | // VirtualMachineService is the Schema for the virtualmachineservices API. 141 | // A VirtualMachineService represents the desired specification and the observed status of a VirtualMachineService 142 | // instance. A VirtualMachineService represents a network service, provided by one or more VirtualMachines, that is 143 | // desired to be exposed to other workloads both internal and external to the cluster. 144 | type VirtualMachineService struct { 145 | metav1.TypeMeta `json:",inline"` 146 | metav1.ObjectMeta `json:"metadata,omitempty"` 147 | 148 | Spec VirtualMachineServiceSpec `json:"spec,omitempty"` 149 | Status VirtualMachineServiceStatus `json:"status,omitempty"` 150 | } 151 | 152 | func (s *VirtualMachineService) NamespacedName() string { 153 | return s.Namespace + "/" + s.Name 154 | } 155 | 156 | // +kubebuilder:object:root=true 157 | 158 | // VirtualMachineServiceList contains a list of VirtualMachineService. 159 | type VirtualMachineServiceList struct { 160 | metav1.TypeMeta `json:",inline"` 161 | metav1.ListMeta `json:"metadata,omitempty"` 162 | Items []VirtualMachineService `json:"items"` 163 | } 164 | 165 | func init() { 166 | RegisterTypeWithScheme(&VirtualMachineService{}, &VirtualMachineServiceList{}) 167 | } 168 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachinesetresourcepolicy_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // ResourcePoolSpec defines a Logical Grouping of workloads that share resource policies. 11 | type ResourcePoolSpec struct { 12 | // Name describes the name of the ResourcePool grouping. 13 | // +optional 14 | Name string `json:"name,omitempty"` 15 | 16 | // Reservations describes the guaranteed resources reserved for the ResourcePool. 17 | // +optional 18 | Reservations VirtualMachineResourceSpec `json:"reservations,omitempty"` 19 | 20 | // Limits describes the limit to resources available to the ResourcePool. 21 | // +optional 22 | Limits VirtualMachineResourceSpec `json:"limits,omitempty"` 23 | } 24 | 25 | // FolderSpec defines a Folder. 26 | type FolderSpec struct { 27 | // Name describes the name of the Folder 28 | // +optional 29 | Name string `json:"name,omitempty"` 30 | } 31 | 32 | // ClusterModuleSpec defines a grouping of VirtualMachines that are to be grouped together as a logical unit by 33 | // the infrastructure provider. Within vSphere, the ClusterModuleSpec maps directly to a vSphere ClusterModule. 34 | type ClusterModuleSpec struct { 35 | // GroupName describes the name of the ClusterModule Group. 36 | GroupName string `json:"groupname"` 37 | } 38 | 39 | // VirtualMachineSetResourcePolicySpec defines the desired state of VirtualMachineSetResourcePolicy. 40 | type VirtualMachineSetResourcePolicySpec struct { 41 | ResourcePool ResourcePoolSpec `json:"resourcepool,omitempty"` 42 | Folder FolderSpec `json:"folder,omitempty"` 43 | ClusterModules []ClusterModuleSpec `json:"clustermodules,omitempty"` 44 | } 45 | 46 | // VirtualMachineSetResourcePolicyStatus defines the observed state of VirtualMachineSetResourcePolicy. 47 | type VirtualMachineSetResourcePolicyStatus struct { 48 | ClusterModules []ClusterModuleStatus `json:"clustermodules,omitempty"` 49 | } 50 | 51 | type ClusterModuleStatus struct { 52 | GroupName string `json:"groupname"` 53 | ModuleUuid string `json:"moduleUUID"` //nolint:revive,stylecheck 54 | ClusterMoID string `json:"clusterMoID"` 55 | } 56 | 57 | // +kubebuilder:object:root=true 58 | // +kubebuilder:storageversion 59 | // +kubebuilder:subresource:status 60 | 61 | // VirtualMachineSetResourcePolicy is the Schema for the virtualmachinesetresourcepolicies API. 62 | type VirtualMachineSetResourcePolicy struct { 63 | metav1.TypeMeta `json:",inline"` 64 | metav1.ObjectMeta `json:"metadata,omitempty"` 65 | 66 | Spec VirtualMachineSetResourcePolicySpec `json:"spec,omitempty"` 67 | Status VirtualMachineSetResourcePolicyStatus `json:"status,omitempty"` 68 | } 69 | 70 | func (res VirtualMachineSetResourcePolicy) NamespacedName() string { 71 | return res.Namespace + "/" + res.Name 72 | } 73 | 74 | // +kubebuilder:object:root=true 75 | 76 | // VirtualMachineSetResourcePolicyList contains a list of VirtualMachineSetResourcePolicy. 77 | type VirtualMachineSetResourcePolicyList struct { 78 | metav1.TypeMeta `json:",inline"` 79 | metav1.ListMeta `json:"metadata,omitempty"` 80 | Items []VirtualMachineSetResourcePolicy `json:"items"` 81 | } 82 | 83 | func init() { 84 | RegisterTypeWithScheme(&VirtualMachineSetResourcePolicy{}, &VirtualMachineSetResourcePolicyList{}) 85 | } 86 | -------------------------------------------------------------------------------- /api/v1alpha1/virtualmachinetempl_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | // NetworkDeviceStatus defines the network interface IP configuration including 7 | // gateway, subnetmask and IP address as seen by OVF properties. 8 | type NetworkDeviceStatus struct { 9 | // Gateway4 is the gateway for the IPv4 address family for this device. 10 | // +optional 11 | Gateway4 string 12 | 13 | // IpAddresses represents one or more IP addresses assigned to the network 14 | // device in CIDR notation, ex. "192.0.2.1/16". 15 | // +optional 16 | IPAddresses []string 17 | } 18 | 19 | // NetworkStatus describes the observed state of the VM's network configuration. 20 | type NetworkStatus struct { 21 | // Devices describe a list of current status information for each 22 | // network interface that is desired to be attached to the 23 | // VirtualMachineTemplate. 24 | // +optional 25 | Devices []NetworkDeviceStatus 26 | 27 | // Nameservers describe a list of the DNS servers accessible by one of the 28 | // VM's configured network devices. 29 | // +optional 30 | Nameservers []string 31 | } 32 | 33 | // VirtualMachineTemplate defines the specification for configuring 34 | // VirtualMachine Template. A Virtual Machine Template is created during VM 35 | // customization to populate OVF properties. Then by utilizing Golang-based 36 | // templating, Virtual Machine Template provides access to dynamic configuration 37 | // data. 38 | type VirtualMachineTemplate struct { 39 | // Net describes the observed state of the VM's network configuration. 40 | // +optional 41 | Net NetworkStatus 42 | 43 | // VM represents a pointer to a VirtualMachine instance that consist of the 44 | // desired specification and the observed status 45 | VM *VirtualMachine 46 | } 47 | -------------------------------------------------------------------------------- /api/v1alpha1/webconsolerequest_types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package v1alpha1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | // WebConsoleRequestSpec describes the specification for used to request a web console request. 11 | type WebConsoleRequestSpec struct { 12 | // VirtualMachineName is the VM in the same namespace, for which the web console is requested. 13 | VirtualMachineName string `json:"virtualMachineName"` 14 | // PublicKey is used to encrypt the status.response. This is expected to be a RSA OAEP public key in X.509 PEM format. 15 | PublicKey string `json:"publicKey"` 16 | } 17 | 18 | // WebConsoleRequestStatus defines the observed state, which includes the web console request itself. 19 | type WebConsoleRequestStatus struct { 20 | // Response will be the authenticated ticket corresponding to this web console request. 21 | Response string `json:"response,omitempty"` 22 | // ExpiryTime is when the ticket referenced in Response will expire. 23 | ExpiryTime metav1.Time `json:"expiryTime,omitempty"` 24 | } 25 | 26 | // +kubebuilder:object:root=true 27 | // +kubebuilder:resource:scope=Namespaced 28 | // +kubebuilder:storageversion 29 | // +kubebuilder:subresource:status 30 | 31 | // WebConsoleRequest allows the creation of a one-time web console ticket that can be used to interact with the VM. 32 | type WebConsoleRequest struct { 33 | metav1.TypeMeta `json:",inline"` 34 | metav1.ObjectMeta `json:"metadata,omitempty"` 35 | 36 | Spec WebConsoleRequestSpec `json:"spec,omitempty"` 37 | Status WebConsoleRequestStatus `json:"status,omitempty"` 38 | } 39 | 40 | func (s *WebConsoleRequest) NamespacedName() string { 41 | return s.Namespace + "/" + s.Name 42 | } 43 | 44 | // +kubebuilder:object:root=true 45 | 46 | // WebConsoleRequestList contains a list of WebConsoleRequests. 47 | type WebConsoleRequestList struct { 48 | metav1.TypeMeta `json:",inline"` 49 | metav1.ListMeta `json:"metadata,omitempty"` 50 | Items []WebConsoleRequest `json:"items"` 51 | } 52 | 53 | func init() { 54 | RegisterTypeWithScheme(&WebConsoleRequest{}, &WebConsoleRequestList{}) 55 | } 56 | -------------------------------------------------------------------------------- /cspell.config.yaml: -------------------------------------------------------------------------------- 1 | ignorePaths: 2 | - ./**/go.mod 3 | - ./**/go.sum 4 | - ./config/crd/bases/**/* 5 | - ./api/v1alpha2/cloudinit/v22.3/**/* 6 | - ./**/bin/**/* 7 | - ./.golangci.yml 8 | words: 9 | - abspath 10 | - akutz 11 | - apimachinery 12 | - authkeys 13 | - bryanv 14 | - clientset 15 | - Cloudbase 16 | - cloudinit 17 | - clustermodules 18 | - commmands 19 | - contentlibraryproviders 20 | - contentsources 21 | - corev 22 | - corrieb 23 | - cpus 24 | - Cpus 25 | - crds 26 | - deepcopy 27 | - derekbeard 28 | - dhclient 29 | - envtest 30 | - expiredate 31 | - faillog 32 | - gecos 33 | - GOARCH 34 | - golangci 35 | - GOLANGCI 36 | - gomega 37 | - GOSC 38 | - govmomi 39 | - groupname 40 | - guestinfo 41 | - gzipped 42 | - ifneq 43 | - imageregistry 44 | - intstr 45 | - koalaman 46 | - kubebuilder 47 | - kubedns 48 | - Kutz 49 | - lastlog 50 | - linklayer 51 | - Linuxprep 52 | - markdownlint 53 | - mdlrc 54 | - metav 55 | - mivok 56 | - mykey 57 | - nolint 58 | - openapi 59 | - Prereq 60 | - prereqs 61 | - printcolumn 62 | - proxying 63 | - resourcepool 64 | - Roadmap 65 | - rpctool 66 | - runcmd 67 | - shellcheck 68 | - snapuser 69 | - storageVersion 70 | - stylecheck 71 | - subnetmask 72 | - subresource 73 | - substr 74 | - Sysrep 75 | - systcl 76 | - Systeprep 77 | - tanzu 78 | - templating 79 | - unexported 80 | - userdata 81 | - utilruntime 82 | - VADP 83 | - Venteicher 84 | - vgpu 85 | - VGPU 86 | - virtualmachineclasses 87 | - virtualmachinedefaults 88 | - virtualmachineimages 89 | - virtualmachines 90 | - virtualmachineservices 91 | - virtualmachinesetresourcepolicies 92 | - vmclass 93 | - vmclassbinding 94 | - vmdefaults 95 | - vmimage 96 | - VMIP 97 | - Vmop 98 | - vmoperator 99 | - vmpr 100 | - vmpub 101 | - vmservice 102 | - VMTX 103 | - workdir 104 | - zoneinfo 105 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/vmware-tanzu/vm-operator-api 2 | 3 | go 1.17 4 | 5 | require ( 6 | k8s.io/api v0.23.1 7 | k8s.io/apimachinery v0.23.1 8 | ) 9 | 10 | require ( 11 | github.com/go-logr/logr v1.2.0 // indirect 12 | github.com/gogo/protobuf v1.3.2 // indirect 13 | github.com/google/go-cmp v0.5.5 // indirect 14 | github.com/google/gofuzz v1.1.0 // indirect 15 | github.com/json-iterator/go v1.1.12 // indirect 16 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 17 | github.com/modern-go/reflect2 v1.0.2 // indirect 18 | golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect 19 | golang.org/x/text v0.3.7 // indirect 20 | gopkg.in/inf.v0 v0.9.1 // indirect 21 | gopkg.in/yaml.v2 v2.4.0 // indirect 22 | k8s.io/klog/v2 v2.30.0 // indirect 23 | k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect 24 | sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect 25 | sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 4 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 5 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 6 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 7 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 8 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 9 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 10 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 12 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 13 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 14 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 15 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 16 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 17 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 18 | github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 19 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 20 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 21 | github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= 22 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 23 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 24 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 25 | github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= 26 | github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 27 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 28 | github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 29 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= 30 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 31 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 32 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 33 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 34 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 35 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 36 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 37 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 38 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 39 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 40 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 41 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 42 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 43 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 44 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 45 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 46 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 47 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 48 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 49 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 50 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 51 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 52 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 53 | github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= 54 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 55 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 56 | github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= 57 | github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= 58 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 59 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 60 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 61 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 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.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 67 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 68 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 69 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 70 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 71 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 72 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 73 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 74 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 75 | github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= 76 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 77 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 78 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 79 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 80 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 81 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 82 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 83 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= 84 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 85 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 86 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 87 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 88 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 89 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 90 | github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= 91 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 92 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 93 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 94 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 95 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 96 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 97 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 98 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 99 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 100 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 101 | github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= 102 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 103 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 104 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 105 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 106 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 107 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 108 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 109 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 110 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 111 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 112 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 113 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 114 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 115 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 116 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 117 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 118 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 119 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 120 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 121 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 122 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 123 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 124 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 125 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 126 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 127 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 128 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 129 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 130 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 131 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 132 | golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= 133 | golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 134 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 135 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 136 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 137 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 138 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 139 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 140 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 141 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 142 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 143 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 144 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 145 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 146 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 147 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 148 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 149 | golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 150 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 151 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 152 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 153 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 154 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 155 | golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 156 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 157 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 158 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 159 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 160 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 161 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 162 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= 163 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 164 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 165 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 166 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 167 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 168 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 169 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 170 | golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 171 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 172 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 173 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 174 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 175 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 176 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 177 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 178 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 179 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 180 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 181 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 182 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 183 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 184 | google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 185 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 186 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 187 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 188 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 189 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 190 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 191 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 192 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 193 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 194 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 195 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 196 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 197 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 198 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 199 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 200 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 201 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 202 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 203 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= 204 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 205 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 206 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 207 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 208 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 209 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 210 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 211 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 212 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 213 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 214 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 215 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 216 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 217 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 218 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 219 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 220 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 221 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 222 | k8s.io/api v0.23.1 h1:ncu/qfBfUoClqwkTGbeRqqOqBCRoUAflMuOaOD7J0c8= 223 | k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo= 224 | k8s.io/apimachinery v0.23.1 h1:sfBjlDFwj2onG0Ijx5C+SrAoeUscPrmghm7wHP+uXlo= 225 | k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno= 226 | k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 227 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 228 | k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= 229 | k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= 230 | k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= 231 | k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= 232 | k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 233 | k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs= 234 | k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 235 | sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= 236 | sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= 237 | sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 238 | sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= 239 | sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= 240 | sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= 241 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= 242 | -------------------------------------------------------------------------------- /hack/boilerplate/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | -------------------------------------------------------------------------------- /hack/samples/Makefile: -------------------------------------------------------------------------------- 1 | # If you update this file, please follow 2 | # https://suva.sh/posts/well-documented-makefiles 3 | 4 | # Ensure Make is run with bash shell as some syntax below is bash-specific 5 | SHELL := /usr/bin/env bash 6 | 7 | .DEFAULT_GOAL := help 8 | 9 | # Active module mode, as we use go modules to manage dependencies 10 | export GO111MODULE := on 11 | 12 | # Directories. 13 | BIN_DIR := bin 14 | 15 | HOST_OS=$(shell go env GOOS) 16 | HOST_ARCH=$(shell go env GOARCH) 17 | 18 | # Binaries. 19 | LIST_CTRL := $(BIN_DIR)/list-ctrl 20 | 21 | .PHONY: all 22 | all: prereqs list-ctrl ## Build all the samples 23 | 24 | prereqs: 25 | cd ../../; $(MAKE) generate-manifests 26 | 27 | ## -------------------------------------- 28 | ##@ Help 29 | ## -------------------------------------- 30 | 31 | help: ## Display this help 32 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-18s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 33 | 34 | ## -------------------------------------- 35 | ##@ Binaries 36 | ## -------------------------------------- 37 | 38 | .PHONY: $(LIST_CTRL) 39 | list-ctrl: prereqs $(LIST_CTRL) ## Build list sample with controller client 40 | $(LIST_CTRL): go.mod 41 | go build -o $@ github.com/vmware-tanzu/vm-operator-api/hack/samples/controller 42 | 43 | ## -------------------------------------- 44 | ##@ Cleanup 45 | ## -------------------------------------- 46 | 47 | .PHONY: clean 48 | clean: ## Run all the clean targets 49 | $(MAKE) clean-bin 50 | 51 | .PHONY: clean-bin 52 | clean-bin: ## Remove all binaries 53 | rm -rf bin 54 | -------------------------------------------------------------------------------- /hack/samples/README.md: -------------------------------------------------------------------------------- 1 | # Sample Code 2 | 3 | Sample code demonstrating how to use the vm-operator-api in your project 4 | 5 | ## Prerequisites 6 | 7 | The sample code sets up a local Kubernetes cluster and populates it with vm-operator-api CRD types. 8 | In order to successfully run the samples, these types need to be generated with `make generate-manifests` 9 | in the project root. This is also done automatically if you run `make all` in the samples directory. 10 | 11 | ## Controller Client Samples 12 | 13 | The client in `sigs.k8s.io/controller-runtime/pkg/client` take a different approach to managing custom 14 | resources. It is both dynamic and opinionated and it's what you will likely use if you build a controller 15 | using kubebuilder. Note that it doesn't provide a Watch function as watching resources is a capability 16 | inherent to a controller. 17 | 18 | Note that the scheme for the vm-operator-api needs to be explicitly added to the client 19 | 20 | ## Build and run 21 | 22 | Building and running the samples is really simple 23 | 24 | ```bash 25 | cd hack/samples 26 | make all 27 | bin/list-ctrl 28 | ``` -------------------------------------------------------------------------------- /hack/samples/controller/list.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | package main 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "path/filepath" 9 | 10 | "github.com/vmware-tanzu/vm-operator-api/api/v1alpha1" 11 | 12 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 | "k8s.io/apimachinery/pkg/runtime" 14 | "k8s.io/client-go/rest" 15 | 16 | ctrlClient "sigs.k8s.io/controller-runtime/pkg/client" 17 | "sigs.k8s.io/controller-runtime/pkg/envtest" 18 | ) 19 | 20 | var testEnv *envtest.Environment 21 | 22 | const namespace string = "default" 23 | 24 | // List VirtualMachines in a target cluster to stdout using a controller client 25 | func main() { 26 | fmt.Printf("Starting test env...\n") 27 | testClient, err := startTestEnv() 28 | if err != nil { 29 | panic(err) 30 | } 31 | defer func() { 32 | fmt.Printf("Stopping test env...\n") 33 | testEnv.Stop() 34 | }() 35 | 36 | vmOpClient, err := getVmopClient(testClient) 37 | if err != nil { 38 | panic(err) 39 | } 40 | 41 | fmt.Printf("Populating test env...\n") 42 | err = populateTestEnv(vmOpClient, "test-vm1") 43 | if err != nil { 44 | panic(err) 45 | } 46 | err = populateTestEnv(vmOpClient, "test-vm2") 47 | if err != nil { 48 | panic(err) 49 | } 50 | 51 | fmt.Printf("Listing VMs:\n") 52 | vmList := v1alpha1.VirtualMachineList{} 53 | err = vmOpClient.List(context.TODO(), &vmList) 54 | if err != nil { 55 | panic(err) 56 | } 57 | for _, vm := range vmList.Items { 58 | fmt.Printf("- %s\n", vm.GetName()) 59 | } 60 | } 61 | 62 | // Get a vm-operator-api client from the generated clientset 63 | func getVmopClient(config *rest.Config) (ctrlClient.Client, error) { 64 | scheme := runtime.NewScheme() 65 | _ = v1alpha1.AddToScheme(scheme) 66 | client, err := ctrlClient.New(config, ctrlClient.Options{ 67 | Scheme: scheme, 68 | }) 69 | return client, err 70 | } 71 | 72 | func startTestEnv() (*rest.Config, error) { 73 | testEnv = &envtest.Environment{ 74 | CRDDirectoryPaths: []string{ 75 | filepath.Join("..", "..", "config", "crd", "bases"), 76 | }, 77 | } 78 | 79 | return testEnv.Start() 80 | } 81 | 82 | func populateTestEnv(client ctrlClient.Client, name string) error { 83 | newVM := v1alpha1.VirtualMachine{ 84 | ObjectMeta: metav1.ObjectMeta{ 85 | Name: name, 86 | Namespace: namespace, 87 | }, 88 | } 89 | return client.Create(context.TODO(), &newVM) 90 | } 91 | -------------------------------------------------------------------------------- /hack/samples/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/vmware-tanzu/vm-operator-api/hack/samples 2 | 3 | go 1.17 4 | 5 | // The generated client is not part of the release, so point to the local version that includes the generated code 6 | // Note also that vm-operator-api is not specified in require the samples automatically pull in the latest 7 | replace github.com/vmware-tanzu/vm-operator-api => ../../../vm-operator-api 8 | 9 | require ( 10 | github.com/vmware-tanzu/vm-operator-api v0.0.0-00010101000000-000000000000 11 | k8s.io/apimachinery v0.23.5 12 | k8s.io/client-go v0.23.5 13 | sigs.k8s.io/controller-runtime v0.11.2 14 | ) 15 | 16 | require ( 17 | github.com/davecgh/go-spew v1.1.1 // indirect 18 | github.com/evanphx/json-patch v4.12.0+incompatible // indirect 19 | github.com/go-logr/logr v1.2.0 // indirect 20 | github.com/gogo/protobuf v1.3.2 // indirect 21 | github.com/golang/protobuf v1.5.2 // indirect 22 | github.com/google/go-cmp v0.5.5 // indirect 23 | github.com/google/gofuzz v1.1.0 // indirect 24 | github.com/googleapis/gnostic v0.5.5 // indirect 25 | github.com/imdario/mergo v0.3.12 // indirect 26 | github.com/json-iterator/go v1.1.12 // indirect 27 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 28 | github.com/modern-go/reflect2 v1.0.2 // indirect 29 | github.com/pkg/errors v0.9.1 // indirect 30 | github.com/spf13/pflag v1.0.5 // indirect 31 | golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect 32 | golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect 33 | golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect 34 | golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect 35 | golang.org/x/text v0.3.7 // indirect 36 | golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect 37 | google.golang.org/appengine v1.6.7 // indirect 38 | google.golang.org/protobuf v1.27.1 // indirect 39 | gopkg.in/inf.v0 v0.9.1 // indirect 40 | gopkg.in/yaml.v2 v2.4.0 // indirect 41 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 42 | k8s.io/api v0.23.5 // indirect 43 | k8s.io/apiextensions-apiserver v0.23.5 // indirect 44 | k8s.io/klog/v2 v2.30.0 // indirect 45 | k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect 46 | k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect 47 | sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect 48 | sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect 49 | sigs.k8s.io/yaml v1.3.0 // indirect 50 | ) 51 | -------------------------------------------------------------------------------- /hack/tools/Makefile: -------------------------------------------------------------------------------- 1 | # If you update this file, please follow 2 | # https://suva.sh/posts/well-documented-makefiles 3 | 4 | # Ensure Make is run with bash shell as some syntax below is bash-specific 5 | SHELL := /usr/bin/env bash 6 | 7 | .DEFAULT_GOAL := help 8 | 9 | # Active module mode, as we use go modules to manage dependencies 10 | export GO111MODULE := on 11 | 12 | # Directories. 13 | BIN_DIR := bin 14 | 15 | HOST_OS=$(shell go env GOOS) 16 | HOST_ARCH=$(shell go env GOARCH) 17 | 18 | # Binaries. 19 | CONTROLLER_GEN := $(BIN_DIR)/controller-gen 20 | GOLANGCI_LINT := $(BIN_DIR)/golangci-lint 21 | 22 | ## -------------------------------------- 23 | ##@ Help 24 | ## -------------------------------------- 25 | 26 | help: ## Display this help 27 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-18s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 28 | 29 | ## -------------------------------------- 30 | ##@ Binaries 31 | ## -------------------------------------- 32 | 33 | .PHONY: $(CONTROLLER_GEN) 34 | controller-gen: $(CONTROLLER_GEN) ## Install controller-gen 35 | $(CONTROLLER_GEN): go.mod 36 | go build -tags=tools -o $@ sigs.k8s.io/controller-tools/cmd/controller-gen 37 | 38 | .PHONY: $(GOLANGCI_LINT) 39 | golangci-lint: $(GOLANGCI_LINT) ## Install golangci-lint 40 | $(GOLANGCI_LINT): 41 | go build -tags=tools -o $@ github.com/golangci/golangci-lint/cmd/golangci-lint 42 | 43 | ## -------------------------------------- 44 | ##@ Generate 45 | ## -------------------------------------- 46 | 47 | .PHONY: modules 48 | modules: ## Runs go mod tidy to validate modules 49 | go mod tidy -v 50 | 51 | .PHONY: modules-download 52 | modules-download: ## Downloads and caches the modules 53 | go mod download 54 | 55 | ## -------------------------------------- 56 | ##@ Cleanup 57 | ## -------------------------------------- 58 | 59 | .PHONY: clean 60 | clean: ## Run all the clean targets 61 | $(MAKE) clean-bin 62 | 63 | .PHONY: clean-bin 64 | clean-bin: ## Remove all generated binaries 65 | rm -rf bin 66 | -------------------------------------------------------------------------------- /hack/tools/README.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | 3 | This folder contains all of the definitions of the tools needed to build and generate the project 4 | 5 | You can either run `make ` in this directory to build a specific tool or 6 | `make tools` in the project root to make them all -------------------------------------------------------------------------------- /hack/tools/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/vmware-tanzu/vm-operator-api/hack/tools 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/golangci/golangci-lint v1.46.2 7 | sigs.k8s.io/controller-tools v0.9.2 8 | ) 9 | 10 | require ( 11 | 4d63.com/gochecknoglobals v0.1.0 // indirect 12 | github.com/Antonboom/errname v0.1.6 // indirect 13 | github.com/Antonboom/nilnil v0.1.1 // indirect 14 | github.com/BurntSushi/toml v1.1.0 // indirect 15 | github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect 16 | github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0 // indirect 17 | github.com/Masterminds/semver v1.5.0 // indirect 18 | github.com/OpenPeeDeeP/depguard v1.1.0 // indirect 19 | github.com/alexkohler/prealloc v1.0.0 // indirect 20 | github.com/ashanbrown/forbidigo v1.3.0 // indirect 21 | github.com/ashanbrown/makezero v1.1.1 // indirect 22 | github.com/beorn7/perks v1.0.1 // indirect 23 | github.com/bkielbasa/cyclop v1.2.0 // indirect 24 | github.com/blizzy78/varnamelen v0.8.0 // indirect 25 | github.com/bombsimon/wsl/v3 v3.3.0 // indirect 26 | github.com/breml/bidichk v0.2.3 // indirect 27 | github.com/breml/errchkjson v0.3.0 // indirect 28 | github.com/butuzov/ireturn v0.1.1 // indirect 29 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 30 | github.com/charithe/durationcheck v0.0.9 // indirect 31 | github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect 32 | github.com/daixiang0/gci v0.3.3 // indirect 33 | github.com/davecgh/go-spew v1.1.1 // indirect 34 | github.com/denis-tingaikin/go-header v0.4.3 // indirect 35 | github.com/esimonov/ifshort v1.0.4 // indirect 36 | github.com/ettle/strcase v0.1.1 // indirect 37 | github.com/fatih/color v1.13.0 // indirect 38 | github.com/fatih/structtag v1.2.0 // indirect 39 | github.com/firefart/nonamedreturns v1.0.1 // indirect 40 | github.com/fsnotify/fsnotify v1.5.4 // indirect 41 | github.com/fzipp/gocyclo v0.5.1 // indirect 42 | github.com/go-critic/go-critic v0.6.3 // indirect 43 | github.com/go-logr/logr v1.2.0 // indirect 44 | github.com/go-toolsmith/astcast v1.0.0 // indirect 45 | github.com/go-toolsmith/astcopy v1.0.0 // indirect 46 | github.com/go-toolsmith/astequal v1.0.1 // indirect 47 | github.com/go-toolsmith/astfmt v1.0.0 // indirect 48 | github.com/go-toolsmith/astp v1.0.0 // indirect 49 | github.com/go-toolsmith/strparse v1.0.0 // indirect 50 | github.com/go-toolsmith/typep v1.0.2 // indirect 51 | github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect 52 | github.com/gobuffalo/flect v0.2.5 // indirect 53 | github.com/gobwas/glob v0.2.3 // indirect 54 | github.com/gofrs/flock v0.8.1 // indirect 55 | github.com/gogo/protobuf v1.3.2 // indirect 56 | github.com/golang/protobuf v1.5.2 // indirect 57 | github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect 58 | github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect 59 | github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect 60 | github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect 61 | github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect 62 | github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect 63 | github.com/golangci/misspell v0.3.5 // indirect 64 | github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect 65 | github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect 66 | github.com/google/go-cmp v0.5.7 // indirect 67 | github.com/google/gofuzz v1.1.0 // indirect 68 | github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect 69 | github.com/gostaticanalysis/analysisutil v0.7.1 // indirect 70 | github.com/gostaticanalysis/comment v1.4.2 // indirect 71 | github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect 72 | github.com/gostaticanalysis/nilerr v0.1.1 // indirect 73 | github.com/hashicorp/errwrap v1.0.0 // indirect 74 | github.com/hashicorp/go-multierror v1.1.1 // indirect 75 | github.com/hashicorp/go-version v1.4.0 // indirect 76 | github.com/hashicorp/hcl v1.0.0 // indirect 77 | github.com/hexops/gotextdiff v1.0.3 // indirect 78 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 79 | github.com/jgautheron/goconst v1.5.1 // indirect 80 | github.com/jingyugao/rowserrcheck v1.1.1 // indirect 81 | github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect 82 | github.com/json-iterator/go v1.1.12 // indirect 83 | github.com/julz/importas v0.1.0 // indirect 84 | github.com/kisielk/errcheck v1.6.0 // indirect 85 | github.com/kisielk/gotool v1.0.0 // indirect 86 | github.com/kulti/thelper v0.6.2 // indirect 87 | github.com/kunwardeep/paralleltest v1.0.3 // indirect 88 | github.com/kyoh86/exportloopref v0.1.8 // indirect 89 | github.com/ldez/gomoddirectives v0.2.3 // indirect 90 | github.com/ldez/tagliatelle v0.3.1 // indirect 91 | github.com/leonklingele/grouper v1.1.0 // indirect 92 | github.com/lufeee/execinquery v1.2.1 // indirect 93 | github.com/magiconair/properties v1.8.6 // indirect 94 | github.com/maratori/testpackage v1.0.1 // indirect 95 | github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect 96 | github.com/mattn/go-colorable v0.1.12 // indirect 97 | github.com/mattn/go-isatty v0.0.14 // indirect 98 | github.com/mattn/go-runewidth v0.0.9 // indirect 99 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect 100 | github.com/mbilski/exhaustivestruct v1.2.0 // indirect 101 | github.com/mgechev/revive v1.2.1 // indirect 102 | github.com/mitchellh/go-homedir v1.1.0 // indirect 103 | github.com/mitchellh/mapstructure v1.5.0 // indirect 104 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 105 | github.com/modern-go/reflect2 v1.0.2 // indirect 106 | github.com/moricho/tparallel v0.2.1 // indirect 107 | github.com/nakabonne/nestif v0.3.1 // indirect 108 | github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect 109 | github.com/nishanths/exhaustive v0.7.11 // indirect 110 | github.com/nishanths/predeclared v0.2.2 // indirect 111 | github.com/olekukonko/tablewriter v0.0.5 // indirect 112 | github.com/pelletier/go-toml v1.9.5 // indirect 113 | github.com/pelletier/go-toml/v2 v2.0.0 // indirect 114 | github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect 115 | github.com/pkg/errors v0.9.1 // indirect 116 | github.com/pmezard/go-difflib v1.0.0 // indirect 117 | github.com/polyfloyd/go-errorlint v1.0.0 // indirect 118 | github.com/prometheus/client_golang v1.12.1 // indirect 119 | github.com/prometheus/client_model v0.2.0 // indirect 120 | github.com/prometheus/common v0.32.1 // indirect 121 | github.com/prometheus/procfs v0.7.3 // indirect 122 | github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect 123 | github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect 124 | github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect 125 | github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect 126 | github.com/ryancurrah/gomodguard v1.2.3 // indirect 127 | github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect 128 | github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect 129 | github.com/securego/gosec/v2 v2.11.0 // indirect 130 | github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect 131 | github.com/sirupsen/logrus v1.8.1 // indirect 132 | github.com/sivchari/containedctx v1.0.2 // indirect 133 | github.com/sivchari/tenv v1.5.0 // indirect 134 | github.com/sonatard/noctx v0.0.1 // indirect 135 | github.com/sourcegraph/go-diff v0.6.1 // indirect 136 | github.com/spf13/afero v1.8.2 // indirect 137 | github.com/spf13/cast v1.4.1 // indirect 138 | github.com/spf13/cobra v1.4.0 // indirect 139 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 140 | github.com/spf13/pflag v1.0.5 // indirect 141 | github.com/spf13/viper v1.11.0 // indirect 142 | github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect 143 | github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect 144 | github.com/stretchr/objx v0.1.1 // indirect 145 | github.com/stretchr/testify v1.7.1 // indirect 146 | github.com/subosito/gotenv v1.2.0 // indirect 147 | github.com/sylvia7788/contextcheck v1.0.4 // indirect 148 | github.com/tdakkota/asciicheck v0.1.1 // indirect 149 | github.com/tetafro/godot v1.4.11 // indirect 150 | github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect 151 | github.com/tomarrell/wrapcheck/v2 v2.6.1 // indirect 152 | github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect 153 | github.com/ultraware/funlen v0.0.3 // indirect 154 | github.com/ultraware/whitespace v0.0.5 // indirect 155 | github.com/uudashr/gocognit v1.0.5 // indirect 156 | github.com/yagipy/maintidx v1.0.0 // indirect 157 | github.com/yeya24/promlinter v0.2.0 // indirect 158 | gitlab.com/bosi/decorder v0.2.1 // indirect 159 | golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect 160 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect 161 | golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect 162 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect 163 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect 164 | golang.org/x/text v0.3.7 // indirect 165 | golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a // indirect 166 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect 167 | google.golang.org/protobuf v1.28.0 // indirect 168 | gopkg.in/inf.v0 v0.9.1 // indirect 169 | gopkg.in/ini.v1 v1.66.4 // indirect 170 | gopkg.in/yaml.v2 v2.4.0 // indirect 171 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 172 | honnef.co/go/tools v0.3.1 // indirect 173 | k8s.io/api v0.24.0 // indirect 174 | k8s.io/apiextensions-apiserver v0.24.0 // indirect 175 | k8s.io/apimachinery v0.24.0 // indirect 176 | k8s.io/klog/v2 v2.60.1 // indirect 177 | k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect 178 | mvdan.cc/gofumpt v0.3.1 // indirect 179 | mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect 180 | mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect 181 | mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 // indirect 182 | sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect 183 | sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect 184 | sigs.k8s.io/yaml v1.3.0 // indirect 185 | ) 186 | -------------------------------------------------------------------------------- /hack/tools/tools.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 VMware, Inc. All Rights Reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build tools 5 | 6 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 7 | package tools 8 | 9 | import ( 10 | _ "sigs.k8s.io/controller-tools/cmd/controller-gen" 11 | _ "github.com/golangci/golangci-lint/cmd/golangci-lint" 12 | ) 13 | --------------------------------------------------------------------------------