diff --git a/.gitignore b/.gitignore index 41e74e35..5de36980 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,6 @@ tags secrets/* .idea cmd/manager/picchuDebug + +testbin/* + diff --git a/.travis.yml b/.travis.yml index a98e7167..0df9cb04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: go go: -- 1.17.x +- 1.19.x sudo: required diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..c261f594 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# Build the manager binary +FROM golang:1.19 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ +COPY client/ client/ +COPY prometheus/ prometheus/ +COPY plan/ plan/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/manager . +USER nonroot:nonroot + +ENTRYPOINT ["/manager"] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile index db25f3e5..d7f7a2eb 100644 --- a/Makefile +++ b/Makefile @@ -2,18 +2,14 @@ # Licensed under the Apache License, Version 2.0; see the NOTICE file. DOMAIN := medium.engineering -PACKAGE := go.$(DOMAIN)/picchu/pkg -API_PACKAGE := $(PACKAGE)/apis -GROUPS := picchu/v1alpha1 +PACKAGE := go.$(DOMAIN)/picchu +API_PACKAGE := $(PACKAGE)/api +GROUPS := v1alpha1 BOILERPLATE := hack/header.go.txt GEN := zz_generated -OPERATOR_SDK_VERSION := v0.13.0 - -platform_temp = $(subst -, ,$(ARCH)) -GOOS = $(word 1, $(platform_temp)) -GOARCH = $(word 2, $(platform_temp)) -export GOROOT = $(shell go env GOROOT) -export GO111MODULE = on +OPERATOR_SDK_VERSION := v1.0.0 +ENVTEST_ASSETS_DIR := $(shell pwd)/testbin +SHELL := /bin/bash OPERATOR_SDK_PLATFORM := unknown @@ -25,81 +21,150 @@ ifeq ($(UNAME),Darwin) OPERATOR_SDK_PLATFORM = apple-darwin endif -.PHONY: all build generate deepcopy defaulter openapi clientset crds ci test verify - -all: deps generate build -ci: all verify generate test -generate: deepcopy defaulter openapi clientset matcher - -build: - @mkdir -p build/_output/bin - go build -o build/_output/bin/picchu ./cmd/manager - go build -o build/_output/bin/picchu-webhook ./cmd/webhook - -docker: generators/operator-sdk - # https://github.com/Medium/operator-sdk/issues/1854#issuecomment-569285967 - $< build $(IMAGE) - docker build -t $(WEBHOOK_IMAGE) -f build/webhook.Dockerfile . - -deps: - go mod tidy - go mod vendor - -deepcopy: generators/operator-sdk - # https://github.com/Medium/operator-sdk/issues/1854#issuecomment-569285967 - $< generate k8s - -defaulter: generators/defaulter - $< -i $(API_PACKAGE)/$(GROUPS) -O $(GEN).defaults -h $(BOILERPLATE) - -openapi: generators/openapi-gen - $< -i $(API_PACKAGE)/$(GROUPS) -O $(GEN).openapi -p $(PACKAGE)/openapi -h $(BOILERPLATE) +# Current Operator version +VERSION ?= 0.0.1 +# Default bundle image tag +BUNDLE_IMG ?= controller-bundle:$(VERSION) +# Options for 'bundle-build' +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) +endif +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) +CRD_OPTIONS ?= "crd:allowDangerousTypes=true" + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif -clientset: generators/client - $< -p $(PACKAGE) --input-base $(API_PACKAGE) --input $(GROUPS) -n client -h $(BOILERPLATE) +all: manager +ci: test +# Run tests +test: generate fmt vet manifests + mkdir -p ${ENVTEST_ASSETS_DIR} + test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.0/hack/setup-envtest.sh + source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out + +# Build manager binary +manager: generate fmt vet + go build -o bin/manager main.go + +# Run against the configured Kubernetes cluster in ~/.kube/config +run: generate fmt vet manifests + go run ./main.go + +# Install CRDs into a cluster +install: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl apply -f - + +# Uninstall CRDs from a cluster +uninstall: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl delete -f - + +# Deploy controller in the configured Kubernetes cluster in ~/.kube/config +deploy: manifests kustomize + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | kubectl apply -f - + +# Generate manifests e.g. CRD, RBAC etc. +manifests: controller-gen + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + ./hack/kustom-parse.sh + +parse: + ./hack/kustom-parse-all.sh + +# Run go fmt against code +fmt: + go fmt ./... + +# Run go vet against code +vet: + go vet ./... + +# Generate code +generate: deps + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + +# Build the docker image +docker-build: + docker build . -t ${IMG} + +# Push the docker image +docker-push: + docker push ${IMG} + +# find or download controller-gen +# download controller-gen if necessary +controller-gen: +ifeq (, $(shell which controller-gen)) + @{ \ + set -e ;\ + CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ + cd $$CONTROLLER_GEN_TMP_DIR ;\ + go mod init tmp ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.5.0 ;\ + which controller-gen;\ + rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ + } +CONTROLLER_GEN=$(GOBIN)/controller-gen +else +CONTROLLER_GEN=$(shell which controller-gen) +endif -matcher: generators/matcher-gen - $< -i github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1 -p go.medium.engineering/picchu/pkg/test/monitoring/v1 +kustomize: +ifeq (, $(shell which kustomize)) + @{ \ + set -e ;\ + KUSTOMIZE_GEN_TMP_DIR=$$(mktemp -d) ;\ + cd $$KUSTOMIZE_GEN_TMP_DIR ;\ + go mod init tmp ;\ + go install sigs.k8s.io/kustomize/kustomize/v4@v4.5.2 ;\ + rm -rf $$KUSTOMIZE_GEN_TMP_DIR ;\ + } +KUSTOMIZE=$(GOBIN)/kustomize +else +KUSTOMIZE=$(shell which kustomize) +endif -crds: generators/operator-sdk - $< generate crds +# Generate bundle manifests and metadata, then validate generated files. +.PHONY: bundle +bundle: manifests generators/operator-sdk + generators/operator-sdk generate kustomize manifests -q + cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) + $(KUSTOMIZE) build config/manifests | generators/operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + generators/operator-sdk bundle validate ./bundle -generators/%: go.sum - @mkdir -p generators - go build -o $@ k8s.io/code-generator/cmd/$*-gen +# Build the bundle image. +.PHONY: bundle-build +bundle-build: + docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . -generators/matcher-gen: go.sum - @mkdir -p generators - go build -o $@ go.medium.engineering/kubernetes/cmd/matcher-gen -generators/openapi-gen: go.sum - @mkdir -p generators - go build -o ./generators/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen +mocks: go.sum + go get github.com/golang/mock/mockgen + mockgen --build_flags=--mod=mod -destination=mocks/client.go -package=mocks sigs.k8s.io/controller-runtime/pkg/client Client + mockgen --build_flags=--mod=mod -destination=prometheus/mocks/mock_promapi.go -package=mocks $(PACKAGE)/prometheus PromAPI + mockgen --build_flags=--mod=mod -destination=controller/releasemanager/mock_deployment.go -package=releasemanager $(PACKAGE)/controllers/releasemanager Deployment + mockgen --build_flags=--mod=mod -destination=controller/releasemanager/mock_incarnations.go -package=releasemanager $(PACKAGE)/controllers/releasemanager Incarnations + mockgen --build_flags=--mod=mod -destination=controller/releasemanager/scaling/mocks/scalabletarget_mock.go -package=mocks $(PACKAGE)/controllers/releasemanager/scaling ScalableTarget + mockgen --build_flags=--mod=mod -destination=plan/mocks/plan_mock.go -package=mocks $(PACKAGE)/plan Plan + +deps: controller-gen kustomize + go mod tidy + go mod vendor + hack/fix.sh generators/operator-sdk: @mkdir -p generators - curl -L https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk-$(OPERATOR_SDK_VERSION)-x86_64-$(OPERATOR_SDK_PLATFORM) -o $@ + test -f generators/operator-sdk || curl -L https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk-$(OPERATOR_SDK_VERSION)-x86_64-$(OPERATOR_SDK_PLATFORM) -o $@ chmod +x generators/operator-sdk - -build-dirs: - @mkdir -p _output/bin/$(GOOS)/$(GOARCH) - @mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build - -test: build-dirs - hack/test.sh - -verify: crds - hack/verify-all.sh - -fix: - hack/fix-all.sh - -mocks: go.sum - @mkdir -p generators - go get github.com/golang/mock/mockgen - mockgen -destination=pkg/mocks/client.go -package=mocks sigs.k8s.io/controller-runtime/pkg/client Client - mockgen -destination=pkg/prometheus/mocks/mock_promapi.go -package=mocks $(PACKAGE)/prometheus PromAPI - mockgen -destination=pkg/controller/releasemanager/mock_deployment.go -package=releasemanager $(PACKAGE)/controller/releasemanager Deployment - mockgen -destination=pkg/controller/releasemanager/mock_incarnations.go -package=releasemanager $(PACKAGE)/controller/releasemanager Incarnations - mockgen -destination=pkg/controller/releasemanager/scaling/mocks/scalabletarget_mock.go -package=mocks $(PACKAGE)/controller/releasemanager/scaling ScalableTarget - mockgen -destination=pkg/plan/mocks/plan_mock.go -package=mocks $(PACKAGE)/plan Plan diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 963184b5..00000000 --- a/NOTICE +++ /dev/null @@ -1,34 +0,0 @@ -Copyright 2019 A Medium Corporation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -This software contains open source components pursuant to the following licenses: - ----- - -go-sentry-api -https://github.com/atlassian/go-sentry-api - -Copyright @ 2016 Atlassian Pty Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/PROJECT b/PROJECT new file mode 100644 index 00000000..e3c2729b --- /dev/null +++ b/PROJECT @@ -0,0 +1,23 @@ +domain: picchu.medium.engineering +layout: go.kubebuilder.io/v2 +projectName: new-picchu +repo: go.medium.engineering/picchu +resources: +- group: picchu.medium.engineering + kind: Cluster + version: v1alpha1 +- group: picchu.medium.engineering + kind: ReleaseManager + version: v1alpha1 +- group: picchu.medium.engineering + kind: Mirror + version: v1alpha1 +- group: picchu.medium.engineering + kind: ClusterSecrets + version: v1alpha1 +- group: picchu.medium.engineering + kind: Revision + version: v1alpha1 +version: 3-alpha +plugins: + go.sdk.operatorframework.io/v2-alpha: {} diff --git a/README.md b/README.md deleted file mode 100644 index 6e41b10b..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -⚠️ **This is an experimental, undocumented work in progress. Don’t try to use it yet.** - ---- - -Picchu [![Build Status](https://travis-ci.com/Medium/picchu.svg?branch=main)](https://travis-ci.com/Medium/picchu) ------- - -Picchu is a deployment and release operator for Kubernetes + Istio. diff --git a/pkg/apis/addtoscheme_picchu_v1alpha1.go b/api/v1alpha1/apis/addtoscheme_v1alpha1.go similarity index 79% rename from pkg/apis/addtoscheme_picchu_v1alpha1.go rename to api/v1alpha1/apis/addtoscheme_v1alpha1.go index f5255484..ec791ad4 100644 --- a/pkg/apis/addtoscheme_picchu_v1alpha1.go +++ b/api/v1alpha1/apis/addtoscheme_v1alpha1.go @@ -1,7 +1,7 @@ package apis import ( - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + "go.medium.engineering/picchu/api/v1alpha1" ) func init() { diff --git a/pkg/apis/apis.go b/api/v1alpha1/apis/apis.go similarity index 85% rename from pkg/apis/apis.go rename to api/v1alpha1/apis/apis.go index 07dc9616..636dd3a2 100644 --- a/pkg/apis/apis.go +++ b/api/v1alpha1/apis/apis.go @@ -1,8 +1,6 @@ package apis -import ( - "k8s.io/apimachinery/pkg/runtime" -) +import "k8s.io/apimachinery/pkg/runtime" // AddToSchemes may be used to add all resources defined in the project to a Scheme var AddToSchemes runtime.SchemeBuilder diff --git a/pkg/apis/picchu/v1alpha1/cluster_types.go b/api/v1alpha1/cluster_types.go similarity index 81% rename from pkg/apis/picchu/v1alpha1/cluster_types.go rename to api/v1alpha1/cluster_types.go index fa8c9f8a..edb6ae3c 100644 --- a/pkg/apis/picchu/v1alpha1/cluster_types.go +++ b/api/v1alpha1/cluster_types.go @@ -1,3 +1,19 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( @@ -11,30 +27,8 @@ import ( clientapi "k8s.io/client-go/tools/clientcmd/api" ) -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Cluster is the Schema for the clusters API -// +k8s:openapi-gen=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Namespaced -// +kubebuilder:resource:categories=all;picchu -type Cluster struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ClusterSpec `json:"spec,omitempty"` - Status ClusterStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ClusterList contains a list of Cluster -type ClusterList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Cluster `json:"items"` -} +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // ClusterSpec defines the desired state of Cluster type ClusterSpec struct { @@ -70,6 +64,8 @@ type IngressInfo struct { // ClusterStatus defines the observed state of Cluster type ClusterStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file Kubernetes ClusterKubernetesStatus `json:"kubernetes,omitempty"` } @@ -78,6 +74,28 @@ type ClusterKubernetesStatus struct { Ready bool `json:"ready"` } +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +k8s:openapi-gen=true + +// Cluster is the Schema for the clusters API +type Cluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterSpec `json:"spec,omitempty"` + Status ClusterStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterList contains a list of Cluster +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cluster `json:"items"` +} + func init() { SchemeBuilder.Register(&Cluster{}, &ClusterList{}) } diff --git a/pkg/apis/picchu/v1alpha1/clustersecrets_types.go b/api/v1alpha1/clustersecrets_types.go similarity index 68% rename from pkg/apis/picchu/v1alpha1/clustersecrets_types.go rename to api/v1alpha1/clustersecrets_types.go index 9423420f..f5dc8403 100644 --- a/pkg/apis/picchu/v1alpha1/clustersecrets_types.go +++ b/api/v1alpha1/clustersecrets_types.go @@ -1,15 +1,38 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + // ClusterSecretsSpec defines the desired state of ClusterSecrets // +k8s:openapi-gen=true // +kubebuilder:subresource:status // +kubebuilder:resource:scope=Namespaced // +kubebuilder:resource:categories=picchu type ClusterSecretsSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of ClusterSecrets. Edit ClusterSecrets_types.go to remove/update Source ClusterSecretSource `json:"source"` Target ClusterSecretTarget `json:"target"` } @@ -38,18 +61,16 @@ type ClusterSecretTarget struct { } // ClusterSecretsStatus defines the observed state of ClusterSecrets -// +k8s:openapi-gen=true type ClusterSecretsStatus struct { - // Names of secrets copied to targets - // +listType=set + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file Secrets []string `json:"secrets,omitempty"` } -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status // ClusterSecrets is the Schema for the clustersecrets API -// +k8s:openapi-gen=true type ClusterSecrets struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -58,7 +79,7 @@ type ClusterSecrets struct { Status ClusterSecretsStatus `json:"status,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true // ClusterSecretsList contains a list of ClusterSecrets type ClusterSecretsList struct { diff --git a/pkg/apis/picchu/v1alpha1/common.go b/api/v1alpha1/common.go similarity index 100% rename from pkg/apis/picchu/v1alpha1/common.go rename to api/v1alpha1/common.go diff --git a/pkg/apis/picchu/v1alpha1/faultinjector_types.go b/api/v1alpha1/faultinjector_types.go similarity index 53% rename from pkg/apis/picchu/v1alpha1/faultinjector_types.go rename to api/v1alpha1/faultinjector_types.go index d49d81b2..855aba6a 100644 --- a/pkg/apis/picchu/v1alpha1/faultinjector_types.go +++ b/api/v1alpha1/faultinjector_types.go @@ -1,12 +1,32 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( istio "istio.io/api/networking/v1alpha3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + // HTTPPortFault allows injecting faults into apps by port number -// +k8s:deepcopy-gen=false +// +k8s:deepcopy-gen=true type HTTPPortFault struct { PortSelector *istio.PortSelector `json:"portSelector,omitempty"` HTTPFault *istio.HTTPFaultInjection `json:"fault,omitempty"` @@ -14,19 +34,21 @@ type HTTPPortFault struct { // FaultInjectorSpec defines the desired state of FaultInjector type FaultInjectorSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file HTTPPortFaults []HTTPPortFault `json:"httpPortFaults"` } // FaultInjectorStatus defines the observed state of FaultInjector type FaultInjectorStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file } -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status // FaultInjector is the Schema for the faultinjectors API -// +kubebuilder:subresource:status -// +kubebuilder:resource:path=faultinjectors,scope=Namespaced type FaultInjector struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -35,7 +57,7 @@ type FaultInjector struct { Status FaultInjectorStatus `json:"status,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true // FaultInjectorList contains a list of FaultInjector type FaultInjectorList struct { diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..9d3c8011 --- /dev/null +++ b/api/v1alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the picchu.medium.engineering v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=picchu.medium.engineering +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "picchu.medium.engineering", Version: "v1alpha1"} + SchemeGroupVersion = schema.GroupVersion{Group: "picchu.medium.engineering", Version: "v1alpha1"} + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/pkg/apis/picchu/v1alpha1/mirror_types.go b/api/v1alpha1/mirror_types.go similarity index 53% rename from pkg/apis/picchu/v1alpha1/mirror_types.go rename to api/v1alpha1/mirror_types.go index 7c7b8c83..991bedf2 100644 --- a/pkg/apis/picchu/v1alpha1/mirror_types.go +++ b/api/v1alpha1/mirror_types.go @@ -1,16 +1,55 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. -// Mirror is the Schema for the mirrors API -// +k8s:openapi-gen=true +// MirrorSpec defines the desired state of Mirror +type MirrorSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + ClusterName string `json:"clusterName"` + AdditionalConfigSelectors []ConfigSelector `json:"additionalConfigSelectors,omitempty"` +} + +type ConfigSelector struct { + Namespace string `json:"namespace,omitempty"` + LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` + AppLabelName string `json:"appLabelName"` + TagLabelName string `json:"tagLabelName"` +} + +// MirrorStatus defines the observed state of Mirror +type MirrorStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Namespaced +// +k8s:openapi-gen=true + +// Mirror is the Schema for the mirrors API type Mirror struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -19,7 +58,8 @@ type Mirror struct { Status MirrorStatus `json:"status,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true + // MirrorList contains a list of Mirror type MirrorList struct { metav1.TypeMeta `json:",inline"` @@ -27,22 +67,6 @@ type MirrorList struct { Items []Mirror `json:"items"` } -// MirrorSpec defines the desired state of Mirror -type MirrorSpec struct { - ClusterName string `json:"clusterName"` - AdditionalConfigSelectors []ConfigSelector `json:"additionalConfigSelectors,omitempty"` -} - -type ConfigSelector struct { - Namespace string `json:"namespace,omitempty"` - LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` - AppLabelName string `json:"appLabelName"` - TagLabelName string `json:"tagLabelName"` -} - -// MirrorStatus defines the observed state of Mirror -type MirrorStatus struct{} - func init() { SchemeBuilder.Register(&Mirror{}, &MirrorList{}) } diff --git a/pkg/apis/picchu/v1alpha1/releasemanager_types.go b/api/v1alpha1/releasemanager_types.go similarity index 87% rename from pkg/apis/picchu/v1alpha1/releasemanager_types.go rename to api/v1alpha1/releasemanager_types.go index 42015218..ae1b55cc 100644 --- a/pkg/apis/picchu/v1alpha1/releasemanager_types.go +++ b/api/v1alpha1/releasemanager_types.go @@ -1,3 +1,19 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( @@ -6,14 +22,32 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. -// ReleaseManager is the Schema for the releasemanagers API -// +k8s:openapi-gen=true +// ReleaseManagerSpec defines the desired state of ReleaseManager +type ReleaseManagerSpec struct { + Fleet string `json:"fleet"` + App string `json:"app"` + Target string `json:"target"` + Variants []Variant `json:"variants,omitempty"` +} + +type Variant struct { + Name string `json:"name"` + Enabled bool `json:"enabled"` +} + +// ReleaseManagerStatus defines the observed state of ReleaseManager +type ReleaseManagerStatus struct { + Revisions []ReleaseManagerRevisionStatus `json:"revisions,omitempty"` + LastUpdated *metav1.Time `json:"lastUpdated"` +} + +// +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Namespaced -// +kubebuilder:resource:categories=all;picchu +// +k8s:openapi-gen=true +// ReleaseManager is the Schema for the releasemanagers API type ReleaseManager struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -22,7 +56,7 @@ type ReleaseManager struct { Status ReleaseManagerStatus `json:"status,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true // ReleaseManagerList contains a list of ReleaseManager type ReleaseManagerList struct { @@ -31,29 +65,6 @@ type ReleaseManagerList struct { Items []ReleaseManager `json:"items"` } -// ReleaseManagerSpec defines the desired state of ReleaseManager -// +k8s:openapi-gen=true -type ReleaseManagerSpec struct { - Fleet string `json:"fleet"` - App string `json:"app"` - Target string `json:"target"` - // +listType=atomic - Variants []Variant `json:"variants,omitempty"` -} - -type Variant struct { - Name string `json:"name"` - Enabled bool `json:"enabled"` -} - -// ReleaseManagerStatus defines the observed state of ReleaseManager -// +k8s:openapi-gen=true -type ReleaseManagerStatus struct { - // +listType=atomic - Revisions []ReleaseManagerRevisionStatus `json:"revisions,omitempty"` - LastUpdated *metav1.Time `json:"lastUpdated"` -} - type ReleaseManagerRevisionStatus struct { Tag string `json:"tag"` State ReleaseManagerRevisionStateStatus `json:"state,omitempty"` diff --git a/pkg/apis/picchu/v1alpha1/revision_test.go b/api/v1alpha1/revision_test.go similarity index 98% rename from pkg/apis/picchu/v1alpha1/revision_test.go rename to api/v1alpha1/revision_test.go index 62969322..00b3ccf1 100644 --- a/pkg/apis/picchu/v1alpha1/revision_test.go +++ b/api/v1alpha1/revision_test.go @@ -58,7 +58,7 @@ func TestCanaryTestPending(t *testing.T) { now := metav1.Now() assert.True(t, target.IsCanaryPending(&now)) - lastSecond := metav1.Time{time.Now().Add(-time.Second)} + lastSecond := metav1.Time{Time: time.Now().Add(-time.Second)} assert.False(t, target.IsCanaryPending(&lastSecond)) } diff --git a/pkg/apis/picchu/v1alpha1/revision_types.go b/api/v1alpha1/revision_types.go similarity index 77% rename from pkg/apis/picchu/v1alpha1/revision_types.go rename to api/v1alpha1/revision_types.go index 7e806344..7f4b4510 100644 --- a/pkg/apis/picchu/v1alpha1/revision_types.go +++ b/api/v1alpha1/revision_types.go @@ -1,3 +1,19 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package v1alpha1 import ( @@ -5,13 +21,12 @@ import ( istio "istio.io/api/networking/v1alpha3" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// see custom_deepcopy.go -// +k8s:deepcopy-gen=false +// +kubebuilder:pruning:PreserveUnknownFields type Istio struct { TrafficPolicy *istio.TrafficPolicy `json:"trafficPolicy,omitempty"` Sidecar *IstioSidecar `json:"sidecar,omitempty"` @@ -21,60 +36,8 @@ type IstioSidecar struct { EgressHosts []string `json:"egressHosts,omitempty"` } -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Revision is the Schema for the revisions API -// +k8s:openapi-gen=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Namespaced -// +kubebuilder:resource:categories=all;picchu -type Revision struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec RevisionSpec `json:"spec,omitempty"` - Status RevisionStatus `json:"status,omitempty"` -} - -func (r *Revision) Fail() { - if !r.Spec.Failed { - r.Spec.Failed = true - t := time.Now() - if r.Annotations == nil { - r.Annotations = map[string]string{ - AnnotationFailedAt: t.Format(time.RFC3339), - } - } else { - r.Annotations[AnnotationFailedAt] = t.Format(time.RFC3339) - } - } -} - -func (r *Revision) SinceFailed() time.Duration { - ft, ok := r.Annotations[AnnotationFailedAt] - if !ok { - return time.Duration(0) - } - t, err := time.Parse(time.RFC3339, ft) - if err != nil { - return time.Duration(0) - } - return time.Since(t) -} - -func (r *Revision) Failed() bool { - return r.Annotations != nil && r.Annotations[AnnotationFailedAt] != "" -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// RevisionList contains a list of Revision -type RevisionList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Revision `json:"items"` -} +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // RevisionSpec defines the desired state of Revision type RevisionSpec struct { @@ -96,20 +59,20 @@ type RevisionApp struct { } type RevisionTarget struct { - Name string `json:"name"` - Fleet string `json:"fleet"` - Scale ScaleInfo `json:"scale"` - Release ReleaseInfo `json:"release,omitempty"` - ServiceMonitors []*ServiceMonitor `json:"serviceMonitors,omitempty"` - ServiceLevelObjectives []*ServiceLevelObjective `json:"serviceLevelObjectives,omitempty"` - ServiceLevelObjectiveLabels ServiceLevelObjectiveLabels `json:"serviceLevelObjectiveLabels,omitempty"` - AcceptanceTarget bool `json:"acceptanceTarget,omitempty"` - ConfigSelector *metav1.LabelSelector `json:"configSelector,omitempty"` - AWS AWSInfo `json:"aws,omitempty"` - AlertRules []monitoringv1.Rule `json:"alertRules,omitempty"` - Sidecars []corev1.Container `json:"sidecars,omitempty"` - VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` - Volumes []corev1.Volume `json:"volumes,omitempty"` + Name string `json:"name"` + Fleet string `json:"fleet"` + Scale ScaleInfo `json:"scale"` + Release ReleaseInfo `json:"release,omitempty"` + ServiceMonitors []*ServiceMonitor `json:"serviceMonitors,omitempty"` + SlothServiceLevelObjectives []*SlothServiceLevelObjective `json:"serviceLevelObjectives,omitempty"` + ServiceLevelObjectiveLabels ServiceLevelObjectiveLabels `json:"serviceLevelObjectiveLabels,omitempty"` + AcceptanceTarget bool `json:"acceptanceTarget,omitempty"` + ConfigSelector *metav1.LabelSelector `json:"configSelector,omitempty"` + AWS AWSInfo `json:"aws,omitempty"` + AlertRules []monitoringv1.Rule `json:"alertRules,omitempty"` + Sidecars []corev1.Container `json:"sidecars,omitempty"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` PodAnnotations map[string]string `json:"podAnnotations,omitempty"` ServiceAccountName string `json:"serviceAccountName,omitempty"` @@ -146,12 +109,11 @@ type Canary struct { TTL int64 `json:"ttl"` } -type ServiceLevelObjective struct { +type SlothServiceLevelObjective struct { Name string `json:"name,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` Description string `json:"description,omitempty"` Enabled bool `json:"enabled"` - ObjectivePercentString string `json:"objectivePercentString,omitempty"` + Objective string `json:"objectivePercentString,omitempty"` ServiceLevelIndicator ServiceLevelIndicator `json:"serviceLevelIndicator,omitempty"` ServiceLevelObjectiveLabels ServiceLevelObjectiveLabels `json:"serviceLevelObjectiveLabels,omitempty"` } @@ -186,6 +148,7 @@ type ServiceMonitor struct { Spec monitoringv1.ServiceMonitorSpec `json:"spec,omitempty"` } +// RevisionStatus defines the observed state of Revision type RevisionStatus struct { Sentry SentryInfo `json:"sentry"` Targets []RevisionTargetStatus `json:"targets"` @@ -223,6 +186,56 @@ type RevisionReleaseStatus struct { PeakPercent uint32 `json:"peakPercent"` } +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// Revision is the Schema for the revisions API +type Revision struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RevisionSpec `json:"spec,omitempty"` + Status RevisionStatus `json:"status,omitempty"` +} + +func (r *Revision) Fail() { + if !r.Spec.Failed { + r.Spec.Failed = true + t := time.Now() + if r.Annotations == nil { + r.Annotations = map[string]string{ + AnnotationFailedAt: t.Format(time.RFC3339), + } + } else { + r.Annotations[AnnotationFailedAt] = t.Format(time.RFC3339) + } + } +} + +func (r *Revision) SinceFailed() time.Duration { + ft, ok := r.Annotations[AnnotationFailedAt] + if !ok { + return time.Duration(0) + } + t, err := time.Parse(time.RFC3339, ft) + if err != nil { + return time.Duration(0) + } + return time.Since(t) +} + +func (r *Revision) Failed() bool { + return r.Annotations != nil && r.Annotations[AnnotationFailedAt] != "" +} + +// +kubebuilder:object:root=true + +// RevisionList contains a list of Revision +type RevisionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Revision `json:"items"` +} + func (r *RevisionTargetStatus) AddReleaseManagerStatus(status ReleaseManagerRevisionStatus) { r.Release.CurrentPercent = status.CurrentPercent r.Release.PeakPercent = status.PeakPercent diff --git a/api/v1alpha1/revision_webhook.go b/api/v1alpha1/revision_webhook.go new file mode 100644 index 00000000..5ae222d0 --- /dev/null +++ b/api/v1alpha1/revision_webhook.go @@ -0,0 +1,230 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// log is for logging in this package. +var revisionlog = logf.Log.WithName("revision-resource") + +func (r *Revision) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-picchu-medium-engineering-v1alpha1-revision,mutating=true,failurePolicy=fail,groups=picchu.medium.engineering,resources=revisions,verbs=create;update,versions=v1alpha1,name=mrevision.kb.io,admissionReviewVersions=v1,sideEffects=None + +var _ webhook.Defaulter = &Revision{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Revision) Default() { + revisionlog.Info("default", "name", r.Name) + r.getPatches() + // TODO(user): fill in your defaulting logic. +} + +func (r *Revision) getPatches() error { + if err := r.getIngressesPatches(); err != nil { + return err + } + if err := r.getIngressDefaultPortPatches(); err != nil { + return err + } + return nil +} + +func (r *Revision) getIngressesPatches() error { + + for i := range r.Spec.Targets { + for j := range r.Spec.Targets[i].Ports { + port := r.Spec.Targets[i].Ports[j] + if len(port.Ingresses) > 0 { + continue + } + if port.Mode == PortPrivate || port.Mode == PortPublic { + r.Spec.Targets[i].Ports[j].Ingresses = append(r.Spec.Targets[i].Ports[j].Ingresses, "private") + + } + if port.Mode == PortPublic { + r.Spec.Targets[i].Ports[j].Ingresses = append(r.Spec.Targets[i].Ports[j].Ingresses, "public") + + } + + } + + } + return nil + +} + +func (r *Revision) getIngressDefaultPortPatches() error { + // if a single public or private ingress port is defined in a target and it's not set to default, it will be set as + // the default. + // if multiple ingress ports are defined and none are set to default and there is a port called 'http', it will be + // set to default + // internal ports will never be set as default + for i := range r.Spec.Targets { + ingressDefaultPorts := map[string]string{} + for ingress, ports := range bucketIngressPorts(r.Spec.Targets[i]) { + if len(ports) == 1 { + ingressDefaultPorts[ingress] = ports[0].Name + } + + var httpFound bool + var defaultFound bool + for j := range ports { + port := ports[j] + defaultFound = defaultFound || port.Default + if port.Name == "http" { + httpFound = true + } + } + if !defaultFound && httpFound { + ingressDefaultPorts[ingress] = "http" + } + } + existing := r.Spec.Targets[i].DefaultIngressPorts + if (existing == nil || len(existing) <= 0) && len(ingressDefaultPorts) > 0 { + r.Spec.Targets[i].DefaultIngressPorts = ingressDefaultPorts + continue + } + for ingress, def := range ingressDefaultPorts { + if _, ok := existing[ingress]; !ok { + r.Spec.Targets[i].DefaultIngressPorts[ingress] = def + } + } + } + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// +kubebuilder:webhook:verbs=create;update,path=/validate-picchu-medium-engineering-v1alpha1-revision,mutating=false,failurePolicy=fail,groups=picchu.medium.engineering,resources=revisions,versions=v1alpha1,name=vrevision.kb.io,admissionReviewVersions=v1,sideEffects=None + +var _ webhook.Validator = &Revision{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Revision) ValidateCreate() error { + revisionlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return r.validate() +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Revision) ValidateUpdate(old runtime.Object) error { + revisionlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return r.validate() +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Revision) ValidateDelete() error { + revisionlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} + +func (r *Revision) validate() error { + var allErrors field.ErrorList + for _, target := range r.Spec.Targets { + found := target.Release.ScalingStrategy == "" + for _, s := range ScalingStrategies { + if target.Release.ScalingStrategy == s { + found = true + } + } + if !found { + err := field.Invalid(field.NewPath("spec"), target.Release.ScalingStrategy, "Invalid scaling strategy") + allErrors = append(allErrors, err) + } + buckets := bucketIngressPorts(target) + for ingress, ports := range buckets { + if target.DefaultIngressPorts == nil { + err := field.Required(field.NewPath("spec"), fmt.Sprintf("Default ingress ports not specified for %s", ingress)) + allErrors = append(allErrors, err) + } + found := false + for _, port := range ports { + if target.DefaultIngressPorts[ingress] == port.Name { + found = true + break + } + } + if !found { + err := field.NotFound(field.NewPath("spec"), fmt.Sprintf("Specified default for ingress %s that doesn't exist", ingress)) + allErrors = append(allErrors, err) + } + } + for ingress := range target.DefaultIngressPorts { + if _, ok := buckets[ingress]; !ok { + err := field.NotFound(field.NewPath("spec"), fmt.Sprintf("Specified default for ingress %s that doesn't exist", ingress)) + allErrors = append(allErrors, err) + } + } + } + if len(allErrors) == 0 { + return nil + } + return apierrors.NewInvalid(schema.GroupKind{Group: GroupVersion.Group, Kind: "revision"}, r.GetName(), allErrors) +} + +type portInfo struct { + PortInfo + index int +} + +// returns a map of ingresses and ports mapped to ingresses +func bucketIngressPorts(target RevisionTarget) map[string][]portInfo { + // bucket ports by mode + track := map[string][]portInfo{} + for i := range target.Ports { + pi := portInfo{ + PortInfo: target.Ports[i], + index: i, + } + if pi.Ingresses != nil { + for _, ingress := range pi.Ingresses { + track[ingress] = append(track[ingress], pi) + } + continue + } + + switch pi.Mode { + case PortPublic: + track["public"] = append(track["public"], pi) + track["private"] = append(track["private"], pi) + case PortPrivate: + track["private"] = append(track["private"], pi) + } + } + return track +} diff --git a/pkg/webhook/revision/revision_test.go b/api/v1alpha1/revision_webhook_test.go similarity index 67% rename from pkg/webhook/revision/revision_test.go rename to api/v1alpha1/revision_webhook_test.go index 11ab31ca..4b427aba 100644 --- a/pkg/webhook/revision/revision_test.go +++ b/api/v1alpha1/revision_webhook_test.go @@ -1,25 +1,27 @@ -package revision +package v1alpha1 import ( - testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "gomodules.xyz/jsonpatch/v2" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" "time" + + testify "github.com/stretchr/testify/assert" + apierrors "k8s.io/apimachinery/pkg/api/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" ) type revisionBuilder struct { - *picchu.Revision + *Revision portCounter int32 } -func (r *revisionBuilder) internalAddPort(target string, name string, mode picchu.PortMode, ingresses ...string) *revisionBuilder { +func (r *revisionBuilder) internalAddPort(target string, name string, mode PortMode, ingresses ...string) *revisionBuilder { r.portCounter += 1 r.ensureTarget(target) for i := range r.Spec.Targets { if r.Spec.Targets[i].Name == target { - r.Spec.Targets[i].Ports = append(r.Spec.Targets[i].Ports, picchu.PortInfo{ + r.Spec.Targets[i].Ports = append(r.Spec.Targets[i].Ports, PortInfo{ Name: name, IngressPort: r.portCounter, Port: r.portCounter, @@ -34,7 +36,7 @@ func (r *revisionBuilder) internalAddPort(target string, name string, mode picch panic("Bug") } -func (r *revisionBuilder) addPortWithMode(target, name string, mode picchu.PortMode) *revisionBuilder { +func (r *revisionBuilder) addPortWithMode(target, name string, mode PortMode) *revisionBuilder { r.ensureTarget(target) return r.internalAddPort(target, name, mode) } @@ -58,11 +60,11 @@ func (r *revisionBuilder) addIngressDefaultPort(target, ingress, port string) *r return r } -func (r *revisionBuilder) setRate(target string, scaling picchu.LinearScaling) *revisionBuilder { +func (r *revisionBuilder) setRate(target string, scaling LinearScaling) *revisionBuilder { r.ensureTarget(target) for i := range r.Spec.Targets { if r.Spec.Targets[i].Name == target { - r.Spec.Targets[i].Release.ScalingStrategy = picchu.ScalingStrategyLinear + r.Spec.Targets[i].Release.ScalingStrategy = ScalingStrategyLinear r.Spec.Targets[i].Release.LinearScaling = scaling break } @@ -76,14 +78,14 @@ func (r *revisionBuilder) ensureTarget(name string) *revisionBuilder { return r } } - r.Spec.Targets = append(r.Spec.Targets, picchu.RevisionTarget{ + r.Spec.Targets = append(r.Spec.Targets, RevisionTarget{ Name: name, - Release: picchu.ReleaseInfo{ + Release: ReleaseInfo{ Eligible: false, Max: 0, - ScalingStrategy: picchu.ScalingStrategyLinear, - GeometricScaling: picchu.GeometricScaling{}, - LinearScaling: picchu.LinearScaling{}, + ScalingStrategy: ScalingStrategyLinear, + GeometricScaling: GeometricScaling{}, + LinearScaling: LinearScaling{}, Schedule: "", TTL: 0, }, @@ -91,19 +93,19 @@ func (r *revisionBuilder) ensureTarget(name string) *revisionBuilder { return r } -func (r *revisionBuilder) build() *picchu.Revision { +func (r *revisionBuilder) build() *Revision { return r.Revision } func newRevisionBuilder() *revisionBuilder { return &revisionBuilder{ - Revision: &picchu.Revision{ + Revision: &Revision{ ObjectMeta: meta.ObjectMeta{ Name: "name", Namespace: "namespace", }, - Spec: picchu.RevisionSpec{ - App: picchu.RevisionApp{ + Spec: RevisionSpec{ + App: RevisionApp{ Name: "name", Ref: "ref", Tag: "tag", @@ -116,37 +118,21 @@ func newRevisionBuilder() *revisionBuilder { func TestMutate(t *testing.T) { assert := testify.New(t) - mutator := revisionMutator{} + //mutator := Revision{} ts := []struct { name string - rev *picchu.Revision - expected []jsonpatch.JsonPatchOperation + rev *Revision + expected []error }{ { name: "SetHTTPAsDefaultPort", rev: newRevisionBuilder(). - addPortWithMode("production", "http", picchu.PortPrivate). - addPortWithMode("production", "grpc", picchu.PortPublic). - addPortWithMode("production", "status", picchu.PortLocal). + addPortWithMode("production", "http", PortPrivate). + addPortWithMode("production", "grpc", PortPublic). + addPortWithMode("production", "status", PortLocal). build(), - expected: []jsonpatch.JsonPatchOperation{ - { - Operation: "add", - Path: "/spec/targets/0/ports/0/ingresses", - Value: []string{"private"}, - }, - { - Operation: "add", - Path: "/spec/targets/0/ports/1/ingresses", - Value: []string{"private", "public"}, - }, - { - Operation: "add", - Path: "/spec/targets/0/defaultIngressPorts", - Value: map[string]string{"private": "http", "public": "grpc"}, - }, - }, + expected: nil, }, { name: "DontSetHTTPAsDefaultPort", @@ -161,12 +147,12 @@ func TestMutate(t *testing.T) { { name: "DontSetLinearScalingProperties", rev: newRevisionBuilder(). - setRate("production", picchu.LinearScaling{ + setRate("production", LinearScaling{ Increment: 10, Delay: &meta.Duration{Duration: time.Duration(20) * time.Second}, }). build(), - expected: []jsonpatch.JsonPatchOperation{}, + expected: nil, }, { name: "DontSetHTTPAsDefaultPort", @@ -186,11 +172,7 @@ func TestMutate(t *testing.T) { addPort("production", "status"). addIngressDefaultPort("production", "private", "grpc"). build(), - expected: []jsonpatch.JsonPatchOperation{{ - Operation: "add", - Path: "/spec/targets/0/defaultIngressPorts[public]", - Value: "http", - }}, + expected: nil, }, { name: "NoHTTP", @@ -207,13 +189,7 @@ func TestMutate(t *testing.T) { addPort("production", "grpc", "public", "private"). addPort("production", "status"). build(), - expected: []jsonpatch.JsonPatchOperation{ - { - Operation: "add", - Path: "/spec/targets/0/defaultIngressPorts", - Value: map[string]string{"public": "grpc", "private": "grpc"}, - }, - }, + expected: nil, }, { name: "SingleAndHTTP", @@ -222,13 +198,7 @@ func TestMutate(t *testing.T) { addPort("production", "http", "private"). addPort("production", "status"). build(), - expected: []jsonpatch.JsonPatchOperation{ - { - Operation: "add", - Path: "/spec/targets/0/defaultIngressPorts", - Value: map[string]string{"public": "grpc", "private": "http"}, - }, - }, + expected: nil, }, { name: "NoDefaultOnLocal", @@ -243,19 +213,19 @@ func TestMutate(t *testing.T) { for _, tc := range ts { t.Run(tc.name, func(t *testing.T) { - assert.ElementsMatch(tc.expected, mutator.getPatches(tc.rev)) + assert.ElementsMatch(tc.expected, tc.rev.getPatches()) }) } } func TestValidate(t *testing.T) { assert := testify.New(t) - validator := revisionValidator{} + //validator := Revision{} ts := []struct { name string - rev *picchu.Revision - expected []string + rev *Revision + expected error }{ { name: "DefaultsSet", @@ -275,7 +245,9 @@ func TestValidate(t *testing.T) { addPort("production", "grpc", "private"). addPort("production", "status"). build(), - expected: []string{"production"}, + expected: apierrors.NewInvalid(schema.GroupKind{Group: GroupVersion.Group, Kind: "revision"}, "name", field.ErrorList{ + field.Required(field.NewPath("spec"), "Default ingress ports not specified for private"), + field.NotFound(field.NewPath("spec"), "Specified default for ingress private that doesn't exist")}), }, { name: "DefaultLocal", @@ -283,7 +255,7 @@ func TestValidate(t *testing.T) { addPort("production", "status"). addIngressDefaultPort("production", "local", "status"). build(), - expected: []string{"production"}, + expected: &apierrors.StatusError{}, }, { name: "NoPorts", @@ -304,7 +276,7 @@ func TestValidate(t *testing.T) { addPort("production", "status"). addIngressDefaultPort("production", "private", "httpz"). build(), - expected: []string{"production"}, + expected: &apierrors.StatusError{}, }, { name: "MultiTargetFailures", @@ -316,23 +288,20 @@ func TestValidate(t *testing.T) { addPort("production", "grpc", "private"). addPort("production", "status"). build(), - expected: []string{"production", "staging"}, + expected: &apierrors.StatusError{}, }, } for _, tc := range ts { t.Run(tc.name, func(t *testing.T) { - failures := validator.failures(tc.rev) - failedTargetsMap := map[string]bool{} - for _, failure := range failures { - failedTargetsMap[failure.target] = true - } - var failedTargets []string - for target := range failedTargetsMap { - failedTargets = append(failedTargets, target) - } - - assert.ElementsMatch(tc.expected, failedTargets, failures) + failures := tc.rev.validate() + //t.Log(assert.ElementsMatch(failures, tc.expected)) + //t.Log(failures) + //t.Log(tc.expected) + //t.Log(tc.rev) + t.Log(assert.IsType(failures, tc.expected)) + assert.IsType(failures, tc.expected) + //assert.ElementsMatch(failures, tc.expected) }) } } diff --git a/pkg/apis/picchu/v1alpha1/source_defaults.go b/api/v1alpha1/source_defaults.go similarity index 100% rename from pkg/apis/picchu/v1alpha1/source_defaults.go rename to api/v1alpha1/source_defaults.go diff --git a/pkg/apis/picchu/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go similarity index 94% rename from pkg/apis/picchu/v1alpha1/zz_generated.deepcopy.go rename to api/v1alpha1/zz_generated.deepcopy.go index 7c8559dc..0832570b 100644 --- a/pkg/apis/picchu/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,21 +1,37 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated -// Code generated by operator-sdk. DO NOT EDIT. +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. package v1alpha1 import ( - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AWSInfo) DeepCopyInto(out *AWSInfo) { *out = *in out.IAM = in.IAM - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSInfo. @@ -31,7 +47,6 @@ func (in *AWSInfo) DeepCopy() *AWSInfo { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Canary) DeepCopyInto(out *Canary) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Canary. @@ -51,7 +66,6 @@ func (in *Cluster) DeepCopyInto(out *Cluster) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. @@ -80,7 +94,6 @@ func (in *ClusterConfig) DeepCopyInto(out *ClusterConfig) { *out = make([]byte, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfig. @@ -98,7 +111,6 @@ func (in *ClusterIngresses) DeepCopyInto(out *ClusterIngresses) { *out = *in in.Public.DeepCopyInto(&out.Public) in.Private.DeepCopyInto(&out.Private) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterIngresses. @@ -114,7 +126,6 @@ func (in *ClusterIngresses) DeepCopy() *ClusterIngresses { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterKubernetesStatus) DeepCopyInto(out *ClusterKubernetesStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterKubernetesStatus. @@ -139,7 +150,6 @@ func (in *ClusterList) DeepCopyInto(out *ClusterList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. @@ -163,7 +173,6 @@ func (in *ClusterList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterSecretSource) DeepCopyInto(out *ClusterSecretSource) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecretSource. @@ -193,7 +202,6 @@ func (in *ClusterSecretTarget) DeepCopyInto(out *ClusterSecretTarget) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecretTarget. @@ -213,7 +221,6 @@ func (in *ClusterSecrets) DeepCopyInto(out *ClusterSecrets) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecrets. @@ -246,7 +253,6 @@ func (in *ClusterSecretsList) DeepCopyInto(out *ClusterSecretsList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecretsList. @@ -272,7 +278,6 @@ func (in *ClusterSecretsSpec) DeepCopyInto(out *ClusterSecretsSpec) { *out = *in out.Source = in.Source in.Target.DeepCopyInto(&out.Target) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecretsSpec. @@ -293,7 +298,6 @@ func (in *ClusterSecretsStatus) DeepCopyInto(out *ClusterSecretsStatus) { *out = make([]string, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecretsStatus. @@ -320,7 +324,6 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { **out = **in } in.Ingresses.DeepCopyInto(&out.Ingresses) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. @@ -337,7 +340,6 @@ func (in *ClusterSpec) DeepCopy() *ClusterSpec { func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { *out = *in out.Kubernetes = in.Kubernetes - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. @@ -358,7 +360,6 @@ func (in *ConfigSelector) DeepCopyInto(out *ConfigSelector) { *out = new(v1.LabelSelector) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigSelector. @@ -383,7 +384,6 @@ func (in *ExternalTest) DeepCopyInto(out *ExternalTest) { in, out := &in.LastUpdated, &out.LastUpdated *out = (*in).DeepCopy() } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalTest. @@ -403,7 +403,6 @@ func (in *FaultInjector) DeepCopyInto(out *FaultInjector) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FaultInjector. @@ -436,7 +435,6 @@ func (in *FaultInjectorList) DeepCopyInto(out *FaultInjectorList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FaultInjectorList. @@ -467,7 +465,6 @@ func (in *FaultInjectorSpec) DeepCopyInto(out *FaultInjectorSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FaultInjectorSpec. @@ -483,7 +480,6 @@ func (in *FaultInjectorSpec) DeepCopy() *FaultInjectorSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FaultInjectorStatus) DeepCopyInto(out *FaultInjectorStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FaultInjectorStatus. @@ -504,7 +500,6 @@ func (in *GeometricScaling) DeepCopyInto(out *GeometricScaling) { *out = new(v1.Duration) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeometricScaling. @@ -517,10 +512,32 @@ func (in *GeometricScaling) DeepCopy() *GeometricScaling { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPPortFault) DeepCopyInto(out *HTTPPortFault) { + *out = *in + if in.PortSelector != nil { + in, out := &in.PortSelector, &out.PortSelector + *out = (*in).DeepCopy() + } + if in.HTTPFault != nil { + in, out := &in.HTTPFault, &out.HTTPFault + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPortFault. +func (in *HTTPPortFault) DeepCopy() *HTTPPortFault { + if in == nil { + return nil + } + out := new(HTTPPortFault) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IAMInfo) DeepCopyInto(out *IAMInfo) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAMInfo. @@ -541,7 +558,6 @@ func (in *IngressInfo) DeepCopyInto(out *IngressInfo) { *out = make([]string, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressInfo. @@ -554,6 +570,30 @@ func (in *IngressInfo) DeepCopy() *IngressInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Istio) DeepCopyInto(out *Istio) { + *out = *in + if in.TrafficPolicy != nil { + in, out := &in.TrafficPolicy, &out.TrafficPolicy + *out = (*in).DeepCopy() + } + if in.Sidecar != nil { + in, out := &in.Sidecar, &out.Sidecar + *out = new(IstioSidecar) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Istio. +func (in *Istio) DeepCopy() *Istio { + if in == nil { + return nil + } + out := new(Istio) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IstioHTTPPortConfig) DeepCopyInto(out *IstioHTTPPortConfig) { *out = *in @@ -567,7 +607,6 @@ func (in *IstioHTTPPortConfig) DeepCopyInto(out *IstioHTTPPortConfig) { *out = new(v1.Duration) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstioHTTPPortConfig. @@ -584,7 +623,6 @@ func (in *IstioHTTPPortConfig) DeepCopy() *IstioHTTPPortConfig { func (in *IstioPortConfig) DeepCopyInto(out *IstioPortConfig) { *out = *in in.HTTP.DeepCopyInto(&out.HTTP) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstioPortConfig. @@ -605,7 +643,6 @@ func (in *IstioSidecar) DeepCopyInto(out *IstioSidecar) { *out = make([]string, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstioSidecar. @@ -626,7 +663,6 @@ func (in *LinearScaling) DeepCopyInto(out *LinearScaling) { *out = new(v1.Duration) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinearScaling. @@ -646,7 +682,6 @@ func (in *Mirror) DeepCopyInto(out *Mirror) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mirror. @@ -679,7 +714,6 @@ func (in *MirrorList) DeepCopyInto(out *MirrorList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirrorList. @@ -710,7 +744,6 @@ func (in *MirrorSpec) DeepCopyInto(out *MirrorSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirrorSpec. @@ -726,7 +759,6 @@ func (in *MirrorSpec) DeepCopy() *MirrorSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MirrorStatus) DeepCopyInto(out *MirrorStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirrorStatus. @@ -753,7 +785,6 @@ func (in *PortInfo) DeepCopyInto(out *PortInfo) { copy(*out, *in) } in.Istio.DeepCopyInto(&out.Istio) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortInfo. @@ -771,7 +802,6 @@ func (in *ReleaseInfo) DeepCopyInto(out *ReleaseInfo) { *out = *in in.GeometricScaling.DeepCopyInto(&out.GeometricScaling) in.LinearScaling.DeepCopyInto(&out.LinearScaling) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseInfo. @@ -791,7 +821,6 @@ func (in *ReleaseManager) DeepCopyInto(out *ReleaseManager) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManager. @@ -824,7 +853,6 @@ func (in *ReleaseManagerList) DeepCopyInto(out *ReleaseManagerList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerList. @@ -913,7 +941,6 @@ func (in *ReleaseManagerRevisionMetricsStatus) DeepCopyInto(out *ReleaseManagerR *out = new(int) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerRevisionMetricsStatus. @@ -929,7 +956,6 @@ func (in *ReleaseManagerRevisionMetricsStatus) DeepCopy() *ReleaseManagerRevisio // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReleaseManagerRevisionScaleStatus) DeepCopyInto(out *ReleaseManagerRevisionScaleStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerRevisionScaleStatus. @@ -949,7 +975,6 @@ func (in *ReleaseManagerRevisionStateStatus) DeepCopyInto(out *ReleaseManagerRev in, out := &in.LastUpdated, &out.LastUpdated *out = (*in).DeepCopy() } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerRevisionStateStatus. @@ -1001,7 +1026,6 @@ func (in *ReleaseManagerRevisionStatus) DeepCopyInto(out *ReleaseManagerRevision } in.Metrics.DeepCopyInto(&out.Metrics) out.Scale = in.Scale - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerRevisionStatus. @@ -1022,7 +1046,6 @@ func (in *ReleaseManagerSpec) DeepCopyInto(out *ReleaseManagerSpec) { *out = make([]Variant, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerSpec. @@ -1049,7 +1072,6 @@ func (in *ReleaseManagerStatus) DeepCopyInto(out *ReleaseManagerStatus) { in, out := &in.LastUpdated, &out.LastUpdated *out = (*in).DeepCopy() } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseManagerStatus. @@ -1075,7 +1097,6 @@ func (in *Retries) DeepCopyInto(out *Retries) { *out = new(string) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Retries. @@ -1095,7 +1116,6 @@ func (in *Revision) DeepCopyInto(out *Revision) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Revision. @@ -1119,7 +1139,6 @@ func (in *Revision) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RevisionApp) DeepCopyInto(out *RevisionApp) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionApp. @@ -1144,7 +1163,6 @@ func (in *RevisionList) DeepCopyInto(out *RevisionList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionList. @@ -1168,7 +1186,6 @@ func (in *RevisionList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RevisionReleaseStatus) DeepCopyInto(out *RevisionReleaseStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionReleaseStatus. @@ -1184,7 +1201,6 @@ func (in *RevisionReleaseStatus) DeepCopy() *RevisionReleaseStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RevisionScaleStatus) DeepCopyInto(out *RevisionScaleStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionScaleStatus. @@ -1209,7 +1225,6 @@ func (in *RevisionSpec) DeepCopyInto(out *RevisionSpec) { } } out.Sentry = in.Sentry - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionSpec. @@ -1231,7 +1246,6 @@ func (in *RevisionStatus) DeepCopyInto(out *RevisionStatus) { *out = make([]RevisionTargetStatus, len(*in)) copy(*out, *in) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionStatus. @@ -1260,13 +1274,13 @@ func (in *RevisionTarget) DeepCopyInto(out *RevisionTarget) { } } } - if in.ServiceLevelObjectives != nil { - in, out := &in.ServiceLevelObjectives, &out.ServiceLevelObjectives - *out = make([]*ServiceLevelObjective, len(*in)) + if in.SlothServiceLevelObjectives != nil { + in, out := &in.SlothServiceLevelObjectives, &out.SlothServiceLevelObjectives + *out = make([]*SlothServiceLevelObjective, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(ServiceLevelObjective) + *out = new(SlothServiceLevelObjective) (*in).DeepCopyInto(*out) } } @@ -1366,9 +1380,9 @@ func (in *RevisionTarget) DeepCopyInto(out *RevisionTarget) { } if in.Istio != nil { in, out := &in.Istio, &out.Istio - *out = (*in).DeepCopy() + *out = new(Istio) + (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionTarget. @@ -1386,7 +1400,6 @@ func (in *RevisionTargetStatus) DeepCopyInto(out *RevisionTargetStatus) { *out = *in out.Scale = in.Scale out.Release = in.Release - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RevisionTargetStatus. @@ -1402,7 +1415,6 @@ func (in *RevisionTargetStatus) DeepCopy() *RevisionTargetStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SLICanaryConfig) DeepCopyInto(out *SLICanaryConfig) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SLICanaryConfig. @@ -1443,7 +1455,6 @@ func (in *ScaleInfo) DeepCopyInto(out *ScaleInfo) { *out = new(WorkerScaleInfo) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScaleInfo. @@ -1459,7 +1470,6 @@ func (in *ScaleInfo) DeepCopy() *ScaleInfo { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SentryInfo) DeepCopyInto(out *SentryInfo) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SentryInfo. @@ -1476,7 +1486,6 @@ func (in *SentryInfo) DeepCopy() *SentryInfo { func (in *ServiceLevelIndicator) DeepCopyInto(out *ServiceLevelIndicator) { *out = *in out.Canary = in.Canary - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLevelIndicator. @@ -1489,31 +1498,6 @@ func (in *ServiceLevelIndicator) DeepCopy() *ServiceLevelIndicator { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceLevelObjective) DeepCopyInto(out *ServiceLevelObjective) { - *out = *in - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - out.ServiceLevelIndicator = in.ServiceLevelIndicator - in.ServiceLevelObjectiveLabels.DeepCopyInto(&out.ServiceLevelObjectiveLabels) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLevelObjective. -func (in *ServiceLevelObjective) DeepCopy() *ServiceLevelObjective { - if in == nil { - return nil - } - out := new(ServiceLevelObjective) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceLevelObjectiveLabels) DeepCopyInto(out *ServiceLevelObjectiveLabels) { *out = *in @@ -1538,7 +1522,6 @@ func (in *ServiceLevelObjectiveLabels) DeepCopyInto(out *ServiceLevelObjectiveLa (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLevelObjectiveLabels. @@ -1569,7 +1552,6 @@ func (in *ServiceMonitor) DeepCopyInto(out *ServiceMonitor) { } } in.Spec.DeepCopyInto(&out.Spec) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMonitor. @@ -1582,10 +1564,26 @@ func (in *ServiceMonitor) DeepCopy() *ServiceMonitor { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SlothServiceLevelObjective) DeepCopyInto(out *SlothServiceLevelObjective) { + *out = *in + out.ServiceLevelIndicator = in.ServiceLevelIndicator + in.ServiceLevelObjectiveLabels.DeepCopyInto(&out.ServiceLevelObjectiveLabels) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SlothServiceLevelObjective. +func (in *SlothServiceLevelObjective) DeepCopy() *SlothServiceLevelObjective { + if in == nil { + return nil + } + out := new(SlothServiceLevelObjective) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Variant) DeepCopyInto(out *Variant) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Variant. @@ -1616,7 +1614,6 @@ func (in *WorkerScaleInfo) DeepCopyInto(out *WorkerScaleInfo) { *out = new(string) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkerScaleInfo. diff --git a/pkg/apis/picchu/v1alpha1/zz_generated.defaults.go b/api/v1alpha1/zz_generated.defaults.go similarity index 100% rename from pkg/apis/picchu/v1alpha1/zz_generated.defaults.go rename to api/v1alpha1/zz_generated.defaults.go diff --git a/build/Dockerfile b/build/Dockerfile deleted file mode 100644 index d74f9d3d..00000000 --- a/build/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM alpine:3.8 - -RUN apk add --no-cache tzdata - -ENV OPERATOR=/usr/local/bin/picchu \ - USER_UID=1001 \ - USER_NAME=picchu - -# install operator binary -COPY build/_output/bin/picchu ${OPERATOR} - -COPY build/bin /usr/local/bin -RUN apk add --no-cache ca-certificates && \ - /usr/local/bin/user_setup - -ENTRYPOINT ["/usr/local/bin/entrypoint"] - -USER ${USER_UID} diff --git a/build/bin/entrypoint b/build/bin/entrypoint deleted file mode 100755 index 15e9b15b..00000000 --- a/build/bin/entrypoint +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -e - -# This is documented here: -# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines - -if ! whoami &>/dev/null; then - if [ -w /etc/passwd ]; then - echo "${USER_NAME:-picchu}:x:$(id -u):$(id -g):${USER_NAME:-picchu} user:${HOME}:/sbin/nologin" >> /etc/passwd - fi -fi - -exec ${OPERATOR} $@ diff --git a/build/bin/user_setup b/build/bin/user_setup deleted file mode 100755 index 1e36064c..00000000 --- a/build/bin/user_setup +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -set -x - -# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be) -mkdir -p ${HOME} -chown ${USER_UID}:0 ${HOME} -chmod ug+rwx ${HOME} - -# runtime user will need to be able to self-insert in /etc/passwd -chmod g+rw /etc/passwd - -# no need for this script to remain in the image after running -rm $0 diff --git a/build/webhook.Dockerfile b/build/webhook.Dockerfile deleted file mode 100644 index 5d63ea1f..00000000 --- a/build/webhook.Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM golang:1.15 - -WORKDIR /go/src/go.medium.engineering/picchu - -COPY pkg ./pkg -COPY cmd ./cmd -COPY version ./version - -COPY go.mod go.sum ./ - -RUN ls - -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o webhook ./cmd/webhook - -FROM alpine:3.8 - -RUN apk add --no-cache tzdata - -ENV OPERATOR=/usr/local/bin/picchu-webhook \ - USER_UID=1001 \ - USER_NAME=picchu - -# install operator binary -COPY --from=0 /go/src/go.medium.engineering/picchu/webhook ${OPERATOR} - -COPY build/bin /usr/local/bin -RUN apk add --no-cache ca-certificates && \ - /usr/local/bin/user_setup - -ENTRYPOINT ["/usr/local/bin/entrypoint"] - -USER ${USER_UID} diff --git a/pkg/client/clientset.go b/client/clientset.go similarity index 96% rename from pkg/client/clientset.go rename to client/clientset.go index d54ec727..3c67f3f1 100644 --- a/pkg/client/clientset.go +++ b/client/clientset.go @@ -8,7 +8,7 @@ package client import ( "fmt" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/client/typed/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/client/typed/picchu/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" diff --git a/pkg/client/doc.go b/client/doc.go similarity index 100% rename from pkg/client/doc.go rename to client/doc.go diff --git a/pkg/client/fake/clientset_generated.go b/client/fake/clientset_generated.go similarity index 90% rename from pkg/client/fake/clientset_generated.go rename to client/fake/clientset_generated.go index e9415116..686ac601 100644 --- a/pkg/client/fake/clientset_generated.go +++ b/client/fake/clientset_generated.go @@ -6,9 +6,9 @@ package fake import ( - clientset "go.medium.engineering/picchu/pkg/client" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/client/typed/picchu/v1alpha1" - fakepicchuv1alpha1 "go.medium.engineering/picchu/pkg/client/typed/picchu/v1alpha1/fake" + clientset "go.medium.engineering/picchu/client" + picchuv1alpha1 "go.medium.engineering/picchu/client/typed/picchu/v1alpha1" + fakepicchuv1alpha1 "go.medium.engineering/picchu/client/typed/picchu/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" diff --git a/pkg/client/fake/doc.go b/client/fake/doc.go similarity index 100% rename from pkg/client/fake/doc.go rename to client/fake/doc.go diff --git a/pkg/client/fake/register.go b/client/fake/register.go similarity index 70% rename from pkg/client/fake/register.go rename to client/fake/register.go index 06b99682..b4c56ecc 100644 --- a/pkg/client/fake/register.go +++ b/client/fake/register.go @@ -6,7 +6,7 @@ package fake import ( - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,14 +24,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/pkg/client/scheme/doc.go b/client/scheme/doc.go similarity index 100% rename from pkg/client/scheme/doc.go rename to client/scheme/doc.go diff --git a/pkg/client/scheme/register.go b/client/scheme/register.go similarity index 71% rename from pkg/client/scheme/register.go rename to client/scheme/register.go index 70ec2715..b2fc0900 100644 --- a/pkg/client/scheme/register.go +++ b/client/scheme/register.go @@ -6,7 +6,7 @@ package scheme import ( - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -24,14 +24,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. @@ -40,4 +40,5 @@ var AddToScheme = localSchemeBuilder.AddToScheme func init() { v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) utilruntime.Must(AddToScheme(Scheme)) + } diff --git a/pkg/client/typed/picchu/v1alpha1/cluster.go b/client/typed/picchu/v1alpha1/cluster.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/cluster.go rename to client/typed/picchu/v1alpha1/cluster.go index ecd32b7b..cdaf4989 100644 --- a/pkg/client/typed/picchu/v1alpha1/cluster.go +++ b/client/typed/picchu/v1alpha1/cluster.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/client/typed/picchu/v1alpha1/clustersecrets.go b/client/typed/picchu/v1alpha1/clustersecrets.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/clustersecrets.go rename to client/typed/picchu/v1alpha1/clustersecrets.go index 816b6f97..ca7b2661 100644 --- a/pkg/client/typed/picchu/v1alpha1/clustersecrets.go +++ b/client/typed/picchu/v1alpha1/clustersecrets.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/client/typed/picchu/v1alpha1/doc.go b/client/typed/picchu/v1alpha1/doc.go similarity index 100% rename from pkg/client/typed/picchu/v1alpha1/doc.go rename to client/typed/picchu/v1alpha1/doc.go diff --git a/pkg/client/typed/picchu/v1alpha1/fake/doc.go b/client/typed/picchu/v1alpha1/fake/doc.go similarity index 100% rename from pkg/client/typed/picchu/v1alpha1/fake/doc.go rename to client/typed/picchu/v1alpha1/fake/doc.go diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_cluster.go b/client/typed/picchu/v1alpha1/fake/fake_cluster.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_cluster.go rename to client/typed/picchu/v1alpha1/fake/fake_cluster.go index 984d746d..66990ed6 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_cluster.go +++ b/client/typed/picchu/v1alpha1/fake/fake_cluster.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go b/client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go rename to client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go index 6cb6261d..c7fdf5cb 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go +++ b/client/typed/picchu/v1alpha1/fake/fake_clustersecrets.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_faultinjector.go b/client/typed/picchu/v1alpha1/fake/fake_faultinjector.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_faultinjector.go rename to client/typed/picchu/v1alpha1/fake/fake_faultinjector.go index 077f5493..04825e18 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_faultinjector.go +++ b/client/typed/picchu/v1alpha1/fake/fake_faultinjector.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_mirror.go b/client/typed/picchu/v1alpha1/fake/fake_mirror.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_mirror.go rename to client/typed/picchu/v1alpha1/fake/fake_mirror.go index 1c8182ac..ac224839 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_mirror.go +++ b/client/typed/picchu/v1alpha1/fake/fake_mirror.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_picchu_client.go b/client/typed/picchu/v1alpha1/fake/fake_picchu_client.go similarity index 94% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_picchu_client.go rename to client/typed/picchu/v1alpha1/fake/fake_picchu_client.go index a25b5290..a8b1b32c 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_picchu_client.go +++ b/client/typed/picchu/v1alpha1/fake/fake_picchu_client.go @@ -6,7 +6,7 @@ package fake import ( - v1alpha1 "go.medium.engineering/picchu/pkg/client/typed/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/client/typed/picchu/v1alpha1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_releasemanager.go b/client/typed/picchu/v1alpha1/fake/fake_releasemanager.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_releasemanager.go rename to client/typed/picchu/v1alpha1/fake/fake_releasemanager.go index de25c190..3ee52e48 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_releasemanager.go +++ b/client/typed/picchu/v1alpha1/fake/fake_releasemanager.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/fake/fake_revision.go b/client/typed/picchu/v1alpha1/fake/fake_revision.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/fake/fake_revision.go rename to client/typed/picchu/v1alpha1/fake/fake_revision.go index 2a7f9096..6fc337eb 100644 --- a/pkg/client/typed/picchu/v1alpha1/fake/fake_revision.go +++ b/client/typed/picchu/v1alpha1/fake/fake_revision.go @@ -8,7 +8,7 @@ package fake import ( "context" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/client/typed/picchu/v1alpha1/faultinjector.go b/client/typed/picchu/v1alpha1/faultinjector.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/faultinjector.go rename to client/typed/picchu/v1alpha1/faultinjector.go index 0fd33105..12a3b6c2 100644 --- a/pkg/client/typed/picchu/v1alpha1/faultinjector.go +++ b/client/typed/picchu/v1alpha1/faultinjector.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/client/typed/picchu/v1alpha1/generated_expansion.go b/client/typed/picchu/v1alpha1/generated_expansion.go similarity index 100% rename from pkg/client/typed/picchu/v1alpha1/generated_expansion.go rename to client/typed/picchu/v1alpha1/generated_expansion.go diff --git a/pkg/client/typed/picchu/v1alpha1/mirror.go b/client/typed/picchu/v1alpha1/mirror.go similarity index 97% rename from pkg/client/typed/picchu/v1alpha1/mirror.go rename to client/typed/picchu/v1alpha1/mirror.go index a8030c52..5ac632ec 100644 --- a/pkg/client/typed/picchu/v1alpha1/mirror.go +++ b/client/typed/picchu/v1alpha1/mirror.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/client/typed/picchu/v1alpha1/picchu_client.go b/client/typed/picchu/v1alpha1/picchu_client.go similarity index 95% rename from pkg/client/typed/picchu/v1alpha1/picchu_client.go rename to client/typed/picchu/v1alpha1/picchu_client.go index 21cd6851..74501688 100644 --- a/pkg/client/typed/picchu/v1alpha1/picchu_client.go +++ b/client/typed/picchu/v1alpha1/picchu_client.go @@ -6,8 +6,8 @@ package v1alpha1 import ( - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/client/scheme" rest "k8s.io/client-go/rest" ) diff --git a/pkg/client/typed/picchu/v1alpha1/releasemanager.go b/client/typed/picchu/v1alpha1/releasemanager.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/releasemanager.go rename to client/typed/picchu/v1alpha1/releasemanager.go index 0f39f4cc..d3af1ec1 100644 --- a/pkg/client/typed/picchu/v1alpha1/releasemanager.go +++ b/client/typed/picchu/v1alpha1/releasemanager.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/client/typed/picchu/v1alpha1/revision.go b/client/typed/picchu/v1alpha1/revision.go similarity index 98% rename from pkg/client/typed/picchu/v1alpha1/revision.go rename to client/typed/picchu/v1alpha1/revision.go index 23df744b..3ca2d724 100644 --- a/pkg/client/typed/picchu/v1alpha1/revision.go +++ b/client/typed/picchu/v1alpha1/revision.go @@ -9,8 +9,8 @@ import ( "context" "time" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - scheme "go.medium.engineering/picchu/pkg/client/scheme" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + scheme "go.medium.engineering/picchu/client/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/cmd/manager/main.go b/cmd/manager/main.go deleted file mode 100644 index f3ed0c1b..00000000 --- a/cmd/manager/main.go +++ /dev/null @@ -1,206 +0,0 @@ -package main - -import ( - "context" - "flag" - "fmt" - "os" - "runtime" - "runtime/debug" - "time" - - slo "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" - monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - "github.com/operator-framework/operator-sdk/pkg/leader" - "github.com/operator-framework/operator-sdk/pkg/log/zap" - "github.com/operator-framework/operator-sdk/pkg/metrics" - sdkVersion "github.com/operator-framework/operator-sdk/version" - wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" - "github.com/spf13/pflag" - "go.medium.engineering/picchu/pkg/apis" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/client/scheme" - "go.medium.engineering/picchu/pkg/controller" - "go.medium.engineering/picchu/pkg/controller/utils" - istio "istio.io/client-go/pkg/apis/networking/v1alpha3" - apps "k8s.io/api/apps/v1" - autoscaling "k8s.io/api/autoscaling/v2beta2" - core "k8s.io/api/core/v1" - k8sruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/intstr" - _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "sigs.k8s.io/controller-runtime/pkg/client/config" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/manager/signals" -) - -// Change below variables to serve metrics on different host or port. -var ( - metricsHost = "0.0.0.0" - metricsPort int32 = 8383 -) -var log = logf.Log.WithName("cmd") - -func printVersion() { - log.Info(fmt.Sprintf("Go Version: %s", runtime.Version())) - log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)) - log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version)) -} - -func main() { - // Add the zap logger flag set to the CLI. The flag set must - // be added before calling pflag.Parse(). - pflag.CommandLine.AddFlagSet(zap.FlagSet()) - - // Add flags registered by imported packages (e.g. glog and - // controller-runtime) - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - - manageRoute53 := pflag.Bool("manage-route53", false, "Should picchu manage route53?") - requeuePeriodSeconds := pflag.Int("sync-period-seconds", 15, "Delay between requeues") - prometheusQueryAddress := pflag.String("prometheus-query-address", "", "The (usually thanos) address that picchu should query to SLO alerts") - prometheusQueryTTL := pflag.Duration("prometheus-query-ttl", time.Duration(10)*time.Second, "How long to cache SLO alerts") - humaneReleasesEnabled := pflag.Bool("humane-releases-enabled", true, "Release apps on the humane schedule") - prometheusEnabled := pflag.Bool("prometheus-enabled", true, "Prometheus integration for SLO alerts is enabled") - serviceLevelsNamespace := pflag.String("service-levels-namespace", "service-level-objectives", "The namespace to use when creating ServiceLevel resources in the delivery cluster") - serviceLevelsFleet := pflag.String("service-levels-fleet", "delivery", "The fleet to use when creating ServiceLevel resources") - concurrentRevisions := pflag.Int("concurrent-revisions", 20, "How many concurrent revisions to reconcile") - concurrentReleaseManagers := pflag.Int("concurrent-release-managers", 50, "How many concurrent release managers to reconcile") - devRoutesServiceHost := pflag.String("dev-routes-service-host", "", "Configures the dev routes service host, if cluster dev routes are enabled") - devRoutesServicePort := pflag.Int("dev-routes-service-port", 80, "Configures the dev routes service port, if cluster dev routes are enabled") - - pflag.Parse() - - // Use a zap logr.Logger implementation. If none of the zap - // flags are configured (or if the zap flag set is not being - // used), this defaults to a production zap logger. - // - // The logger instantiated here can be changed to any logger - // implementing the logr.Logger interface. This logger will - // be propagated through the whole operator, generating - // uniform and structured logs. - logf.SetLogger(zap.Logger()) - - printVersion() - - if !*humaneReleasesEnabled { - log.Info("New revisions with the default (humane) schedule will not be released (--humane-releases-enabled=false)") - } - if !*prometheusEnabled { - log.Info("SLO alerts will not be respected (--prometheus-enabled=false)") - *prometheusQueryAddress = "" - } - - namespace, err := k8sutil.GetWatchNamespace() - if err != nil { - log.Error(err, "Failed to get watch namespace") - os.Exit(1) - } - - // Get a config to talk to the apiserver - cfg, err := config.GetConfig() - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - ctx := context.TODO() - - // Become the leader before proceeding - err = leader.Become(ctx, "picchu-lock") - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - requeuePeriod := time.Duration(*requeuePeriodSeconds) * time.Second - - // Create a new Cmd to provide shared dependencies and start components - mgr, err := manager.New(cfg, manager.Options{ - Namespace: namespace, - MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), - }) - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - log.Info("Registering Components.") - - schemeBuilders := k8sruntime.SchemeBuilder{ - apps.AddToScheme, - core.AddToScheme, - apis.AddToScheme, - autoscaling.AddToScheme, - picchu.AddToScheme, - istio.AddToScheme, - monitoring.AddToScheme, - slo.AddToScheme, - wpav1.AddToScheme, - } - - for _, sch := range []*k8sruntime.Scheme{mgr.GetScheme(), scheme.Scheme} { - if err := picchu.RegisterDefaults(sch); err != nil { - log.Error(err, "") - os.Exit(1) - } - - for _, addToScheme := range schemeBuilders { - if err := addToScheme(sch); err != nil { - log.Error(err, "") - os.Exit(1) - } - } - } - - cconfig := utils.Config{ - ManageRoute53: *manageRoute53, - HumaneReleasesEnabled: *humaneReleasesEnabled, - RequeueAfter: requeuePeriod, - PrometheusQueryAddress: *prometheusQueryAddress, - PrometheusQueryTTL: *prometheusQueryTTL, - ServiceLevelsNamespace: *serviceLevelsNamespace, - ServiceLevelsFleet: *serviceLevelsFleet, - ConcurrentRevisions: *concurrentRevisions, - ConcurrentReleaseManagers: *concurrentReleaseManagers, - DevRoutesServiceHost: *devRoutesServiceHost, - DevRoutesServicePort: *devRoutesServicePort, - } - - // Setup all Controllers - if err := controller.AddToManager(mgr, cconfig); err != nil { - log.Error(err, "") - os.Exit(1) - } - - // Create Service object to expose the metrics port. - servicePorts := []core.ServicePort{ - {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: core.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}}, - } - _, err = metrics.CreateMetricsService(ctx, nil, servicePorts) - if err != nil { - log.Info(err.Error()) - } - - log.Info("Starting the Cmd.") - - // Recover panics to serialize output to json for our logger - defer func() { - if r := recover(); r != nil { - log.Error( - err, "panic", - "recovered", r, - "stacktrace", string(debug.Stack()), - ) - os.Exit(2) - } - }() - - // Start the Cmd - if err = mgr.Start(signals.SetupSignalHandler()); err != nil { - log.Error(err, "Manager exited non-zero") - os.Exit(1) - } -} diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go deleted file mode 100644 index 762adba4..00000000 --- a/cmd/webhook/main.go +++ /dev/null @@ -1,170 +0,0 @@ -package main - -import ( - "context" - "flag" - "fmt" - "os" - "runtime" - "runtime/debug" - - slo "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" - monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - "github.com/operator-framework/operator-sdk/pkg/log/zap" - "github.com/operator-framework/operator-sdk/pkg/metrics" - sdkVersion "github.com/operator-framework/operator-sdk/version" - wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" - "github.com/spf13/pflag" - "go.medium.engineering/picchu/pkg/apis" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/client/scheme" - "go.medium.engineering/picchu/pkg/webhook" - istio "istio.io/client-go/pkg/apis/networking/v1alpha3" - admissionv1beta1 "k8s.io/api/admission/v1beta1" - apps "k8s.io/api/apps/v1" - autoscaling "k8s.io/api/autoscaling/v2beta2" - core "k8s.io/api/core/v1" - k8sruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/intstr" - _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - "sigs.k8s.io/controller-runtime/pkg/client/config" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/manager/signals" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// Change below variables to serve metrics on different host or port. -var ( - metricsHost = "0.0.0.0" - metricsPort int32 = 8383 -) -var log = logf.Log.WithName("cmd") - -func printVersion() { - log.Info(fmt.Sprintf("Go Version: %s", runtime.Version())) - log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)) - log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version)) -} - -func main() { - // Add the zap logger flag set to the CLI. The flag set must - // be added before calling pflag.Parse(). - pflag.CommandLine.AddFlagSet(zap.FlagSet()) - - // Add flags registered by imported packages (e.g. glog and - // controller-runtime) - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - - webhookPort := pflag.Int("webhook-port", 8443, "The port to listen for admission webhooks on") - - pflag.Parse() - - // Use a zap logr.Logger implementation. If none of the zap - // flags are configured (or if the zap flag set is not being - // used), this defaults to a production zap logger. - // - // The logger instantiated here can be changed to any logger - // implementing the logr.Logger interface. This logger will - // be propagated through the whole operator, generating - // uniform and structured logs. - logf.SetLogger(zap.Logger()) - - printVersion() - - namespace, err := k8sutil.GetWatchNamespace() - if err != nil { - log.Error(err, "Failed to get watch namespace") - os.Exit(1) - } - - // Get a config to talk to the apiserver - cfg, err := config.GetConfig() - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - cli, err := client.New(cfg, client.Options{}) - if err != nil { - panic(err) - } - - webhook.Init(cli, int32(*webhookPort), namespace, log) - - ctx := context.Background() - - // Create a new Cmd to provide shared dependencies and start components - mgr, err := manager.New(cfg, manager.Options{ - Namespace: namespace, - MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), - }) - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - log.Info("Registering Components.") - - schemeBuilders := k8sruntime.SchemeBuilder{ - apps.AddToScheme, - core.AddToScheme, - apis.AddToScheme, - autoscaling.AddToScheme, - picchu.AddToScheme, - istio.AddToScheme, - monitoring.AddToScheme, - slo.AddToScheme, - wpav1.AddToScheme, - admissionv1beta1.AddToScheme, - } - - for _, sch := range []*k8sruntime.Scheme{mgr.GetScheme(), scheme.Scheme} { - if err := picchu.RegisterDefaults(sch); err != nil { - log.Error(err, "") - os.Exit(1) - } - - for _, addToScheme := range schemeBuilders { - if err := addToScheme(sch); err != nil { - log.Error(err, "") - os.Exit(1) - } - } - } - - mgr.GetWebhookServer().Port = *webhookPort - - webhook.Register(mgr) - - // Create Service object to expose the metrics port. - servicePorts := []core.ServicePort{ - {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: core.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}}, - } - _, err = metrics.CreateMetricsService(ctx, nil, servicePorts) - if err != nil { - log.Info(err.Error()) - } - - log.Info("Starting the Cmd.") - - // Recover panics to serialize output to json for our logger - defer func() { - if r := recover(); r != nil { - log.Error( - err, "panic", - "recovered", r, - "stacktrace", string(debug.Stack()), - ) - os.Exit(2) - } - }() - - // Start the Cmd - if err = mgr.Start(signals.SetupSignalHandler()); err != nil { - log.Error(err, "Manager exited non-zero") - os.Exit(1) - } -} diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 00000000..d361f623 --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,26 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for +# breaking changes +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 00000000..bebea5a5 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000..90d7c313 --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/config/crd/bases/picchu.medium.engineering_clusters.yaml b/config/crd/bases/picchu.medium.engineering_clusters.yaml new file mode 100644 index 00000000..2f297d67 --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_clusters.yaml @@ -0,0 +1,119 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_clusters.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: clusters.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: Cluster + listKind: ClusterList + plural: clusters + singular: cluster + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster + properties: + config: + properties: + certificate-authority-data: + format: byte + type: string + server: + type: string + required: + - certificate-authority-data + - server + type: object + devRouteTagTemplate: + type: string + enableDevRoutes: + type: boolean + enabled: + type: boolean + hotStandby: + type: boolean + ingresses: + properties: + private: + properties: + defaultDomains: + items: + type: string + type: array + dnsName: + type: string + gateway: + type: string + required: + - defaultDomains + - dnsName + type: object + public: + properties: + defaultDomains: + items: + type: string + type: array + dnsName: + type: string + gateway: + type: string + required: + - defaultDomains + - dnsName + type: object + required: + - private + - public + type: object + scalingFactorString: + type: string + required: + - enabled + - ingresses + type: object + status: + description: ClusterStatus defines the observed state of Cluster + properties: + kubernetes: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state + of cluster Important: Run "make" to regenerate code after modifying + this file' + properties: + ready: + type: boolean + version: + type: string + required: + - ready + - version + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/picchu.medium.engineering_clustersecrets.yaml b/config/crd/bases/picchu.medium.engineering_clustersecrets.yaml new file mode 100644 index 00000000..eed8f29b --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_clustersecrets.yaml @@ -0,0 +1,96 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_clustersecrets.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: clustersecrets.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: ClusterSecrets + listKind: ClusterSecretsList + plural: clustersecrets + singular: clustersecrets + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterSecrets is the Schema for the clustersecrets API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ClusterSecretsSpec defines the desired state of ClusterSecrets + properties: + source: + description: Foo is an example field of ClusterSecrets. Edit ClusterSecrets_types.go + to remove/update + properties: + fieldSelector: + type: string + labelSelector: + type: string + namespace: + type: string + required: + - namespace + type: object + target: + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the copied secrets + type: object + fieldSelector: + description: FieldSelector of clusters to copy secrets to + type: string + labelSelector: + description: LabelSelector of clusters to copy secrets to + type: string + labels: + additionalProperties: + type: string + description: Labels to add to the copied secrets + type: object + namespace: + description: Namespace to copy secrets to + type: string + required: + - namespace + type: object + required: + - source + - target + type: object + status: + description: ClusterSecretsStatus defines the observed state of ClusterSecrets + properties: + secrets: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state + of cluster Important: Run "make" to regenerate code after modifying + this file' + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/picchu.medium.engineering_faultinjectors.yaml b/config/crd/bases/picchu.medium.engineering_faultinjectors.yaml new file mode 100644 index 00000000..f9e93d67 --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_faultinjectors.yaml @@ -0,0 +1,112 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_faultinjectors.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: faultinjectors.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: FaultInjector + listKind: FaultInjectorList + plural: faultinjectors + singular: faultinjector + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: FaultInjector is the Schema for the faultinjectors API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: FaultInjectorSpec defines the desired state of FaultInjector + properties: + httpPortFaults: + description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + Important: Run "make" to regenerate code after modifying this file' + items: + description: HTTPPortFault allows injecting faults into apps by + port number + properties: + fault: + description: "HTTPFaultInjection can be used to specify one + or more faults to inject while forwarding HTTP requests to + the destination specified in a route. Fault specification + is part of a VirtualService rule. Faults include aborting + the Http request from downstream service, and/or delaying + proxying of requests. A fault rule MUST HAVE delay or abort + or both. \n *Note:* Delay and abort faults are independent + of one another, even if both are specified simultaneously." + properties: + abort: + description: Abort Http request attempts and return error + codes back to downstream service, giving the impression + that the upstream service is faulty. + properties: + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + type: number + type: object + type: object + delay: + description: Delay requests before forwarding, emulating + various failures such as network issues, overloaded upstream + service, etc. + properties: + percent: + description: Percentage of requests on which the delay + will be injected (0-100). Use of integer `percent` + value is deprecated. Use the double `percentage` field + instead. + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + type: number + type: object + type: object + type: object + portSelector: + description: PortSelector specifies the number of a port to + be used for matching or selection for final routing. + properties: + number: + description: Valid port number + format: int32 + type: integer + type: object + type: object + type: array + required: + - httpPortFaults + type: object + status: + description: FaultInjectorStatus defines the observed state of FaultInjector + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/picchu.medium.engineering_mirrors.yaml b/config/crd/bases/picchu.medium.engineering_mirrors.yaml new file mode 100644 index 00000000..8e82a398 --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_mirrors.yaml @@ -0,0 +1,114 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_mirrors.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: mirrors.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: Mirror + listKind: MirrorList + plural: mirrors + singular: mirror + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Mirror is the Schema for the mirrors API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: MirrorSpec defines the desired state of Mirror + properties: + additionalConfigSelectors: + items: + properties: + appLabelName: + type: string + labelSelector: + description: A label selector is a label query over a set of + resources. The result of matchLabels and matchExpressions + are ANDed. An empty label selector matches all objects. A + null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespace: + type: string + tagLabelName: + type: string + required: + - appLabelName + - tagLabelName + type: object + type: array + clusterName: + type: string + required: + - clusterName + type: object + status: + description: MirrorStatus defines the observed state of Mirror + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/picchu.medium.engineering_releasemanagers.yaml b/config/crd/bases/picchu.medium.engineering_releasemanagers.yaml new file mode 100644 index 00000000..3c16cd1f --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_releasemanagers.yaml @@ -0,0 +1,184 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_releasemanagers.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: releasemanagers.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: ReleaseManager + listKind: ReleaseManagerList + plural: releasemanagers + singular: releasemanager + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ReleaseManager is the Schema for the releasemanagers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ReleaseManagerSpec defines the desired state of ReleaseManager + properties: + app: + type: string + fleet: + type: string + target: + type: string + variants: + items: + properties: + enabled: + type: boolean + name: + type: string + required: + - enabled + - name + type: object + type: array + required: + - app + - fleet + - target + type: object + status: + description: ReleaseManagerStatus defines the observed state of ReleaseManager + properties: + lastUpdated: + format: date-time + type: string + revisions: + items: + properties: + canaryStartTimestamp: + format: date-time + type: string + currentPercent: + format: int32 + type: integer + deleted: + type: boolean + deployingStartTimestamp: + format: date-time + type: string + gitTimestamp: + format: date-time + type: string + lastUpdated: + format: date-time + type: string + metrics: + description: ReleaseManagerRevisionMetricsStatus defines the + observed state of ReleaseManagerRevisionMetrics + properties: + canarySecondsInt: + type: integer + deploySecondsInt: + type: integer + gitCanarySecondsInt: + type: integer + gitCreateSecondsInt: + type: integer + gitDeploySecondsInt: + type: integer + gitPendingReleaseSecondsInt: + type: integer + gitReleaseSecondsInt: + type: integer + releaseSecondsInt: + type: integer + revisionCanarySecondsInt: + type: integer + revisionDeploySecondsInt: + type: integer + revisionPendingReleaseSecondsInt: + type: integer + revisionReleaseSecondsInt: + type: integer + revisionRollbackSecondsInt: + type: integer + type: object + peakPercent: + format: int32 + type: integer + pendingReleaseStartTimestamp: + format: date-time + type: string + releaseEligible: + type: boolean + releaseStartTimestamp: + format: date-time + type: string + revisionTimestamp: + format: date-time + type: string + scale: + properties: + Current: + format: int32 + type: integer + Desired: + format: int32 + type: integer + Peak: + format: int32 + type: integer + type: object + state: + properties: + current: + type: string + lastUpdated: + format: date-time + type: string + target: + type: string + required: + - current + - target + type: object + tag: + type: string + triggeredAlerts: + items: + type: string + type: array + ttl: + format: int64 + type: integer + required: + - currentPercent + - lastUpdated + - peakPercent + - releaseEligible + - scale + - tag + type: object + type: array + required: + - lastUpdated + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/picchu.medium.engineering_revisions.yaml b/config/crd/bases/picchu.medium.engineering_revisions.yaml new file mode 100644 index 00000000..c8ec9354 --- /dev/null +++ b/config/crd/bases/picchu.medium.engineering_revisions.yaml @@ -0,0 +1,7196 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + config.kubernetes.io/origin: | + path: bases/picchu.medium.engineering_revisions.yaml + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: revisions.picchu.medium.engineering +spec: + group: picchu.medium.engineering + names: + kind: Revision + listKind: RevisionList + plural: revisions + singular: revision + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Revision is the Schema for the revisions API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RevisionSpec defines the desired state of Revision + properties: + app: + properties: + image: + type: string + name: + type: string + ref: + type: string + tag: + type: string + required: + - image + - name + - ref + - tag + type: object + canaryWithSLIRules: + type: boolean + disableMirroring: + type: boolean + failed: + type: boolean + ignoreSLOs: + type: boolean + sentry: + properties: + release: + type: boolean + type: object + tagRoutingHeader: + type: string + targets: + items: + properties: + acceptanceTarget: + type: boolean + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a + no-op). A null preferred scheduling term matches + no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. If + the operator is Gt or Lt, the values + array must have a single element, + which will be interpreted as an integer. + This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. If + the operator is Gt or Lt, the values + array must have a single element, + which will be interpreted as an integer. + This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range + 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an + update), the system may or may not try to eventually + evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. If + the operator is Gt or Lt, the values + array must have a single element, + which will be interpreted as an integer. + This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. If + the operator is Gt or Lt, the values + array must have a single element, + which will be interpreted as an integer. + This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the + corresponding podAffinityTerm; the node(s) with the + highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of + namespaces that the term applies to. The + term is applied to the union of the namespaces + selected by this field and the ones listed + in the namespaces field. null selector and + null or empty namespaces list means "this + pod's namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term applies + to. The term is applied to the union of + the namespaces listed in this field and + the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose value + of the label with key topologyKey matches + that of any node on which any of the selected + pods is running. Empty topologyKey is not + allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range + 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a + pod label update), the system may or may not try to + eventually evict the pod from its node. When there + are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all + terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or + not co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any + node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the greatest + sum of weights, i.e. for each node that meets all + of the scheduling requirements (resource request, + requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if the + node has pods which matches the corresponding podAffinityTerm; + the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of + namespaces that the term applies to. The + term is applied to the union of the namespaces + selected by this field and the ones listed + in the namespaces field. null selector and + null or empty namespaces list means "this + pod's namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term applies + to. The term is applied to the union of + the namespaces listed in this field and + the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose value + of the label with key topologyKey matches + that of any node on which any of the selected + pods is running. Empty topologyKey is not + allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range + 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a + pod label update), the system may or may not try to + eventually evict the pod from its node. When there + are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all + terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or + not co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any + node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified + namespaces, where co-located is defined as running + on a node whose value of the label with key + topologyKey matches that of any node on which + any of the selected pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + alertRules: + items: + description: 'Rule describes an alerting or recording rule + See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) + or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) + rule' + properties: + alert: + description: Name of the alert. Must be a valid label + value. Only one of `record` and `alert` must be set. + type: string + annotations: + additionalProperties: + type: string + description: Annotations to add to each alert. Only valid + for alerting rules. + type: object + expr: + anyOf: + - type: integer + - type: string + description: PromQL expression to evaluate. + x-kubernetes-int-or-string: true + for: + description: Alerts are considered firing once they have + been returned for this long. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + labels: + additionalProperties: + type: string + description: Labels to add or overwrite. + type: object + record: + description: Name of the time series to output to. Must + be a valid metric name. Only one of `record` and `alert` + must be set. + type: string + required: + - expr + type: object + type: array + aws: + description: 'TODO(lyra): PodTemplate' + properties: + iam: + properties: + role_arn: + type: string + type: object + type: object + canary: + properties: + percent: + format: int32 + type: integer + ttl: + format: int64 + type: integer + required: + - percent + - ttl + type: object + configSelector: + description: A label selector is a label query over a set of + resources. The result of matchLabels and matchExpressions + are ANDed. An empty label selector matches all objects. A + null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + defaultIngressPorts: + additionalProperties: + type: string + type: object + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + externalTest: + properties: + completed: + type: boolean + enabled: + type: boolean + lastUpdated: + format: date-time + type: string + started: + type: boolean + succeeded: + type: boolean + timeout: + type: string + required: + - completed + - enabled + - started + type: object + fleet: + type: string + istio: + properties: + sidecar: + properties: + egressHosts: + items: + type: string + type: array + type: object + trafficPolicy: + description: Traffic policies to apply for a specific destination, + across all destination ports. See DestinationRule for + examples. + properties: + connection_pool: + description: Settings controlling the volume of connections + to an upstream service + properties: + http: + description: HTTP connection pool settings. + properties: + h2_upgrade_policy: + description: Specify if http1.1 connection should + be upgraded to http2 for the associated destination. + format: int32 + type: integer + http1_max_pending_requests: + description: Maximum number of pending HTTP + requests to a destination. Default 2^32-1. + format: int32 + type: integer + http2_max_requests: + description: Maximum number of requests to a + backend. Default 2^32-1. + format: int32 + type: integer + idle_timeout: + description: The idle timeout for upstream connection + pool connections. The idle timeout is defined + as the period in which there are no active + requests. If not set, the default is 1 hour. + When the idle timeout is reached, the connection + will be closed. If the connection is an HTTP/2 + connection a drain sequence will occur prior + to closing the connection. Note that request + based timeouts mean that HTTP/2 PINGs will + not keep the connection alive. Applies to + both HTTP1.1 and HTTP2 connections. + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span of + time. Durations less than one second are + represented with a 0 `seconds` field and + a positive or negative `nanos` field. + For durations of one second or more, a + non-zero value for the `nanos` field must + be of the same sign as the `seconds` field. + Must be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span + of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these + bounds are computed from: 60 sec/min * + 60 min/hr * 24 hr/day * 365.25 days/year + * 10000 years' + format: int64 + type: integer + type: object + max_requests_per_connection: + description: Maximum number of requests per + connection to a backend. Setting this parameter + to 1 disables keep alive. Default 0, meaning + "unlimited", up to 2^29. + format: int32 + type: integer + max_retries: + description: Maximum number of retries that + can be outstanding to all hosts in a cluster + at a given time. Defaults to 2^32-1. + format: int32 + type: integer + use_client_protocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. Note that when this is set to + true, h2_upgrade_policy will be ineffective + i.e. the client connections will not be upgraded + to http2. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP + upstream connections. + properties: + connect_timeout: + description: 'TCP connection timeout. format: + 1h/1m/1s/1ms. MUST BE >=1ms. Default is 10s.' + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span of + time. Durations less than one second are + represented with a 0 `seconds` field and + a positive or negative `nanos` field. + For durations of one second or more, a + non-zero value for the `nanos` field must + be of the same sign as the `seconds` field. + Must be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span + of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these + bounds are computed from: 60 sec/min * + 60 min/hr * 24 hr/day * 365.25 days/year + * 10000 years' + format: int64 + type: integer + type: object + max_connections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. Default 2^32-1. + format: int32 + type: integer + tcp_keepalive: + description: If set then set SO_KEEPALIVE on + the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. Default is to use the OS level + configuration (unless overridden, Linux + defaults to 75s.) + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span + of time. Durations less than one second + are represented with a 0 `seconds` + field and a positive or negative `nanos` + field. For durations of one second + or more, a non-zero value for the + `nanos` field must be of the same + sign as the `seconds` field. Must + be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the + span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: 60 + sec/min * 60 min/hr * 24 hr/day * + 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + probes: + description: Maximum number of keepalive + probes to send without response before + deciding the connection is dead. Default + is to use the OS level configuration (unless + overridden, Linux defaults to 9.) + format: int32 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. Default is to use the + OS level configuration (unless overridden, + Linux defaults to 7200s (ie 2 hours.) + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span + of time. Durations less than one second + are represented with a 0 `seconds` + field and a positive or negative `nanos` + field. For durations of one second + or more, a non-zero value for the + `nanos` field must be of the same + sign as the `seconds` field. Must + be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the + span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: 60 + sec/min * 60 min/hr * 24 hr/day * + 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + type: object + type: object + type: object + load_balancer: + description: Settings controlling the load balancer + algorithms. + properties: + locality_lb_setting: + description: Locality load balancer settings, this + will override mesh wide settings in entirety, + meaning no merging would be performed between + this object and the object one in MeshConfig + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set. Explicitly + specify loadbalancing weight across different + zones and geographical locations. Refer to + [Locality weighted load balancing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight) + If empty, the locality weight is set according + to the endpoints number within it.' + items: + description: "Describes how traffic originating + in the 'from' zone or sub-zone is distributed + over a set of 'to' zones. Syntax for specifying + a zone is {region}/{zone}/{sub-zone} and + terminal wildcards are allowed on any segment + of the specification. Examples: \n `*` - + matches all localities \n `us-west/*` - + all zones and sub-zones within the us-west + region \n `us-west/zone-1/*` - all sub-zones + within us-west/zone-1" + properties: + from: + description: Originating locality, '/' + separated, e.g. 'region/zone/sub_zone'. + type: string + to: + additionalProperties: + format: int32 + type: integer + description: Map of upstream localities + to traffic distribution weights. The + sum of all weights should be 100. Any + locality not present will receive no + traffic. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, + this is DestinationRule-level and will override + mesh wide settings in entirety. e.g. true + means that turn on locality load balancing + for this DestinationRule no matter what mesh + wide settings is. + properties: + value: + description: The bool value. + type: boolean + type: object + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set. Explicitly + specify the region traffic will land on when + endpoints in local region becomes unhealthy. + Should be used together with OutlierDetection + to detect unhealthy endpoints. Note: if no + OutlierDetection specified, this will not + take effect.' + items: + description: Specify the traffic failover + policy across regions. Since zone and sub-zone + failover is supported by default this only + needs to be specified for regions when the + operator needs to constrain traffic failover + so that the default behavior of failing + over to any endpoint globally does not apply. + This is useful when failing over traffic + across regions would not improve service + health or may need to be restricted for + other reasons like regulatory controls. + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in + the 'from' region becomes unhealthy. + type: string + type: object + type: array + failover_priority: + description: "failoverPriority is an ordered + list of labels used to sort endpoints to do + priority based load balancing. This is to + support traffic failover across different + groups of endpoints. Suppose there are total + N labels specified: \n 1. Endpoints matching + all N labels with the client proxy have priority + P(0) i.e. the highest priority. 2. Endpoints + matching the first N-1 labels with the client + proxy have priority P(1) i.e. second highest + priority. 3. By extension of this logic, endpoints + matching only the first label with the client + proxy has priority P(N-1) i.e. second lowest + priority. 4. All the other endpoints have + priority P(N) i.e. lowest priority. \n Note: + For a label to be considered for match, the + previous labels must match, i.e. nth label + would be considered matched only if first + n-1 labels match. \n It can be any label specified + on both client and server workloads. The following + labels which have special semantic meaning + are also supported: \n - `topology.istio.io/network` + is used to match the network metadata of an + endpoint, which can be specified by pod/namespace + label `topology.istio.io/network`, sidecar + env `ISTIO_META_NETWORK` or MeshNetworks. + - `topology.istio.io/cluster` is used to match + the clusterID of an endpoint, which can be + specified by pod label `topology.istio.io/cluster` + or pod env `ISTIO_META_CLUSTER_ID`. - `topology.kubernetes.io/region` + is used to match the region metadata of an + endpoint, which maps to Kubernetes node label + `topology.kubernetes.io/region` or the deprecated + label `failure-domain.beta.kubernetes.io/region`. + - `topology.kubernetes.io/zone` is used to + match the zone metadata of an endpoint, which + maps to Kubernetes node label `topology.kubernetes.io/zone` + or the deprecated label `failure-domain.beta.kubernetes.io/zone`. + - `topology.istio.io/subzone` is used to match + the subzone metadata of an endpoint, which + maps to Istio node label `topology.istio.io/subzone`. + \n The below topology config indicates the + following priority levels: \n ```yaml failoverPriority: + - \"topology.istio.io/network\" - \"topology.kubernetes.io/region\" + - \"topology.kubernetes.io/zone\" - \"topology.istio.io/subzone\" + ``` \n 1. endpoints match same [network, region, + zone, subzone] label with the client proxy + have the highest priority. 2. endpoints have + same [network, region, zone] label but different + [subzone] label with the client proxy have + the second highest priority. 3. endpoints + have same [network, region] label but different + [zone] label with the client proxy have the + third highest priority. 4. endpoints have + same [network] but different [region] labels + with the client proxy have the fourth highest + priority. 5. all the other endpoints have + the same lowest priority. \n Optional: only + one of distribute, failover or failoverPriority + can be set. And it should be used together + with `OutlierDetection` to detect unhealthy + endpoints, otherwise has no effect." + items: + type: string + type: array + type: object + warmup_duration_secs: + description: Represents the warmup duration of Service. + If set, the newly created endpoint of service + remains in warmup mode starting from its creation + time for the duration of this window and Istio + progressively increases amount of traffic for + that endpoint instead of sending proportional + amount of traffic. This should be enabled for + services that require warm up time to serve full + production load with reasonable latency. Currently + this is only supported for ROUND_ROBIN and LEAST_CONN + load balancers. + properties: + nanos: + description: Signed fractions of a second at + nanosecond resolution of the span of time. + Durations less than one second are represented + with a 0 `seconds` field and a positive or + negative `nanos` field. For durations of one + second or more, a non-zero value for the `nanos` + field must be of the same sign as the `seconds` + field. Must be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span of + time. Must be from -315,576,000,000 to +315,576,000,000 + inclusive. Note: these bounds are computed + from: 60 sec/min * 60 min/hr * 24 hr/day * + 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + type: object + outlier_detection: + description: Settings controlling eviction of unhealthy + hosts from the load balancing pool + properties: + base_ejection_time: + description: 'Minimum ejection duration. A host + will remain ejected for a period equal to the + product of minimum ejection duration and the number + of times the host has been ejected. This technique + allows the system to automatically increase the + ejection period for unhealthy upstream servers. + format: 1h/1m/1s/1ms. MUST BE >=1ms. Default is + 30s.' + properties: + nanos: + description: Signed fractions of a second at + nanosecond resolution of the span of time. + Durations less than one second are represented + with a 0 `seconds` field and a positive or + negative `nanos` field. For durations of one + second or more, a non-zero value for the `nanos` + field must be of the same sign as the `seconds` + field. Must be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span of + time. Must be from -315,576,000,000 to +315,576,000,000 + inclusive. Note: these bounds are computed + from: 60 sec/min * 60 min/hr * 24 hr/day * + 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + consecutive_5xx_errors: + description: "Number of 5xx errors before a host + is ejected from the connection pool. When the + upstream host is accessed over an opaque TCP connection, + connect timeouts, connection error/failure and + request failure events qualify as a 5xx error. + This feature defaults to 5 but can be disabled + by setting the value to 0. \n Note that consecutive_gateway_errors + and consecutive_5xx_errors can be used separately + or together. Because the errors counted by consecutive_gateway_errors + are also included in consecutive_5xx_errors, if + the value of consecutive_gateway_errors is greater + than or equal to the value of consecutive_5xx_errors, + consecutive_gateway_errors will have no effect." + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + consecutive_errors: + description: Number of errors before a host is ejected + from the connection pool. Defaults to 5. When + the upstream host is accessed over HTTP, a 502, + 503, or 504 return code qualifies as an error. + When the upstream host is accessed over an opaque + TCP connection, connect timeouts and connection + error/failure events qualify as an error. $hide_from_docs + format: int32 + type: integer + consecutive_gateway_errors: + description: "Number of gateway errors before a + host is ejected from the connection pool. When + the upstream host is accessed over HTTP, a 502, + 503, or 504 return code qualifies as a gateway + error. When the upstream host is accessed over + an opaque TCP connection, connect timeouts and + connection error/failure events qualify as a gateway + error. This feature is disabled by default or + when set to the value 0. \n Note that consecutive_gateway_errors + and consecutive_5xx_errors can be used separately + or together. Because the errors counted by consecutive_gateway_errors + are also included in consecutive_5xx_errors, if + the value of consecutive_gateway_errors is greater + than or equal to the value of consecutive_5xx_errors, + consecutive_gateway_errors will have no effect." + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + consecutive_local_origin_failures: + description: The number of consecutive locally originated + failures before ejection occurs. Defaults to 5. + Parameter takes effect only when split_external_local_origin_errors + is set to true. + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + interval: + description: 'Time interval between ejection sweep + analysis. format: 1h/1m/1s/1ms. MUST BE >=1ms. + Default is 10s.' + properties: + nanos: + description: Signed fractions of a second at + nanosecond resolution of the span of time. + Durations less than one second are represented + with a 0 `seconds` field and a positive or + negative `nanos` field. For durations of one + second or more, a non-zero value for the `nanos` + field must be of the same sign as the `seconds` + field. Must be from -999,999,999 to +999,999,999 + inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span of + time. Must be from -315,576,000,000 to +315,576,000,000 + inclusive. Note: these bounds are computed + from: 60 sec/min * 60 min/hr * 24 hr/day * + 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + max_ejection_percent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + Defaults to 10%. + format: int32 + type: integer + min_health_percent: + description: Outlier detection will be enabled as + long as the associated load balancing pool has + at least min_health_percent hosts in healthy mode. + When the percentage of healthy hosts in the load + balancing pool drops below this threshold, outlier + detection will be disabled and the proxy will + load balance across all hosts in the pool (healthy + and unhealthy). The threshold can be disabled + by setting it to 0%. The default is 0% as it's + not typically applicable in k8s environments with + few pods per service. + format: int32 + type: integer + split_external_local_origin_errors: + description: Determines whether to distinguish local + origin failures from external errors. If set to + true consecutive_local_origin_failure is taken + into account for outlier detection calculations. + This should be used when you want to derive the + outlier detection status based on the errors seen + locally such as failure to connect, timeout while + connecting etc. rather than the status code retuned + by upstream service. This is especially useful + when the upstream service explicitly returns a + 5xx for some requests and you want to ignore those + responses from upstream service while determining + the outlier detection status of a host. Defaults + to false. + type: boolean + type: object + port_level_settings: + description: Traffic policies specific to individual + ports. Note that port level settings will override + the destination-level settings. Traffic settings specified + at the destination-level will not be inherited when + overridden by port-level settings, i.e. default values + will be applied to fields omitted in port-level traffic + policies. + items: + description: Traffic policies that apply to specific + ports of the service + properties: + connection_pool: + description: Settings controlling the volume of + connections to an upstream service + properties: + http: + description: HTTP connection pool settings. + properties: + h2_upgrade_policy: + description: Specify if http1.1 connection + should be upgraded to http2 for the + associated destination. + format: int32 + type: integer + http1_max_pending_requests: + description: Maximum number of pending + HTTP requests to a destination. Default + 2^32-1. + format: int32 + type: integer + http2_max_requests: + description: Maximum number of requests + to a backend. Default 2^32-1. + format: int32 + type: integer + idle_timeout: + description: The idle timeout for upstream + connection pool connections. The idle + timeout is defined as the period in + which there are no active requests. + If not set, the default is 1 hour. When + the idle timeout is reached, the connection + will be closed. If the connection is + an HTTP/2 connection a drain sequence + will occur prior to closing the connection. + Note that request based timeouts mean + that HTTP/2 PINGs will not keep the + connection alive. Applies to both HTTP1.1 + and HTTP2 connections. + properties: + nanos: + description: Signed fractions of a + second at nanosecond resolution + of the span of time. Durations less + than one second are represented + with a 0 `seconds` field and a positive + or negative `nanos` field. For durations + of one second or more, a non-zero + value for the `nanos` field must + be of the same sign as the `seconds` + field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the + span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day + * 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + max_requests_per_connection: + description: Maximum number of requests + per connection to a backend. Setting + this parameter to 1 disables keep alive. + Default 0, meaning "unlimited", up to + 2^29. + format: int32 + type: integer + max_retries: + description: Maximum number of retries + that can be outstanding to all hosts + in a cluster at a given time. Defaults + to 2^32-1. + format: int32 + type: integer + use_client_protocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. Note that when this is set + to true, h2_upgrade_policy will be ineffective + i.e. the client connections will not + be upgraded to http2. + type: boolean + type: object + tcp: + description: Settings common to both HTTP + and TCP upstream connections. + properties: + connect_timeout: + description: 'TCP connection timeout. + format: 1h/1m/1s/1ms. MUST BE >=1ms. + Default is 10s.' + properties: + nanos: + description: Signed fractions of a + second at nanosecond resolution + of the span of time. Durations less + than one second are represented + with a 0 `seconds` field and a positive + or negative `nanos` field. For durations + of one second or more, a non-zero + value for the `nanos` field must + be of the same sign as the `seconds` + field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the + span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day + * 365.25 days/year * 10000 years' + format: int64 + type: integer + type: object + max_connections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. Default + 2^32-1. + format: int32 + type: integer + tcp_keepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. Default is to + use the OS level configuration (unless + overridden, Linux defaults to 75s.) + properties: + nanos: + description: Signed fractions + of a second at nanosecond resolution + of the span of time. Durations + less than one second are represented + with a 0 `seconds` field and + a positive or negative `nanos` + field. For durations of one + second or more, a non-zero value + for the `nanos` field must be + of the same sign as the `seconds` + field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of + the span of time. Must be from + -315,576,000,000 to +315,576,000,000 + inclusive. Note: these bounds + are computed from: 60 sec/min + * 60 min/hr * 24 hr/day * 365.25 + days/year * 10000 years' + format: int64 + type: integer + type: object + probes: + description: Maximum number of keepalive + probes to send without response + before deciding the connection is + dead. Default is to use the OS level + configuration (unless overridden, + Linux defaults to 9.) + format: int32 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive + probes start being sent. Default + is to use the OS level configuration + (unless overridden, Linux defaults + to 7200s (ie 2 hours.) + properties: + nanos: + description: Signed fractions + of a second at nanosecond resolution + of the span of time. Durations + less than one second are represented + with a 0 `seconds` field and + a positive or negative `nanos` + field. For durations of one + second or more, a non-zero value + for the `nanos` field must be + of the same sign as the `seconds` + field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of + the span of time. Must be from + -315,576,000,000 to +315,576,000,000 + inclusive. Note: these bounds + are computed from: 60 sec/min + * 60 min/hr * 24 hr/day * 365.25 + days/year * 10000 years' + format: int64 + type: integer + type: object + type: object + type: object + type: object + load_balancer: + description: Settings controlling the load balancer + algorithms. + properties: + locality_lb_setting: + description: Locality load balancer settings, + this will override mesh wide settings in + entirety, meaning no merging would be performed + between this object and the object one in + MeshConfig + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be + set. Explicitly specify loadbalancing + weight across different zones and geographical + locations. Refer to [Locality weighted + load balancing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight) + If empty, the locality weight is set + according to the endpoints number within + it.' + items: + description: "Describes how traffic + originating in the 'from' zone or + sub-zone is distributed over a set + of 'to' zones. Syntax for specifying + a zone is {region}/{zone}/{sub-zone} + and terminal wildcards are allowed + on any segment of the specification. + Examples: \n `*` - matches all localities + \n `us-west/*` - all zones and sub-zones + within the us-west region \n `us-west/zone-1/*` + - all sub-zones within us-west/zone-1" + properties: + from: + description: Originating locality, + '/' separated, e.g. 'region/zone/sub_zone'. + type: string + to: + additionalProperties: + format: int32 + type: integer + description: Map of upstream localities + to traffic distribution weights. + The sum of all weights should + be 100. Any locality not present + will receive no traffic. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, + this is DestinationRule-level and will + override mesh wide settings in entirety. + e.g. true means that turn on locality + load balancing for this DestinationRule + no matter what mesh wide settings is. + properties: + value: + description: The bool value. + type: boolean + type: object + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be + set. Explicitly specify the region traffic + will land on when endpoints in local + region becomes unhealthy. Should be + used together with OutlierDetection + to detect unhealthy endpoints. Note: + if no OutlierDetection specified, this + will not take effect.' + items: + description: Specify the traffic failover + policy across regions. Since zone + and sub-zone failover is supported + by default this only needs to be specified + for regions when the operator needs + to constrain traffic failover so that + the default behavior of failing over + to any endpoint globally does not + apply. This is useful when failing + over traffic across regions would + not improve service health or may + need to be restricted for other reasons + like regulatory controls. + properties: + from: + description: Originating region. + type: string + to: + description: Destination region + the traffic will fail over to + when endpoints in the 'from' region + becomes unhealthy. + type: string + type: object + type: array + failover_priority: + description: "failoverPriority is an ordered + list of labels used to sort endpoints + to do priority based load balancing. + This is to support traffic failover + across different groups of endpoints. + Suppose there are total N labels specified: + \n 1. Endpoints matching all N labels + with the client proxy have priority + P(0) i.e. the highest priority. 2. Endpoints + matching the first N-1 labels with the + client proxy have priority P(1) i.e. + second highest priority. 3. By extension + of this logic, endpoints matching only + the first label with the client proxy + has priority P(N-1) i.e. second lowest + priority. 4. All the other endpoints + have priority P(N) i.e. lowest priority. + \n Note: For a label to be considered + for match, the previous labels must + match, i.e. nth label would be considered + matched only if first n-1 labels match. + \n It can be any label specified on + both client and server workloads. The + following labels which have special + semantic meaning are also supported: + \n - `topology.istio.io/network` is + used to match the network metadata of + an endpoint, which can be specified + by pod/namespace label `topology.istio.io/network`, + sidecar env `ISTIO_META_NETWORK` or + MeshNetworks. - `topology.istio.io/cluster` + is used to match the clusterID of an + endpoint, which can be specified by + pod label `topology.istio.io/cluster` + or pod env `ISTIO_META_CLUSTER_ID`. + - `topology.kubernetes.io/region` is + used to match the region metadata of + an endpoint, which maps to Kubernetes + node label `topology.kubernetes.io/region` + or the deprecated label `failure-domain.beta.kubernetes.io/region`. + - `topology.kubernetes.io/zone` is used + to match the zone metadata of an endpoint, + which maps to Kubernetes node label + `topology.kubernetes.io/zone` or the + deprecated label `failure-domain.beta.kubernetes.io/zone`. + - `topology.istio.io/subzone` is used + to match the subzone metadata of an + endpoint, which maps to Istio node label + `topology.istio.io/subzone`. \n The + below topology config indicates the + following priority levels: \n ```yaml + failoverPriority: - \"topology.istio.io/network\" + - \"topology.kubernetes.io/region\" + - \"topology.kubernetes.io/zone\" - + \"topology.istio.io/subzone\" ``` \n + 1. endpoints match same [network, region, + zone, subzone] label with the client + proxy have the highest priority. 2. + endpoints have same [network, region, + zone] label but different [subzone] + label with the client proxy have the + second highest priority. 3. endpoints + have same [network, region] label but + different [zone] label with the client + proxy have the third highest priority. + 4. endpoints have same [network] but + different [region] labels with the client + proxy have the fourth highest priority. + 5. all the other endpoints have the + same lowest priority. \n Optional: only + one of distribute, failover or failoverPriority + can be set. And it should be used together + with `OutlierDetection` to detect unhealthy + endpoints, otherwise has no effect." + items: + type: string + type: array + type: object + warmup_duration_secs: + description: Represents the warmup duration + of Service. If set, the newly created endpoint + of service remains in warmup mode starting + from its creation time for the duration + of this window and Istio progressively increases + amount of traffic for that endpoint instead + of sending proportional amount of traffic. + This should be enabled for services that + require warm up time to serve full production + load with reasonable latency. Currently + this is only supported for ROUND_ROBIN and + LEAST_CONN load balancers. + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span + of time. Durations less than one second + are represented with a 0 `seconds` field + and a positive or negative `nanos` field. + For durations of one second or more, + a non-zero value for the `nanos` field + must be of the same sign as the `seconds` + field. Must be from -999,999,999 to + +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span + of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: 60 sec/min + * 60 min/hr * 24 hr/day * 365.25 days/year + * 10000 years' + format: int64 + type: integer + type: object + type: object + outlier_detection: + description: Settings controlling eviction of + unhealthy hosts from the load balancing pool + properties: + base_ejection_time: + description: 'Minimum ejection duration. A + host will remain ejected for a period equal + to the product of minimum ejection duration + and the number of times the host has been + ejected. This technique allows the system + to automatically increase the ejection period + for unhealthy upstream servers. format: + 1h/1m/1s/1ms. MUST BE >=1ms. Default is + 30s.' + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span + of time. Durations less than one second + are represented with a 0 `seconds` field + and a positive or negative `nanos` field. + For durations of one second or more, + a non-zero value for the `nanos` field + must be of the same sign as the `seconds` + field. Must be from -999,999,999 to + +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span + of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: 60 sec/min + * 60 min/hr * 24 hr/day * 365.25 days/year + * 10000 years' + format: int64 + type: integer + type: object + consecutive_5xx_errors: + description: "Number of 5xx errors before + a host is ejected from the connection pool. + When the upstream host is accessed over + an opaque TCP connection, connect timeouts, + connection error/failure and request failure + events qualify as a 5xx error. This feature + defaults to 5 but can be disabled by setting + the value to 0. \n Note that consecutive_gateway_errors + and consecutive_5xx_errors can be used separately + or together. Because the errors counted + by consecutive_gateway_errors are also included + in consecutive_5xx_errors, if the value + of consecutive_gateway_errors is greater + than or equal to the value of consecutive_5xx_errors, + consecutive_gateway_errors will have no + effect." + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + consecutive_errors: + description: Number of errors before a host + is ejected from the connection pool. Defaults + to 5. When the upstream host is accessed + over HTTP, a 502, 503, or 504 return code + qualifies as an error. When the upstream + host is accessed over an opaque TCP connection, + connect timeouts and connection error/failure + events qualify as an error. $hide_from_docs + format: int32 + type: integer + consecutive_gateway_errors: + description: "Number of gateway errors before + a host is ejected from the connection pool. + When the upstream host is accessed over + HTTP, a 502, 503, or 504 return code qualifies + as a gateway error. When the upstream host + is accessed over an opaque TCP connection, + connect timeouts and connection error/failure + events qualify as a gateway error. This + feature is disabled by default or when set + to the value 0. \n Note that consecutive_gateway_errors + and consecutive_5xx_errors can be used separately + or together. Because the errors counted + by consecutive_gateway_errors are also included + in consecutive_5xx_errors, if the value + of consecutive_gateway_errors is greater + than or equal to the value of consecutive_5xx_errors, + consecutive_gateway_errors will have no + effect." + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + consecutive_local_origin_failures: + description: The number of consecutive locally + originated failures before ejection occurs. + Defaults to 5. Parameter takes effect only + when split_external_local_origin_errors + is set to true. + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + interval: + description: 'Time interval between ejection + sweep analysis. format: 1h/1m/1s/1ms. MUST + BE >=1ms. Default is 10s.' + properties: + nanos: + description: Signed fractions of a second + at nanosecond resolution of the span + of time. Durations less than one second + are represented with a 0 `seconds` field + and a positive or negative `nanos` field. + For durations of one second or more, + a non-zero value for the `nanos` field + must be of the same sign as the `seconds` + field. Must be from -999,999,999 to + +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: 'Signed seconds of the span + of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: + these bounds are computed from: 60 sec/min + * 60 min/hr * 24 hr/day * 365.25 days/year + * 10000 years' + format: int64 + type: integer + type: object + max_ejection_percent: + description: Maximum % of hosts in the load + balancing pool for the upstream service + that can be ejected. Defaults to 10%. + format: int32 + type: integer + min_health_percent: + description: Outlier detection will be enabled + as long as the associated load balancing + pool has at least min_health_percent hosts + in healthy mode. When the percentage of + healthy hosts in the load balancing pool + drops below this threshold, outlier detection + will be disabled and the proxy will load + balance across all hosts in the pool (healthy + and unhealthy). The threshold can be disabled + by setting it to 0%. The default is 0% as + it's not typically applicable in k8s environments + with few pods per service. + format: int32 + type: integer + split_external_local_origin_errors: + description: Determines whether to distinguish + local origin failures from external errors. + If set to true consecutive_local_origin_failure + is taken into account for outlier detection + calculations. This should be used when you + want to derive the outlier detection status + based on the errors seen locally such as + failure to connect, timeout while connecting + etc. rather than the status code retuned + by upstream service. This is especially + useful when the upstream service explicitly + returns a 5xx for some requests and you + want to ignore those responses from upstream + service while determining the outlier detection + status of a host. Defaults to false. + type: boolean + type: object + port: + description: Specifies the number of a port on + the destination service on which this policy + is being applied. + properties: + number: + description: Valid port number + format: int32 + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + ca_certificates: + description: 'OPTIONAL: The path to the file + containing certificate authority certificates + to use in verifying a presented server certificate. + If omitted, the proxy will not verify the + server''s certificate. Should be empty if + mode is `ISTIO_MUTUAL`.' + type: string + client_certificate: + description: REQUIRED if mode is `MUTUAL`. + The path to the file holding the client-side + TLS certificate to use. Should be empty + if mode is `ISTIO_MUTUAL`. + type: string + credential_name: + description: "The name of the secret that + holds the TLS certs for the client including + the CA certificates. Secret must exist in + the same namespace with the proxy using + the certificates. The secret (of type `generic`)should + contain the following keys and values: `key: + `, `cert: `, `cacert: + `. Here CACertificate is + used to verify the server certificate. Secret + of type tls for client certificates along + with ca.crt key for CA certificates is also + supported. Only one of client certificates + and CA certificate or credentialName can + be specified. \n **NOTE:** This field is + currently applicable only at gateways. Sidecars + will continue to use the certificate paths." + type: string + insecure_skip_verify: + description: "InsecureSkipVerify specifies + whether the proxy should skip verifying + the CA signature and SAN for the server + certificate corresponding to the host. This + flag should only be set if global CA signature + verifcation is enabled, `VerifyCertAtClient` + environmental variable is set to `true`, + but no verification is desired for a specific + host. If enabled with or without `VerifyCertAtClient` + enabled, verification of the CA signature + and SAN will be skipped. \n `InsecureSkipVerify` + is `false` by default. `VerifyCertAtClient` + is `false` by default in Istio version 1.9 + but will be `true` by default in a later + version where, going forward, it will be + enabled by default." + properties: + value: + description: The bool value. + type: boolean + type: object + mode: + description: Indicates whether connections + to this port should be secured using TLS. + The value of this field determines how TLS + is enforced. + format: int32 + type: integer + private_key: + description: REQUIRED if mode is `MUTUAL`. + The path to the file holding the client's + private key. Should be empty if mode is + `ISTIO_MUTUAL`. + type: string + sni: + description: SNI string to present to the + server during TLS handshake. + type: string + subject_alt_names: + description: A list of alternate names to + verify the subject identity in the certificate. + If specified, the proxy will verify that + the server certificate's subject alt name + matches one of the specified values. If + specified, this list overrides the value + of subject_alt_names from the ServiceEntry. + items: + type: string + type: array + type: object + type: object + type: array + tls: + description: TLS related settings for connections to + the upstream service. + properties: + ca_certificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate. If omitted, the + proxy will not verify the server''s certificate. + Should be empty if mode is `ISTIO_MUTUAL`.' + type: string + client_certificate: + description: REQUIRED if mode is `MUTUAL`. The path + to the file holding the client-side TLS certificate + to use. Should be empty if mode is `ISTIO_MUTUAL`. + type: string + credential_name: + description: "The name of the secret that holds + the TLS certs for the client including the CA + certificates. Secret must exist in the same namespace + with the proxy using the certificates. The secret + (of type `generic`)should contain the following + keys and values: `key: `, `cert: `, + `cacert: `. Here CACertificate + is used to verify the server certificate. Secret + of type tls for client certificates along with + ca.crt key for CA certificates is also supported. + Only one of client certificates and CA certificate + or credentialName can be specified. \n **NOTE:** + This field is currently applicable only at gateways. + Sidecars will continue to use the certificate + paths." + type: string + insecure_skip_verify: + description: "InsecureSkipVerify specifies whether + the proxy should skip verifying the CA signature + and SAN for the server certificate corresponding + to the host. This flag should only be set if global + CA signature verifcation is enabled, `VerifyCertAtClient` + environmental variable is set to `true`, but no + verification is desired for a specific host. If + enabled with or without `VerifyCertAtClient` enabled, + verification of the CA signature and SAN will + be skipped. \n `InsecureSkipVerify` is `false` + by default. `VerifyCertAtClient` is `false` by + default in Istio version 1.9 but will be `true` + by default in a later version where, going forward, + it will be enabled by default." + properties: + value: + description: The bool value. + type: boolean + type: object + mode: + description: Indicates whether connections to this + port should be secured using TLS. The value of + this field determines how TLS is enforced. + format: int32 + type: integer + private_key: + description: REQUIRED if mode is `MUTUAL`. The path + to the file holding the client's private key. + Should be empty if mode is `ISTIO_MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subject_alt_names: + description: A list of alternate names to verify + the subject identity in the certificate. If specified, + the proxy will verify that the server certificate's + subject alt name matches one of the specified + values. If specified, this list overrides the + value of subject_alt_names from the ServiceEntry. + items: + type: string + type: array + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + lifecycle: + description: Lifecycle describes actions that the management + system should take in response to container lifecycle events. + For the PostStart and PreStop lifecycle handlers, management + of the container blocks until the action is complete, unless + the container process fails, in which case the handler is + aborted. + properties: + postStart: + description: 'PostStart is called immediately after a container + is created. If the handler fails, the container is terminated + and restarted according to its restart policy. Other management + of the container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container + is terminated due to an API request or management event + such as liveness/startup probe failure, preemption, resource + contention, etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace period + countdown begins before the PreStop hook is executed. + Regardless of the outcome of the handler, the container + will eventually terminate within the Pod''s termination + grace period (unless delayed by finalizers). Other management + of the container blocks until the hook completes or until + the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probe describes a health check to be performed + against a container to determine whether it is alive or ready + to receive traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + This is a beta field and requires enabling GRPCContainerProbe + feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + type: string + podAnnotations: + additionalProperties: + type: string + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + default: + description: 'Default denotes that this port will receive + the default hostnames for the service. This is only + useful if a service exposes multiple ports over the + same ingress gateway (mode: public or private). If only + one port is exposed, it will be the default port. If + multiple ports are exposed and no default is specified + and a port with the `http` name is present, it will + become the default port. If multiple ports are specified + and the `http` port is not present, validation will + fail. Only Mode == (private|public) use the default + flag, as they are trafficked through the same external + port. Internal ports can have the same hostnames since + they can be selected by port number.' + type: boolean + hosts: + items: + type: string + type: array + ingressPort: + format: int32 + type: integer + ingresses: + items: + type: string + type: array + istio: + properties: + http: + properties: + retries: + properties: + attempts: + format: int32 + type: integer + perTryTimeout: + type: string + retryOn: + type: string + type: object + timeout: + type: string + type: object + type: object + mode: + type: string + name: + type: string + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + required: + - mode + - name + type: object + type: array + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed + against a container to determine whether it is alive or ready + to receive traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + This is a beta field and requires enabling GRPCContainerProbe + feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + release: + properties: + eligible: + type: boolean + geometricScaling: + properties: + delay: + type: string + factor: + format: int32 + type: integer + start: + format: int32 + type: integer + type: object + linearScaling: + properties: + delay: + type: string + increment: + format: int32 + type: integer + type: object + max: + format: int32 + type: integer + scalingStrategy: + type: string + schedule: + type: string + ttl: + format: int64 + type: integer + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: set + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + scale: + properties: + default: + format: int32 + type: integer + max: + format: int32 + type: integer + min: + format: int32 + type: integer + minReadySeconds: + format: int32 + type: integer + requestsRateMetric: + description: 'RequestsRateMetric refers to a Prometheus + Adapter metric. See: https://github.com/DirectXMan12/k8s-prometheus-adapter' + type: string + targetCPUUtilizationPercentage: + description: TargetCPUUtilizationPercentage scales based + on CPU percentage + format: int32 + type: integer + targetMemoryUtilizationPercentage: + description: TargetMemoryUtilizationPercentage scales based + on Memory percentage + format: int32 + type: integer + targetRequestsRate: + description: TargetRequestsRate scales based on the specified + RequestsRateMetric + type: string + worker: + description: Worker specifies parameters for Worker Pod + Autoscaler. See https://github.com/practo/k8s-worker-pod-autoscaler + properties: + maxDisruption: + type: string + queueUri: + type: string + secondsToProcessOneJobString: + type: string + targetMessagesPerWorker: + format: int32 + type: integer + required: + - maxDisruption + - queueUri + - targetMessagesPerWorker + type: object + type: object + serviceAccountName: + type: string + serviceLevelObjectiveLabels: + properties: + alertLabels: + additionalProperties: + type: string + type: object + ruleLabels: + additionalProperties: + type: string + type: object + serviceLevelLabels: + additionalProperties: + type: string + type: object + type: object + serviceLevelObjectives: + items: + properties: + description: + type: string + enabled: + type: boolean + name: + type: string + objectivePercentString: + type: string + serviceLevelIndicator: + properties: + alertAfter: + type: string + canary: + properties: + allowancePercent: + type: number + allowancePercentString: + type: string + enabled: + type: boolean + failAfter: + type: string + required: + - enabled + type: object + errorQuery: + type: string + tagKey: + type: string + totalQuery: + type: string + type: object + serviceLevelObjectiveLabels: + properties: + alertLabels: + additionalProperties: + type: string + type: object + ruleLabels: + additionalProperties: + type: string + type: object + serviceLevelLabels: + additionalProperties: + type: string + type: object + type: object + required: + - enabled + type: object + type: array + serviceMonitors: + items: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + sloRegex: + description: if true, and the Spec.Endpoints.MetricRelabelConfigs + does not specify a regex, will replace the regex with + a list of SLO metric names + type: boolean + spec: + description: ServiceMonitorSpec contains specification + parameters for a ServiceMonitor. + properties: + attachMetadata: + description: Attaches node metadata to discovered + targets. Requires Prometheus v2.37.0 and above. + properties: + node: + description: When set to true, Prometheus must + have permissions to get Nodes. + type: boolean + type: object + endpoints: + description: A list of endpoints allowed as part of + this ServiceMonitor. + items: + description: Endpoint defines a scrapeable endpoint + serving Prometheus metrics. + properties: + authorization: + description: Authorization section for this + endpoint + properties: + credentials: + description: The secret's key that contains + the credentials of the request + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. + Defaults to Bearer, Basic will cause an + error + type: string + type: object + basicAuth: + description: 'BasicAuth allow an endpoint to + authenticate over basic authentication More + info: https://prometheus.io/docs/operating/configuration/#endpoints' + properties: + password: + description: The secret in the service monitor + namespace that contains the password for + authentication. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor + namespace that contains the username for + authentication. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + description: File to read bearer token for scraping + targets. + type: string + bearerTokenSecret: + description: Secret to mount to read bearer + token for scraping targets. The secret needs + to be in the same namespace as the service + monitor and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: Whether to enable HTTP2. + type: boolean + filterRunning: + description: 'Drop pods that are not running. + (Failed, Succeeded). Enabled by default. More + info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' + type: boolean + followRedirects: + description: FollowRedirects configures whether + scrape requests follow HTTP 3xx redirects. + type: boolean + honorLabels: + description: HonorLabels chooses the metric's + labels on collisions with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether + Prometheus respects the timestamps present + in scraped data. + type: boolean + interval: + description: Interval at which metrics should + be scraped If not specified Prometheus' global + scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: MetricRelabelConfigs to apply to + samples before ingestion. + items: + description: 'RelabelConfig allows dynamic + rewriting of the label set, being applied + to samples before ingestion. It defines + ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on + regex matching. Default is 'replace'. + uppercase and lowercase actions require + Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + type: string + modulus: + description: Modulus to take of the hash + of the source label values. + format: int64 + type: integer + regex: + description: Regular expression against + which the extracted value is matched. + Default is '(.*)' + type: string + replacement: + description: Replacement value against + which a regex replace is performed if + the regular expression matches. Regex + capture groups are available. Default + is '$1' + type: string + separator: + description: Separator placed between + concatenated source label values. default + is ';'. + type: string + sourceLabels: + description: The source labels select + values from existing labels. Their content + is concatenated using the configured + separator and matched against the configured + regular expression for the replace, + keep, and drop actions. + items: + description: LabelName is a valid Prometheus + label name which may only contain + ASCII letters, numbers, as well as + underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting + value is written in a replace action. + It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + oauth2: + description: OAuth2 for the URL. Only valid + in Prometheus versions 2.27.0 and newer. + properties: + clientId: + description: The secret or configmap containing + the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data + to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 + client secret + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the + token URL + type: object + scopes: + description: OAuth2 scopes used for the + token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token + from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: Optional HTTP URL parameters + type: object + path: + description: HTTP path to scrape for metrics. + If empty, Prometheus uses the default value + (e.g. `/metrics`). + type: string + port: + description: Name of the service port this endpoint + refers to. Mutually exclusive with targetPort. + type: string + proxyUrl: + description: ProxyURL eg http://proxyserver:2195 + Directs scrapes to proxy through this endpoint. + type: string + relabelings: + description: 'RelabelConfigs to apply to samples + before scraping. Prometheus Operator automatically + adds relabelings for a few standard Kubernetes + fields. The original scrape job''s name is + available via the `__tmp_prometheus_job_name` + label. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' + items: + description: 'RelabelConfig allows dynamic + rewriting of the label set, being applied + to samples before ingestion. It defines + ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on + regex matching. Default is 'replace'. + uppercase and lowercase actions require + Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + type: string + modulus: + description: Modulus to take of the hash + of the source label values. + format: int64 + type: integer + regex: + description: Regular expression against + which the extracted value is matched. + Default is '(.*)' + type: string + replacement: + description: Replacement value against + which a regex replace is performed if + the regular expression matches. Regex + capture groups are available. Default + is '$1' + type: string + separator: + description: Separator placed between + concatenated source label values. default + is ';'. + type: string + sourceLabels: + description: The source labels select + values from existing labels. Their content + is concatenated using the configured + separator and matched against the configured + regular expression for the replace, + keep, and drop actions. + items: + description: LabelName is a valid Prometheus + label name which may only contain + ASCII letters, numbers, as well as + underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting + value is written in a replace action. + It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: HTTP scheme to use for scraping. + type: string + scrapeTimeout: + description: Timeout after which the scrape + is ended If not specified, the Prometheus + global scrape timeout is used unless it is + less than `Interval` in which the latter is + used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: Name or number of the target port + of the Pod behind the Service, the port must + be specified with container port property. + Mutually exclusive with port. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping + the endpoint + properties: + ca: + description: Certificate authority used + when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data + to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the + Prometheus container to use for the targets. + type: string + cert: + description: Client certificate to present + when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data + to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. + apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the + Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file + in the Prometheus container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate + validation. + type: boolean + keyFile: + description: Path to the client key file + in the Prometheus container for the targets. + type: string + keySecret: + description: Secret containing the client + key file for the targets. + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname + for the targets. + type: string + type: object + type: object + type: array + jobLabel: + description: "JobLabel selects the label from the + associated Kubernetes service which will be used + as the `job` label for all metrics. \n For example: + If in `ServiceMonitor.spec.jobLabel: foo` and in + `Service.metadata.labels.foo: bar`, then the `job=\"bar\"` + label is added to all metrics. \n If the value of + this field is empty or if the label doesn't exist + for the given Service, the `job` label of the metrics + defaults to the name of the Kubernetes Service." + type: string + labelLimit: + description: Per-scrape limit on number of labels + that will be accepted for a sample. Only valid in + Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: Per-scrape limit on length of labels + name that will be accepted for a sample. Only valid + in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: Per-scrape limit on length of labels + value that will be accepted for a sample. Only valid + in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + namespaceSelector: + description: Selector to select which namespaces the + Kubernetes Endpoints objects are discovered from. + properties: + any: + description: Boolean describing whether all namespaces + are selected in contrast to a list restricting + them. + type: boolean + matchNames: + description: List of namespace names to select + from. + items: + type: string + type: array + type: object + podTargetLabels: + description: PodTargetLabels transfers labels on the + Kubernetes `Pod` onto the created metrics. + items: + type: string + type: array + sampleLimit: + description: SampleLimit defines per-scrape limit + on number of scraped samples that will be accepted. + format: int64 + type: integer + selector: + description: Selector to select Endpoints objects. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetLabels: + description: TargetLabels transfers labels from the + Kubernetes `Service` onto the created metrics. + items: + type: string + type: array + targetLimit: + description: TargetLimit defines a limit on the number + of scraped targets that will be accepted. + format: int64 + type: integer + required: + - endpoints + - selector + type: object + required: + - name + - sloRegex + type: object + type: array + sidecars: + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a + shell. The container image''s ENTRYPOINT is used if + this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If + a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults + to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported + as an event when the container is starting. When a key + exists in multiple sources, the value associated with + the last source will take precedence. Values defined + by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images in + workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, + IfNotPresent. Defaults to Always if :latest tag is specified, + or IfNotPresent otherwise. Cannot be updated. More info: + https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should + take in response to container lifecycle events. Cannot + be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according + to its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside a + shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you + need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to + access on the container. Number must be + in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to + access on the container. Number must be + in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before + a container is terminated due to an API request + or management event such as liveness/startup probe + failure, preemption, resource contention, etc. The + handler is not called if the container crashes or + exits. The Pod''s termination grace period countdown + begins before the PreStop hook is executed. Regardless + of the outcome of the handler, the container will + eventually terminate within the Pod''s termination + grace period (unless delayed by finalizers). Other + management of the container blocks until the hook + completes or until the termination grace period + is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside a + shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you + need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to + access on the container. Number must be + in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to + access on the container. Number must be + in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory + for the command is root ('/') in the container's + filesystem. The command is simply exec'd, it + is not run inside a shell, so traditional shell + instructions ('|', etc) won't work. To use a + shell, you need to explicitly call out to that + shell. Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a + GRPC port. This is a beta field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see + https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to + perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. + Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod + needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after + the processes running in the pod are sent a termination + signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the + value provided by the pod spec. Value must be non-negative + integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be + accessible from the network. Modifying this array with + strategic merge patch may corrupt the data. For more + information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, + 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in + a pod must have a unique name. Name for the port + that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if + the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory + for the command is root ('/') in the container's + filesystem. The command is simply exec'd, it + is not run inside a shell, so traditional shell + instructions ('|', etc) won't work. To use a + shell, you need to explicitly call out to that + shell. Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a + GRPC port. This is a beta field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see + https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to + perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. + Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod + needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after + the processes running in the pod are sent a termination + signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the + value provided by the pod spec. Value must be non-negative + integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used by + this container. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n This field is immutable." + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one + entry in pod.spec.resourceClaims of the Pod + where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: set + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields + of SecurityContext override the equivalent fields of + PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as + Privileged 2) has CAP_SYS_ADMIN Note that this field + cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this + field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field + cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the + container process. Uses runtime default if unset. + May also be set in PodSecurityContext. If set in + both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not + run as UID 0 (root) and fail to start the container + if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified in + image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be + set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + the container. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod + & container level, the container options override + the pod options. Note that this field cannot be + set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative + to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: + \n Localhost - a profile defined in a file on + the node should be used. RuntimeDefault - the + container runtime default profile should be + used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options from + the PodSecurityContext will be used. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name + is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. + This field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the + feature flag will result in errors when validating + the Pod. All of a Pod's containers must have + the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must + also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has + successfully initialized. If specified, no other probes + are executed until this completes successfully. If this + probe fails, the Pod will be restarted, just as if the + livenessProbe failed. This can be used to provide different + probe parameters at the beginning of a Pod''s lifecycle, + when it might take a long time to load data or warm + a cache, than during steady-state operation. This cannot + be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory + for the command is root ('/') in the container's + filesystem. The command is simply exec'd, it + is not run inside a shell, so traditional shell + instructions ('|', etc) won't work. To use a + shell, you need to explicitly call out to that + shell. Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a + GRPC port. This is a beta field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see + https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to + perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. + Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod + needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after + the processes running in the pod are sent a termination + signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the + value provided by the pod spec. Value must be non-negative + integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a + buffer for stdin in the container runtime. If this is + not set, reads from stdin in the container will always + result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is + empty until the first client attaches to stdin, and + then remains open and accepts data until the client + disconnects, at which time stdin is closed and remains + closed until the container is restarted. If this flag + is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written + is mounted into the container''s filesystem. Message + written is intended to be brief final status, such as + an assertion failure message. Will be truncated by the + node if greater than 4096 bytes. The total message length + across all containers will be limited to 12kb. Defaults + to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last + chunk of container log output if the termination message + file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, + whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a + TTY for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which + the volume should be mounted. Must not contain + ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and + the other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to + false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults + to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the + container's environment. Defaults to "" (volume's + root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which + might be configured in the container image. Cannot be + updated. + type: string + required: + - name + type: object + type: array + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + volumeMounts: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default + is to mount by volume name. Examples: For volume + /dev/sda1, you specify the partition as "1". Similarly, + the volume partition for /dev/sda is "0" (or you + can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a + collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to + OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If + a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked + optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires decimal + values for mode bits. If not specified, the + volume defaultMode will be used. This might + be in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all + secret references are passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal + value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal + values for mode bits. If not specified, the + volume defaultMode will be used. This might + be in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The + maximum usage on memory medium EmptyDir would be + the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that the + limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle + is tied to the pod that defines it - it will be created + before the pod starts, and deleted when the pod is removed. + \n Use this if: a) the volume is only needed while the + pod runs, b) features of normal volumes like restoring + from snapshot or capacity tracking are needed, c) the + storage driver is specified through a storage class, + and d) the storage driver supports dynamic volume provisioning + through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that + persist for longer than the lifecycle of an individual + pod. \n Use CSI for light-weight local ephemeral volumes + if the CSI driver is meant to be used that way - see + the documentation of the driver for more information. + \n A pod can use both types of ephemeral volumes and + persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which this + EphemeralVolumeSource is embedded will be the owner + of the PVC, i.e. the PVC will be deleted together + with the pod. The name of the PVC will be `-` where `` is the + name from the `PodSpec.Volumes` array entry. Pod + validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). + \n An existing PVC with that name that is not owned + by the pod will *not* be used for the pod to avoid + using an unrelated volume by mistake. Starting the + pod is then blocked until the unrelated PVC is removed. + If such a pre-created PVC is meant to be used by + the pod, the PVC has to updated with an owner reference + to the pod once the pod exists. Normally this should + not be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field is + read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If APIGroup + is not specified, the specified Kind + must be in the core API group. For any + other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume + binding will only succeed if the type of + the specified object matches some installed + volume populator or dynamic provisioner. + This field will replace the functionality + of the dataSource field and as such if both + fields are non-empty, they must have the + same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, + both fields (dataSource and dataSourceRef) + will be set to the same value automatically + if one of them is empty and the other is + non-empty. When namespace is specified in + dataSourceRef, dataSource isn''t set to + the same value and must be empty. There + are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves + all values, and generates an error if a + disallowed value is specified. * While dataSource + only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) + Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If APIGroup + is not specified, the specified Kind + must be in the core API group. For any + other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are lower + than previous value but must still be higher + than capacity recorded in the status field + of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n + This is an alpha field and requires + enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the + name of one entry in pod.spec.resourceClaims + of the Pod where this field is + used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: set + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. If + the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default + is to mount by volume name. Examples: For volume + /dev/sda1, you specify the partition as "1". Similarly, + the volume partition for /dev/sda is "0" (or you + can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a + particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an EmptyDir + into an InitContainer that clones the repo using git, + then mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly exposed + to the container. This is generally used for system + agents or other privileged things that are allowed to + see the host machine. Most containers will NOT need + this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to + "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports + 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports + 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to + set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. Directories within the path are not + affected by this setting. This might be in conflict + with other options that affect the file mode, like + fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of the + referenced ConfigMap will be projected + into the volume as a file whose name is + the key and content is the value. If specified, + the listed keys will be projected into + the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the ConfigMap, + the volume setup will error unless it + is marked optional. Paths must be relative + and may not contain the '..' path or start + with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on + this file. Must be an octal value + between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts + both octal and decimal values, JSON + requires decimal values for mode + bits. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options + that affect the file mode, like + fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, JSON + requires decimal values for mode + bits. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options + that affect the file mode, like + fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of the + referenced Secret will be projected into + the volume as a file whose name is the + key and content is the value. If specified, + the listed keys will be projected into + the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the Secret, the + volume setup will error unless it is marked + optional. Paths must be relative and may + not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on + this file. Must be an octal value + between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts + both octal and decimal values, JSON + requires decimal values for mode + bits. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options + that affect the file mode, like + fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience + defaults to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The + kubelet will start trying to rotate the + token if the token is older than 80 percent + of its time to live or if the token is + older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to + the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for + ScaleIO user and other sensitive information. If + this is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated + with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If + a key is specified which is not present in the Secret, + the volume setup will error unless it is marked + optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires decimal + values for mode bits. If not specified, the + volume defaultMode will be used. This might + be in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in + VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is + specified then the Pod's namespace will be used. This + allows the Kubernetes name scoping to be mirrored + within StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - fleet + - name + - scale + type: object + type: array + required: + - app + - failed + - targets + type: object + status: + description: RevisionStatus defines the observed state of Revision + properties: + sentry: + properties: + release: + type: boolean + type: object + targets: + items: + description: RevisionStatus defines the observed state of Revision + properties: + name: + type: string + release: + properties: + currentPercent: + format: int32 + type: integer + peakPercent: + format: int32 + type: integer + required: + - currentPercent + - peakPercent + type: object + scale: + properties: + current: + format: int32 + type: integer + desired: + format: int32 + type: integer + peak: + format: int32 + type: integer + required: + - current + - desired + - peak + type: object + state: + type: string + required: + - name + - release + - scale + type: object + type: array + required: + - sentry + - targets + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml new file mode 100644 index 00000000..0503516c --- /dev/null +++ b/config/crd/kustomization.yaml @@ -0,0 +1,53 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/picchu.medium.engineering_clusters.yaml +- bases/picchu.medium.engineering_releasemanagers.yaml +- bases/picchu.medium.engineering_mirrors.yaml +- bases/picchu.medium.engineering_clustersecrets.yaml +- bases/picchu.medium.engineering_revisions.yaml +- bases/picchu.medium.engineering_faultinjectors.yaml + +buildMetadata: [originAnnotations] + +# +kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_clusters.yaml +#- patches/webhook_in_releasemanagers.yaml +#- patches/webhook_in_mirrors.yaml +#- patches/webhook_in_clustersecrets.yaml +#- patches/webhook_in_revisions.yaml +#- patches/webhook_in_faultinjectors.yaml +# +kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +#- patches/cainjection_in_clusters.yaml +#- patches/cainjection_in_releasemanagers.yaml +#- patches/cainjection_in_mirrors.yaml +#- patches/cainjection_in_clustersecrets.yaml +#- patches/cainjection_in_revisions.yaml +#- patches/cainjection_in_faultinjectors.yaml +# +kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml + +patchesJson6902: +- target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: revisions.picchu.medium.engineering + path: patches/k8s_list_map_keys.yaml +#- target: +# group: apiextensions.k8s.io +# version: v1 +# kind: CustomResourceDefinition +# name: revisions.picchu.medium.engineering +# path: patches/preserve_unknown.yaml diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000..6f83d9a9 --- /dev/null +++ b/config/crd/kustomizeconfig.yaml @@ -0,0 +1,17 @@ +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/config/crd/patches/cainjection_in_clusters.yaml b/config/crd/patches/cainjection_in_clusters.yaml new file mode 100644 index 00000000..0f454c3f --- /dev/null +++ b/config/crd/patches/cainjection_in_clusters.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: clusters.picchu.medium.engineering diff --git a/config/crd/patches/cainjection_in_clustersecrets.yaml b/config/crd/patches/cainjection_in_clustersecrets.yaml new file mode 100644 index 00000000..5a098cd6 --- /dev/null +++ b/config/crd/patches/cainjection_in_clustersecrets.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: clustersecrets.picchu.medium.engineering diff --git a/config/crd/patches/cainjection_in_faultinjectors.yaml b/config/crd/patches/cainjection_in_faultinjectors.yaml new file mode 100644 index 00000000..a297ef5f --- /dev/null +++ b/config/crd/patches/cainjection_in_faultinjectors.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: faultinjectors.picchu.medium.engineering diff --git a/config/crd/patches/cainjection_in_mirrors.yaml b/config/crd/patches/cainjection_in_mirrors.yaml new file mode 100644 index 00000000..e0ea9831 --- /dev/null +++ b/config/crd/patches/cainjection_in_mirrors.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: mirrors.picchu.medium.engineering diff --git a/config/crd/patches/cainjection_in_releasemanagers.yaml b/config/crd/patches/cainjection_in_releasemanagers.yaml new file mode 100644 index 00000000..733b6727 --- /dev/null +++ b/config/crd/patches/cainjection_in_releasemanagers.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: releasemanagers.picchu.medium.engineering diff --git a/config/crd/patches/cainjection_in_revisions.yaml b/config/crd/patches/cainjection_in_revisions.yaml new file mode 100644 index 00000000..b2a52960 --- /dev/null +++ b/config/crd/patches/cainjection_in_revisions.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: revisions.picchu.medium.engineering diff --git a/config/crd/patches/k8s_list_map_keys.yaml b/config/crd/patches/k8s_list_map_keys.yaml new file mode 100644 index 00000000..0144ce26 --- /dev/null +++ b/config/crd/patches/k8s_list_map_keys.yaml @@ -0,0 +1,17 @@ +- op: add + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/targets/items/properties/sidecars/items/properties/resources/properties/claims/items/x-kubernetes-map-type + value: atomic + +- op: add + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/targets/items/properties/volumes/items/properties/ephemeral/properties/volumeClaimTemplate/properties/spec/properties/resources/properties/claims/items/x-kubernetes-map-type + value: atomic + +- op: add + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/targets/items/properties/resources/properties/claims/items/x-kubernetes-map-type + value: atomic + + +#spec.validation.openAPIV3Schema.properties[spec].properties[targets].items.properties[sidecars].items.properties[resources].properties[claims].items.x-kubernetes-map-type: Invalid value: \"null\": must be atomic as item of a list with x-kubernetes-list-type=set, +#spec.validation.openAPIV3Schema.properties[spec].properties[targets].items.properties[resources].properties[claims].items +#spec.validation.openAPIV3Schema.properties[spec].properties[targets].items.properties[volumes].items.properties[ephemeral].properties[volumeClaimTemplate].properties[spec].properties[resources].properties[claims].items.x-kubernetes-map-type +#spec.validation.openAPIV3Schema.properties[spec].properties[targets].items.properties[resources].properties[claims].items \ No newline at end of file diff --git a/config/crd/patches/webhook_in_clusters.yaml b/config/crd/patches/webhook_in_clusters.yaml new file mode 100644 index 00000000..94957ba1 --- /dev/null +++ b/config/crd/patches/webhook_in_clusters.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusters.picchu.medium.engineering +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/crd/patches/webhook_in_clustersecrets.yaml b/config/crd/patches/webhook_in_clustersecrets.yaml new file mode 100644 index 00000000..536d511e --- /dev/null +++ b/config/crd/patches/webhook_in_clustersecrets.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clustersecrets.picchu.medium.engineering +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/crd/patches/webhook_in_faultinjectors.yaml b/config/crd/patches/webhook_in_faultinjectors.yaml new file mode 100644 index 00000000..e733e999 --- /dev/null +++ b/config/crd/patches/webhook_in_faultinjectors.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: faultinjectors.picchu.medium.engineering +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/crd/patches/webhook_in_mirrors.yaml b/config/crd/patches/webhook_in_mirrors.yaml new file mode 100644 index 00000000..b4b26573 --- /dev/null +++ b/config/crd/patches/webhook_in_mirrors.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: mirrors.picchu.medium.engineering +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/crd/patches/webhook_in_releasemanagers.yaml b/config/crd/patches/webhook_in_releasemanagers.yaml new file mode 100644 index 00000000..4100f633 --- /dev/null +++ b/config/crd/patches/webhook_in_releasemanagers.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: releasemanagers.picchu.medium.engineering +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml new file mode 100644 index 00000000..cd6ddeb9 --- /dev/null +++ b/config/default/kustomization.yaml @@ -0,0 +1,69 @@ +# Adds namespace to all resources. +namespace: picchu + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: + # Protect the /metrics endpoint by putting it behind auth. + # If you want your controller-manager to expose the /metrics + # endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +- manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. +# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. +# 'CERTMANAGER' needs to be enabled to use ca injection +- webhookcainjection_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000..dd83b629 --- /dev/null +++ b/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,25 @@ +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: picchu + namespace: picchu +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8383/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https + - name: manager + args: + - "--metrics-addr=127.0.0.1:8383" + - "--enable-leader-election" diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000..376c9c65 --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: picchu + namespace: picchu +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000..02ab515d --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml new file mode 100644 index 00000000..5c5f0b84 --- /dev/null +++ b/config/manager/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- manager.yaml diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml new file mode 100644 index 00000000..e664be3f --- /dev/null +++ b/config/manager/manager.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: picchu + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: picchu + namespace: picchu + labels: + control-plane: picchu +spec: + selector: + matchLabels: + control-plane: picchu + replicas: 1 + template: + metadata: + labels: + control-plane: picchu + spec: + containers: + - command: + - /manager + args: + - --enable-leader-election + image: controller:latest + name: manager + resources: + limits: + memory: 6Gi + requests: + cpu: "1" + memory: 6Gi + terminationGracePeriodSeconds: 10 diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml new file mode 100644 index 00000000..ed137168 --- /dev/null +++ b/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml new file mode 100644 index 00000000..df83ce2f --- /dev/null +++ b/config/prometheus/monitor.yaml @@ -0,0 +1,16 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: picchu + name: picchu-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + selector: + matchLabels: + control-plane: picchu diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000..bd4af137 --- /dev/null +++ b/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: ["/metrics"] + verbs: ["get"] diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000..618f5e41 --- /dev/null +++ b/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000..ced1bcc2 --- /dev/null +++ b/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: picchu + namespace: picchu diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000..b84f7d59 --- /dev/null +++ b/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: picchu + name: picchu-metrics-service + namespace: picchu +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: picchu diff --git a/config/rbac/cluster_editor_role.yaml b/config/rbac/cluster_editor_role.yaml new file mode 100644 index 00000000..b618d76d --- /dev/null +++ b/config/rbac/cluster_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit clusters. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-editor-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - clusters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clusters/status + verbs: + - get diff --git a/config/rbac/cluster_viewer_role.yaml b/config/rbac/cluster_viewer_role.yaml new file mode 100644 index 00000000..cfa22b8d --- /dev/null +++ b/config/rbac/cluster_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view clusters. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - clusters + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clusters/status + verbs: + - get diff --git a/config/rbac/clustersecrets_editor_role.yaml b/config/rbac/clustersecrets_editor_role.yaml new file mode 100644 index 00000000..8e226dad --- /dev/null +++ b/config/rbac/clustersecrets_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit clustersecrets. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: clustersecrets-editor-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets/status + verbs: + - get diff --git a/config/rbac/clustersecrets_viewer_role.yaml b/config/rbac/clustersecrets_viewer_role.yaml new file mode 100644 index 00000000..0dacb8b6 --- /dev/null +++ b/config/rbac/clustersecrets_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view clustersecrets. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: clustersecrets-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets/status + verbs: + - get diff --git a/config/rbac/faultinjector_editor_role.yaml b/config/rbac/faultinjector_editor_role.yaml new file mode 100644 index 00000000..2cdbce49 --- /dev/null +++ b/config/rbac/faultinjector_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit faultinjectors. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: faultinjector-editor-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - faultinjectors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - faultinjectors/status + verbs: + - get diff --git a/config/rbac/faultinjector_viewer_role.yaml b/config/rbac/faultinjector_viewer_role.yaml new file mode 100644 index 00000000..5c4a0506 --- /dev/null +++ b/config/rbac/faultinjector_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view faultinjectors. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: faultinjector-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - faultinjectors + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - faultinjectors/status + verbs: + - get diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml new file mode 100644 index 00000000..4323c973 --- /dev/null +++ b/config/rbac/kustomization.yaml @@ -0,0 +1,15 @@ +resources: +- role.yaml +- role_extra.yaml +- role_binding.yaml +- role_binding_extra.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# Comment the following 4 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +- auth_proxy_service.yaml +- auth_proxy_role.yaml +- auth_proxy_role_binding.yaml +- auth_proxy_client_clusterrole.yaml +- service_account.yaml diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000..f4213838 --- /dev/null +++ b/config/rbac/leader_election_role.yaml @@ -0,0 +1,45 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000..2a1219ec --- /dev/null +++ b/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: picchu + namespace: picchu diff --git a/deploy/role.yaml b/config/rbac/mirror_editor_role.yaml similarity index 63% rename from deploy/role.yaml rename to config/rbac/mirror_editor_role.yaml index 2e4fb8a0..e8d121ff 100644 --- a/deploy/role.yaml +++ b/config/rbac/mirror_editor_role.yaml @@ -1,19 +1,13 @@ +# permissions for end users to edit mirrors. apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null - name: picchu + name: mirror-editor-role rules: -- apiGroups: - - '*' - resources: - - '*' - verbs: - - '*' - apiGroups: - picchu.medium.engineering resources: - - '*' + - mirrors verbs: - create - delete @@ -22,3 +16,9 @@ rules: - patch - update - watch +- apiGroups: + - picchu.medium.engineering + resources: + - mirrors/status + verbs: + - get diff --git a/config/rbac/mirror_viewer_role.yaml b/config/rbac/mirror_viewer_role.yaml new file mode 100644 index 00000000..173611a9 --- /dev/null +++ b/config/rbac/mirror_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view mirrors. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: mirror-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - mirrors + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - mirrors/status + verbs: + - get diff --git a/config/rbac/releasemanager_editor_role.yaml b/config/rbac/releasemanager_editor_role.yaml new file mode 100644 index 00000000..b812bbe4 --- /dev/null +++ b/config/rbac/releasemanager_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit releasemanagers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: releasemanager-editor-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers/status + verbs: + - get diff --git a/config/rbac/releasemanager_viewer_role.yaml b/config/rbac/releasemanager_viewer_role.yaml new file mode 100644 index 00000000..163c1d1a --- /dev/null +++ b/config/rbac/releasemanager_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view releasemanagers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: releasemanager-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers/status + verbs: + - get diff --git a/config/rbac/revision_editor_role.yaml b/config/rbac/revision_editor_role.yaml new file mode 100644 index 00000000..37934365 --- /dev/null +++ b/config/rbac/revision_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit revisions. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: revision-editor-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - revisions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - revisions/status + verbs: + - get diff --git a/config/rbac/revision_viewer_role.yaml b/config/rbac/revision_viewer_role.yaml new file mode 100644 index 00000000..59ded83c --- /dev/null +++ b/config/rbac/revision_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view revisions. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: revision-viewer-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - revisions + verbs: + - get + - list + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - revisions/status + verbs: + - get diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml new file mode 100644 index 00000000..2216f67b --- /dev/null +++ b/config/rbac/role.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - picchu.medium.engineering + resources: + - clusters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clusters/status + verbs: + - get + - patch + - update +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - clustersecrets/status + verbs: + - get + - patch + - update +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - releasemanagers/status + verbs: + - get + - patch + - update +- apiGroups: + - picchu.medium.engineering + resources: + - revisions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - revisions/status + verbs: + - get + - patch + - update diff --git a/deploy/role_binding.yaml b/config/rbac/role_binding.yaml similarity index 81% rename from deploy/role_binding.yaml rename to config/rbac/role_binding.yaml index 72dd1c4e..06289ed9 100644 --- a/deploy/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,12 +1,12 @@ -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: - name: picchu + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role subjects: - kind: ServiceAccount name: picchu namespace: picchu -roleRef: - kind: ClusterRole - name: picchu - apiGroup: rbac.authorization.k8s.io diff --git a/config/rbac/role_binding_extra.yaml b/config/rbac/role_binding_extra.yaml new file mode 100644 index 00000000..b47e1833 --- /dev/null +++ b/config/rbac/role_binding_extra.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: manager-rolebinding-extra +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role-extra +subjects: +- kind: ServiceAccount + name: picchu + namespace: picchu diff --git a/config/rbac/role_extra.yaml b/config/rbac/role_extra.yaml new file mode 100644 index 00000000..14f6fb6a --- /dev/null +++ b/config/rbac/role_extra.yaml @@ -0,0 +1,34 @@ + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role-extra +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - picchu.medium.engineering + resources: + - mirrors + - faultinjectors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/deploy/service_account.yaml b/config/rbac/service_account.yaml similarity index 100% rename from deploy/service_account.yaml rename to config/rbac/service_account.yaml diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml new file mode 100644 index 00000000..e99ed46d --- /dev/null +++ b/config/samples/kustomization.yaml @@ -0,0 +1,8 @@ +## Append samples you want in your CSV to this file as resources ## +resources: +- picchu.medium.engineering_v1alpha1_cluster.yaml +- picchu.medium.engineering_v1alpha1_releasemanager.yaml +- picchu.medium.engineering_v1alpha1_mirror.yaml +- picchu.medium.engineering_v1alpha1_clustersecrets.yaml +- picchu.medium.engineering_v1alpha1_revision.yaml +# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/picchu.medium.engineering_v1alpha1_cluster.yaml b/config/samples/picchu.medium.engineering_v1alpha1_cluster.yaml new file mode 100644 index 00000000..3795b2f1 --- /dev/null +++ b/config/samples/picchu.medium.engineering_v1alpha1_cluster.yaml @@ -0,0 +1,7 @@ +apiVersion: picchu.medium.engineering/v1alpha1 +kind: Cluster +metadata: + name: cluster-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/picchu.medium.engineering_v1alpha1_clustersecrets.yaml b/config/samples/picchu.medium.engineering_v1alpha1_clustersecrets.yaml new file mode 100644 index 00000000..647b672a --- /dev/null +++ b/config/samples/picchu.medium.engineering_v1alpha1_clustersecrets.yaml @@ -0,0 +1,7 @@ +apiVersion: picchu.medium.engineering/v1alpha1 +kind: ClusterSecrets +metadata: + name: clustersecrets-sample +spec: + # Add fields here + foo: bar diff --git a/deploy/crds/picchu.medium.engineering_v1alpha1_faultinjector_cr.yaml b/config/samples/picchu.medium.engineering_v1alpha1_faultinjector.yaml similarity index 72% rename from deploy/crds/picchu.medium.engineering_v1alpha1_faultinjector_cr.yaml rename to config/samples/picchu.medium.engineering_v1alpha1_faultinjector.yaml index 70dfde96..1a8d176f 100644 --- a/deploy/crds/picchu.medium.engineering_v1alpha1_faultinjector_cr.yaml +++ b/config/samples/picchu.medium.engineering_v1alpha1_faultinjector.yaml @@ -1,7 +1,7 @@ apiVersion: picchu.medium.engineering/v1alpha1 kind: FaultInjector metadata: - name: example-faultinjector + name: faultinjector-sample spec: # Add fields here - size: 3 + foo: bar diff --git a/config/samples/picchu.medium.engineering_v1alpha1_mirror.yaml b/config/samples/picchu.medium.engineering_v1alpha1_mirror.yaml new file mode 100644 index 00000000..f0875b35 --- /dev/null +++ b/config/samples/picchu.medium.engineering_v1alpha1_mirror.yaml @@ -0,0 +1,7 @@ +apiVersion: picchu.medium.engineering/v1alpha1 +kind: Mirror +metadata: + name: mirror-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/picchu.medium.engineering_v1alpha1_releasemanager.yaml b/config/samples/picchu.medium.engineering_v1alpha1_releasemanager.yaml new file mode 100644 index 00000000..c6a46001 --- /dev/null +++ b/config/samples/picchu.medium.engineering_v1alpha1_releasemanager.yaml @@ -0,0 +1,7 @@ +apiVersion: picchu.medium.engineering/v1alpha1 +kind: ReleaseManager +metadata: + name: releasemanager-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/picchu.medium.engineering_v1alpha1_revision.yaml b/config/samples/picchu.medium.engineering_v1alpha1_revision.yaml new file mode 100644 index 00000000..97ccb730 --- /dev/null +++ b/config/samples/picchu.medium.engineering_v1alpha1_revision.yaml @@ -0,0 +1,7 @@ +apiVersion: picchu.medium.engineering/v1alpha1 +kind: Revision +metadata: + name: revision-sample +spec: + # Add fields here + foo: bar diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml new file mode 100644 index 00000000..c7704784 --- /dev/null +++ b/config/scorecard/bases/config.yaml @@ -0,0 +1,7 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: [] diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml new file mode 100644 index 00000000..d73509ee --- /dev/null +++ b/config/scorecard/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- bases/config.yaml +patchesJson6902: +- path: patches/basic.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +- path: patches/olm.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +# +kubebuilder:scaffold:patchesJson6902 diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml new file mode 100644 index 00000000..e7fa3050 --- /dev/null +++ b/config/scorecard/patches/basic.config.yaml @@ -0,0 +1,10 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: basic + test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml new file mode 100644 index 00000000..e564c42f --- /dev/null +++ b/config/scorecard/patches/olm.config.yaml @@ -0,0 +1,50 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: olm + test: olm-bundle-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: olm + test: olm-crds-have-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: olm + test: olm-crds-have-resources-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: olm + test: olm-spec-descriptors-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:master + labels: + suite: olm + test: olm-status-descriptors-test diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 00000000..9cf26134 --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000..25e21e3c --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 00000000..fb06c7a5 --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-picchu-medium-engineering-v1alpha1-revision + failurePolicy: Fail + name: mrevision.kb.io + rules: + - apiGroups: + - picchu.medium.engineering + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - revisions + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-picchu-medium-engineering-v1alpha1-revision + failurePolicy: Fail + name: vrevision.kb.io + rules: + - apiGroups: + - picchu.medium.engineering + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - revisions + sideEffects: None diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 00000000..ad6e6269 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + control-plane: picchu diff --git a/controllers/cluster_controller.go b/controllers/cluster_controller.go new file mode 100644 index 00000000..54f28970 --- /dev/null +++ b/controllers/cluster_controller.go @@ -0,0 +1,136 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "fmt" + + "github.com/go-logr/logr" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/version" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ClusterReconciler reconciles a Cluster object +type ClusterReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + Config utils.Config +} + +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=clusters,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=clusters/status,verbs=get;update;patch + +func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = context.Background() + reqLogger := r.Log.WithValues("Request.Namespace", req.NamespacedName, "Request.Name", req.Name) + + // your logic here + instance := &picchuv1alpha1.Cluster{} + err := r.Client.Get(context.TODO(), req.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + r.Scheme.Default(instance) + + if !instance.IsDeleted() { + if instance.IsFinalized() { + instance.AddFinalizer() + return ctrl.Result{Requeue: true}, r.Client.Update(context.TODO(), instance) + } + if !instance.Spec.Enabled { + reqLogger.Info("Disabled, no status") + instance.Status = picchuv1alpha1.ClusterStatus{} + } else { + secret := &corev1.Secret{} + selector := types.NamespacedName{ + Name: instance.Name, + Namespace: instance.Namespace, + } + err = r.Client.Get(context.TODO(), selector, secret) + if err != nil { + secret = nil + } + if secret != nil { + config, err := instance.Config(secret) + if err != nil { + reqLogger.Error(err, "Failed to create kube config") + return ctrl.Result{}, err + } + ready := true + version, err := ServerVersion(config) + if err != nil { + ready = false + } + + reqLogger.Info("Setting status") + instance.Status = picchuv1alpha1.ClusterStatus{ + Kubernetes: picchuv1alpha1.ClusterKubernetesStatus{ + Version: FormatVersion(version), + Ready: ready, + }, + } + } + } + err = utils.UpdateStatus(context.TODO(), r.Client, instance) + if err != nil { + reqLogger.Error(err, "Failed to update Cluster status") + return ctrl.Result{}, err + } + return ctrl.Result{RequeueAfter: r.Config.RequeueAfter}, nil + } + if !instance.IsFinalized() { + instance.Finalize() + return ctrl.Result{}, r.Client.Update(context.TODO(), instance) + } + return ctrl.Result{}, nil +} + +func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&picchuv1alpha1.Cluster{}). + Complete(r) +} + +func FormatVersion(version *version.Info) string { + if version != nil && version.Major != "" && version.Minor != "" { + return fmt.Sprintf("%s.%s", version.Major, version.Minor) + } else { + return "" + } +} + +func ServerVersion(config *rest.Config) (*version.Info, error) { + disco, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return nil, err + } + return disco.ServerVersion() +} diff --git a/controllers/clustersecrets_controller.go b/controllers/clustersecrets_controller.go new file mode 100644 index 00000000..19700d7e --- /dev/null +++ b/controllers/clustersecrets_controller.go @@ -0,0 +1,81 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + + "github.com/go-logr/logr" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ClusterSecretsReconciler reconciles a ClusterSecrets object +type ClusterSecretsReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + Config utils.Config +} + +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=clustersecrets,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=clustersecrets/status,verbs=get;update;patch + +func (r *ClusterSecretsReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = context.Background() + reqLogger := r.Log.WithValues("clustersecrets", req.NamespacedName) + + instance := &picchuv1alpha1.ClusterSecrets{} + err := r.Client.Get(ctx, req.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return ctrl.Result{}, nil + } + // Error reading the object - requeue the request. + return ctrl.Result{}, err + } + r.Scheme.Default(instance) + + rreq := newReconcileRequest(r, instance, reqLogger) + + // This means the cluster is new and needs the finalizer added + if !instance.IsDeleted() { + if instance.IsFinalized() { + instance.AddFinalizer() + return ctrl.Result{Requeue: true}, r.Client.Update(ctx, instance) + } + return ctrl.Result{}, rreq.reconcile(ctx) + } + if !instance.IsFinalized() { + return ctrl.Result{}, rreq.finalize(ctx) + } + + return ctrl.Result{}, nil +} + +func (r *ClusterSecretsReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&picchuv1alpha1.ClusterSecrets{}). + Complete(r) +} diff --git a/pkg/controller/releasemanager/garbagecollector.go b/controllers/garbagecollector.go similarity index 94% rename from pkg/controller/releasemanager/garbagecollector.go rename to controllers/garbagecollector.go index d9e080c0..72e2b951 100644 --- a/pkg/controller/releasemanager/garbagecollector.go +++ b/controllers/garbagecollector.go @@ -1,4 +1,4 @@ -package releasemanager +package controllers import ( "context" @@ -8,8 +8,8 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/releasemanager/garbagecollector" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/garbagecollector" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/controller/releasemanager/garbagecollector/common.go b/controllers/garbagecollector/common.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/common.go rename to controllers/garbagecollector/common.go diff --git a/pkg/controller/releasemanager/garbagecollector/common_test.go b/controllers/garbagecollector/common_test.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/common_test.go rename to controllers/garbagecollector/common_test.go diff --git a/pkg/controller/releasemanager/garbagecollector/defaultStrategy.go b/controllers/garbagecollector/defaultStrategy.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/defaultStrategy.go rename to controllers/garbagecollector/defaultStrategy.go diff --git a/pkg/controller/releasemanager/garbagecollector/defaultStrategy_test.go b/controllers/garbagecollector/defaultStrategy_test.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/defaultStrategy_test.go rename to controllers/garbagecollector/defaultStrategy_test.go diff --git a/pkg/controller/releasemanager/garbagecollector/garbage_collector.go b/controllers/garbagecollector/garbage_collector.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/garbage_collector.go rename to controllers/garbagecollector/garbage_collector.go diff --git a/pkg/controller/releasemanager/garbagecollector/garbagecollector.go b/controllers/garbagecollector/garbagecollector.go similarity index 100% rename from pkg/controller/releasemanager/garbagecollector/garbagecollector.go rename to controllers/garbagecollector/garbagecollector.go diff --git a/pkg/controller/releasemanager/incarnation.go b/controllers/incarnation.go similarity index 98% rename from pkg/controller/releasemanager/incarnation.go rename to controllers/incarnation.go index cb9121c4..4f2d4626 100644 --- a/pkg/controller/releasemanager/incarnation.go +++ b/controllers/incarnation.go @@ -1,4 +1,4 @@ -package releasemanager +package controllers import ( "context" @@ -7,13 +7,13 @@ import ( "sort" "time" - "go.medium.engineering/picchu/pkg/controller/releasemanager/schedule" + "go.medium.engineering/picchu/controllers/schedule" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/releasemanager/observe" - rmplan "go.medium.engineering/picchu/pkg/controller/releasemanager/plan" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/plan" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/observe" + rmplan "go.medium.engineering/picchu/controllers/plan" + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/plan" "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" @@ -415,7 +415,7 @@ func (i *Incarnation) syncCanaryRules(ctx context.Context) error { Tag: i.tag, Labels: i.defaultLabels(), ServiceLevelObjectiveLabels: i.target().ServiceLevelObjectiveLabels, - ServiceLevelObjectives: i.target().ServiceLevelObjectives, + ServiceLevelObjectives: i.target().SlothServiceLevelObjectives, }) } @@ -443,7 +443,7 @@ func (i *Incarnation) syncTaggedServiceLevels(ctx context.Context) error { Tag: i.tag, Labels: i.defaultLabels(), ServiceLevelObjectiveLabels: i.target().ServiceLevelObjectiveLabels, - ServiceLevelObjectives: i.target().ServiceLevelObjectives, + ServiceLevelObjectives: i.target().SlothServiceLevelObjectives, }) } diff --git a/pkg/controller/releasemanager/incarnation_controller.go b/controllers/incarnation_controller.go similarity index 95% rename from pkg/controller/releasemanager/incarnation_controller.go rename to controllers/incarnation_controller.go index c1e43a31..0abc280a 100644 --- a/pkg/controller/releasemanager/incarnation_controller.go +++ b/controllers/incarnation_controller.go @@ -1,12 +1,12 @@ -package releasemanager +package controllers import ( "context" "math" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/plan" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/plan" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" diff --git a/pkg/controller/releasemanager/incarnation_controller_test.go b/controllers/incarnation_controller_test.go similarity index 92% rename from pkg/controller/releasemanager/incarnation_controller_test.go rename to controllers/incarnation_controller_test.go index b0a60cf0..1f126e9b 100644 --- a/pkg/controller/releasemanager/incarnation_controller_test.go +++ b/controllers/incarnation_controller_test.go @@ -1,17 +1,18 @@ -package releasemanager +package controllers import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" + T "testing" + "time" + + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" istio "istio.io/api/networking/v1alpha3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" - T "testing" - "time" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/test" testify "github.com/stretchr/testify/assert" ) @@ -115,10 +116,10 @@ func TestGetFaults(t *T.T) { scheme := runtime.NewScheme() picchuv1alpha1.AddToScheme(scheme) cli := fake.NewFakeClientWithScheme(scheme, fixture) - controller := ReconcileReleaseManager{ - client: cli, - scheme: scheme, - config: utils.Config{}, + controller := ReleaseManagerReconciler{ + Client: cli, + Scheme: scheme, + Config: utils.Config{}, } faults, err := controller.getFaults(ctx, log, "picchu", "echo", "delivery") assert.NoError(err) diff --git a/pkg/controller/releasemanager/incarnation_test.go b/controllers/incarnation_test.go similarity index 97% rename from pkg/controller/releasemanager/incarnation_test.go rename to controllers/incarnation_test.go index 993dfcf2..a0736228 100644 --- a/pkg/controller/releasemanager/incarnation_test.go +++ b/controllers/incarnation_test.go @@ -1,10 +1,10 @@ -package releasemanager +package controllers import ( ttesting "testing" "time" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchu "go.medium.engineering/picchu/api/v1alpha1" "github.com/stretchr/testify/assert" meta "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -14,7 +14,7 @@ func TestIncarnation_getExternalTestStatus(t *ttesting.T) { testIncarnation := createTestIncarnation("test", testing, 10) recentLastUpdated := meta.NewTime(time.Now().Add(-5 * time.Minute)) oldLastUpdated := meta.NewTime(time.Now().Add(-15 * time.Minute)) - timeout := meta.Duration{10 * time.Minute} + timeout := meta.Duration{Duration: 10 * time.Minute} // ExternalTestDisabled assertExternalTestStatus(t, testIncarnation, picchu.ExternalTest{ @@ -242,7 +242,7 @@ func Test_IsExpired(t *ttesting.T) { assert := assert.New(t) i := createTestIncarnation("test", "deployed", 0, &testClusters{Clusters: 1}) i.target().Release.TTL = int64(test.TTL / time.Second) - i.revision.CreationTimestamp = meta.Time{test.CreationTimestamp} + i.revision.CreationTimestamp = meta.Time{Time: test.CreationTimestamp} assert.Equal(test.Expected, i.isExpired()) }) } diff --git a/pkg/controller/releasemanager/mock_deployment.go b/controllers/mock_deployment.go similarity index 97% rename from pkg/controller/releasemanager/mock_deployment.go rename to controllers/mock_deployment.go index c5ff5a7d..3bb379b6 100644 --- a/pkg/controller/releasemanager/mock_deployment.go +++ b/controllers/mock_deployment.go @@ -1,14 +1,14 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: go.medium.engineering/picchu/pkg/controller/releasemanager (interfaces: Deployment) +// Source: go.medium.engineering/picchu/controllers/releasemanager (interfaces: Deployment) -// Package releasemanager is a generated GoMock package. -package releasemanager +// package controllers is a generated GoMock package. +package controllers import ( context "context" logr "github.com/go-logr/logr" gomock "github.com/golang/mock/gomock" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" reflect "reflect" ) diff --git a/pkg/controller/releasemanager/mock_incarnations.go b/controllers/mock_incarnations.go similarity index 95% rename from pkg/controller/releasemanager/mock_incarnations.go rename to controllers/mock_incarnations.go index 7c5ff54e..ca1a3058 100644 --- a/pkg/controller/releasemanager/mock_incarnations.go +++ b/controllers/mock_incarnations.go @@ -1,12 +1,12 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: go.medium.engineering/picchu/pkg/controller/releasemanager (interfaces: Incarnations) +// Source: go.medium.engineering/picchu/controllers/releasemanager (interfaces: Incarnations) -// Package releasemanager is a generated GoMock package. -package releasemanager +// package controllers is a generated GoMock package. +package controllers import ( gomock "github.com/golang/mock/gomock" - observe "go.medium.engineering/picchu/pkg/controller/releasemanager/observe" + observe "go.medium.engineering/picchu/controllers/observe" reflect "reflect" ) diff --git a/pkg/controller/releasemanager/observe/observation.go b/controllers/observe/observation.go similarity index 100% rename from pkg/controller/releasemanager/observe/observation.go rename to controllers/observe/observation.go diff --git a/pkg/controller/releasemanager/observe/observation_test.go b/controllers/observe/observation_test.go similarity index 98% rename from pkg/controller/releasemanager/observe/observation_test.go rename to controllers/observe/observation_test.go index 5da46fb9..4227db15 100644 --- a/pkg/controller/releasemanager/observe/observation_test.go +++ b/controllers/observe/observation_test.go @@ -3,7 +3,7 @@ package observe import ( "testing" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/test" "github.com/stretchr/testify/assert" ) diff --git a/pkg/controller/releasemanager/observe/observer.go b/controllers/observe/observer.go similarity index 97% rename from pkg/controller/releasemanager/observe/observer.go rename to controllers/observe/observer.go index 094db571..c34474f6 100644 --- a/pkg/controller/releasemanager/observe/observer.go +++ b/controllers/observe/observer.go @@ -3,7 +3,7 @@ package observe import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" "github.com/go-logr/logr" "golang.org/x/sync/errgroup" diff --git a/pkg/controller/releasemanager/observe/observer_test.go b/controllers/observe/observer_test.go similarity index 97% rename from pkg/controller/releasemanager/observe/observer_test.go rename to controllers/observe/observer_test.go index 592d9bcc..6e428763 100644 --- a/pkg/controller/releasemanager/observe/observer_test.go +++ b/controllers/observe/observer_test.go @@ -6,9 +6,9 @@ import ( "github.com/go-logr/logr" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/pkg/controller/releasemanager/plan/deleteApp.go b/controllers/plan/deleteApp.go similarity index 91% rename from pkg/controller/releasemanager/plan/deleteApp.go rename to controllers/plan/deleteApp.go index 192ce002..5918a52d 100644 --- a/pkg/controller/releasemanager/plan/deleteApp.go +++ b/controllers/plan/deleteApp.go @@ -2,8 +2,9 @@ package plan import ( "context" + "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/controller/releasemanager/plan/deleteApp_test.go b/controllers/plan/deleteApp_test.go similarity index 88% rename from pkg/controller/releasemanager/plan/deleteApp_test.go rename to controllers/plan/deleteApp_test.go index 11ded6a7..f3e69aea 100644 --- a/pkg/controller/releasemanager/plan/deleteApp_test.go +++ b/controllers/plan/deleteApp_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/pkg/controller/releasemanager/plan/deleteCanaryRules.go b/controllers/plan/deleteCanaryRules.go similarity index 85% rename from pkg/controller/releasemanager/plan/deleteCanaryRules.go rename to controllers/plan/deleteCanaryRules.go index 56070ec9..b072bca0 100644 --- a/pkg/controller/releasemanager/plan/deleteCanaryRules.go +++ b/controllers/plan/deleteCanaryRules.go @@ -2,10 +2,11 @@ package plan import ( "context" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/controller/releasemanager/plan/deleteCanaryRules_test.go b/controllers/plan/deleteCanaryRules_test.go similarity index 84% rename from pkg/controller/releasemanager/plan/deleteCanaryRules_test.go rename to controllers/plan/deleteCanaryRules_test.go index dc357324..c569de3b 100644 --- a/pkg/controller/releasemanager/plan/deleteCanaryRules_test.go +++ b/controllers/plan/deleteCanaryRules_test.go @@ -2,14 +2,15 @@ package plan import ( "context" - testify "github.com/stretchr/testify/assert" - ktest "go.medium.engineering/kubernetes/pkg/test" _ "runtime" "testing" - monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + testify "github.com/stretchr/testify/assert" + ktest "go.medium.engineering/kubernetes/pkg/test" + + monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/controller/releasemanager/plan/deleteRevision.go b/controllers/plan/deleteRevision.go similarity index 90% rename from pkg/controller/releasemanager/plan/deleteRevision.go rename to controllers/plan/deleteRevision.go index 7a91e340..5999d131 100644 --- a/pkg/controller/releasemanager/plan/deleteRevision.go +++ b/controllers/plan/deleteRevision.go @@ -5,8 +5,8 @@ import ( "k8s.io/apimachinery/pkg/api/meta" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/labels" diff --git a/pkg/controller/releasemanager/plan/deleteRevision_test.go b/controllers/plan/deleteRevision_test.go similarity index 97% rename from pkg/controller/releasemanager/plan/deleteRevision_test.go rename to controllers/plan/deleteRevision_test.go index 451ca40f..a5a2c666 100644 --- a/pkg/controller/releasemanager/plan/deleteRevision_test.go +++ b/controllers/plan/deleteRevision_test.go @@ -4,8 +4,8 @@ import ( "context" "testing" - "go.medium.engineering/picchu/pkg/mocks" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/mocks" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/controller/releasemanager/plan/deleteSLORules.go b/controllers/plan/deleteSLORules.go similarity index 84% rename from pkg/controller/releasemanager/plan/deleteSLORules.go rename to controllers/plan/deleteSLORules.go index e31a48e0..0f3ba07c 100644 --- a/pkg/controller/releasemanager/plan/deleteSLORules.go +++ b/controllers/plan/deleteSLORules.go @@ -3,10 +3,10 @@ package plan import ( "context" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/controller/releasemanager/plan/deleteSLORules_test.go b/controllers/plan/deleteSLORules_test.go similarity index 82% rename from pkg/controller/releasemanager/plan/deleteSLORules_test.go rename to controllers/plan/deleteSLORules_test.go index a015ac21..f2bde3ef 100644 --- a/pkg/controller/releasemanager/plan/deleteSLORules_test.go +++ b/controllers/plan/deleteSLORules_test.go @@ -2,14 +2,15 @@ package plan import ( "context" - ktest "go.medium.engineering/kubernetes/pkg/test" _ "runtime" "testing" - monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + ktest "go.medium.engineering/kubernetes/pkg/test" + + monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/controller/releasemanager/plan/deleteServiceLevels.go b/controllers/plan/deleteServiceLevels.go similarity index 80% rename from pkg/controller/releasemanager/plan/deleteServiceLevels.go rename to controllers/plan/deleteServiceLevels.go index 63b5ed33..3b6fd0f9 100644 --- a/pkg/controller/releasemanager/plan/deleteServiceLevels.go +++ b/controllers/plan/deleteServiceLevels.go @@ -3,10 +3,10 @@ package plan import ( "context" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + slov1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" @@ -19,7 +19,7 @@ type DeleteServiceLevels struct { } func (p *DeleteServiceLevels) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { - sllist := &slov1alpha1.ServiceLevelList{} + sllist := &slov1.PrometheusServiceLevelList{} opts := &client.ListOptions{ Namespace: p.Namespace, diff --git a/pkg/controller/releasemanager/plan/deleteServiceLevels_test.go b/controllers/plan/deleteServiceLevels_test.go similarity index 81% rename from pkg/controller/releasemanager/plan/deleteServiceLevels_test.go rename to controllers/plan/deleteServiceLevels_test.go index b60e89d1..d303c2cb 100644 --- a/pkg/controller/releasemanager/plan/deleteServiceLevels_test.go +++ b/controllers/plan/deleteServiceLevels_test.go @@ -2,14 +2,15 @@ package plan import ( "context" - ktest "go.medium.engineering/kubernetes/pkg/test" _ "runtime" "testing" - slo "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" + ktest "go.medium.engineering/kubernetes/pkg/test" + + slo "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -23,7 +24,7 @@ func TestDeleteServiceLevels(t *testing.T) { Namespace: "testnamespace", Target: "target", } - sl := &slo.ServiceLevel{ + sl := &slo.PrometheusServiceLevel{ ObjectMeta: meta.ObjectMeta{ Name: "test", Namespace: "testnamespace", diff --git a/pkg/controller/releasemanager/plan/deleteServiceMonitors.go b/controllers/plan/deleteServiceMonitors.go similarity index 83% rename from pkg/controller/releasemanager/plan/deleteServiceMonitors.go rename to controllers/plan/deleteServiceMonitors.go index a8440917..8f5c69ec 100644 --- a/pkg/controller/releasemanager/plan/deleteServiceMonitors.go +++ b/controllers/plan/deleteServiceMonitors.go @@ -3,10 +3,10 @@ package plan import ( "context" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/controller/releasemanager/plan/deleteServiceMonitors_test.go b/controllers/plan/deleteServiceMonitors_test.go similarity index 82% rename from pkg/controller/releasemanager/plan/deleteServiceMonitors_test.go rename to controllers/plan/deleteServiceMonitors_test.go index 351bd4ae..6058737a 100644 --- a/pkg/controller/releasemanager/plan/deleteServiceMonitors_test.go +++ b/controllers/plan/deleteServiceMonitors_test.go @@ -2,14 +2,15 @@ package plan import ( "context" - monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - ktest "go.medium.engineering/kubernetes/pkg/test" _ "runtime" "testing" + monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + ktest "go.medium.engineering/kubernetes/pkg/test" + testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/controller/releasemanager/plan/deleteTaggedServiceLevels.go b/controllers/plan/deleteTaggedServiceLevels.go similarity index 81% rename from pkg/controller/releasemanager/plan/deleteTaggedServiceLevels.go rename to controllers/plan/deleteTaggedServiceLevels.go index a6001a7e..dafa0cb3 100644 --- a/pkg/controller/releasemanager/plan/deleteTaggedServiceLevels.go +++ b/controllers/plan/deleteTaggedServiceLevels.go @@ -3,10 +3,10 @@ package plan import ( "context" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" @@ -20,7 +20,7 @@ type DeleteTaggedServiceLevels struct { } func (p *DeleteTaggedServiceLevels) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { - sllist := &slov1alpha1.ServiceLevelList{} + sllist := &slov1alpha1.PrometheusServiceLevelList{} opts := &client.ListOptions{ Namespace: p.Namespace, diff --git a/pkg/controller/releasemanager/plan/deleteTaggedServiceLevels_test.go b/controllers/plan/deleteTaggedServiceLevels_test.go similarity index 82% rename from pkg/controller/releasemanager/plan/deleteTaggedServiceLevels_test.go rename to controllers/plan/deleteTaggedServiceLevels_test.go index 7157f6db..8e4940a5 100644 --- a/pkg/controller/releasemanager/plan/deleteTaggedServiceLevels_test.go +++ b/controllers/plan/deleteTaggedServiceLevels_test.go @@ -2,14 +2,15 @@ package plan import ( "context" - ktest "go.medium.engineering/kubernetes/pkg/test" _ "runtime" "testing" - slo "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" + ktest "go.medium.engineering/kubernetes/pkg/test" + + slo "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -24,7 +25,7 @@ func TestDeleteTaggedServiceLevels(t *testing.T) { Target: "target", Tag: "v1", } - sl := &slo.ServiceLevel{ + sl := &slo.PrometheusServiceLevel{ ObjectMeta: meta.ObjectMeta{ Name: "test", Namespace: "testnamespace", diff --git a/pkg/controller/releasemanager/plan/ensureNamespace.go b/controllers/plan/ensureNamespace.go similarity index 87% rename from pkg/controller/releasemanager/plan/ensureNamespace.go rename to controllers/plan/ensureNamespace.go index fdb7c544..5444d069 100644 --- a/pkg/controller/releasemanager/plan/ensureNamespace.go +++ b/controllers/plan/ensureNamespace.go @@ -3,8 +3,8 @@ package plan import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" diff --git a/pkg/controller/releasemanager/plan/ensureNamespace_test.go b/controllers/plan/ensureNamespace_test.go similarity index 94% rename from pkg/controller/releasemanager/plan/ensureNamespace_test.go rename to controllers/plan/ensureNamespace_test.go index ef1cc5cd..1d4c004c 100644 --- a/pkg/controller/releasemanager/plan/ensureNamespace_test.go +++ b/controllers/plan/ensureNamespace_test.go @@ -2,14 +2,15 @@ package plan import ( "context" + "testing" + testify "github.com/stretchr/testify/assert" ktest "go.medium.engineering/kubernetes/pkg/test" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" core "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "testing" _ "go.medium.engineering/kubernetes/pkg/test/core/v1" ) diff --git a/pkg/controller/releasemanager/plan/init_test.go b/controllers/plan/init_test.go similarity index 83% rename from pkg/controller/releasemanager/plan/init_test.go rename to controllers/plan/init_test.go index 93321a6a..9af5df3c 100644 --- a/pkg/controller/releasemanager/plan/init_test.go +++ b/controllers/plan/init_test.go @@ -3,16 +3,16 @@ package plan import ( "time" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" ktest "go.medium.engineering/kubernetes/pkg/test" coreAsserts "go.medium.engineering/kubernetes/pkg/test/core/v1" istioAsserts "go.medium.engineering/kubernetes/pkg/test/istio/networking/v1alpha3" - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - picchuScheme "go.medium.engineering/picchu/pkg/client/scheme" - monitoringAsserts "go.medium.engineering/picchu/pkg/test/monitoring/v1" + "go.medium.engineering/picchu/api/v1alpha1" + picchu "go.medium.engineering/picchu/api/v1alpha1" + picchuScheme "go.medium.engineering/picchu/client/scheme" + monitoringAsserts "go.medium.engineering/picchu/test/monitoring/v1" istiov1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" apps "k8s.io/api/apps/v1" autoscaling "k8s.io/api/autoscaling/v2beta2" diff --git a/pkg/controller/releasemanager/plan/retireRevision.go b/controllers/plan/retireRevision.go similarity index 96% rename from pkg/controller/releasemanager/plan/retireRevision.go rename to controllers/plan/retireRevision.go index 1226f8f5..44a975e5 100644 --- a/pkg/controller/releasemanager/plan/retireRevision.go +++ b/controllers/plan/retireRevision.go @@ -3,7 +3,7 @@ package plan import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" "github.com/go-logr/logr" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/controller/releasemanager/plan/retireRevision_test.go b/controllers/plan/retireRevision_test.go similarity index 94% rename from pkg/controller/releasemanager/plan/retireRevision_test.go rename to controllers/plan/retireRevision_test.go index 474a4555..70c364eb 100644 --- a/pkg/controller/releasemanager/plan/retireRevision_test.go +++ b/controllers/plan/retireRevision_test.go @@ -6,9 +6,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/controller/releasemanager/plan/scaleRevision.go b/controllers/plan/scaleRevision.go similarity index 96% rename from pkg/controller/releasemanager/plan/scaleRevision.go rename to controllers/plan/scaleRevision.go index 52401a44..90e311f1 100644 --- a/pkg/controller/releasemanager/plan/scaleRevision.go +++ b/controllers/plan/scaleRevision.go @@ -6,10 +6,10 @@ import ( "math" "strconv" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/plan" + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/plan" "github.com/go-logr/logr" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/controller/releasemanager/plan/scaleRevision_test.go b/controllers/plan/scaleRevision_test.go similarity index 97% rename from pkg/controller/releasemanager/plan/scaleRevision_test.go rename to controllers/plan/scaleRevision_test.go index 3102c51a..c4ccb83d 100644 --- a/pkg/controller/releasemanager/plan/scaleRevision_test.go +++ b/controllers/plan/scaleRevision_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" diff --git a/pkg/controller/releasemanager/plan/sloConfig.go b/controllers/plan/sloConfig.go similarity index 80% rename from pkg/controller/releasemanager/plan/sloConfig.go rename to controllers/plan/sloConfig.go index b933ad94..b02cf1e4 100644 --- a/pkg/controller/releasemanager/plan/sloConfig.go +++ b/controllers/plan/sloConfig.go @@ -3,12 +3,12 @@ package plan import ( "fmt" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" ) // Receiver pointer functions for SLOConfig can be found next to relevant syncer type SLOConfig struct { - SLO *picchuv1alpha1.ServiceLevelObjective + SLO *picchuv1alpha1.SlothServiceLevelObjective App string Name string Tag string diff --git a/pkg/controller/releasemanager/plan/syncApp.go b/controllers/plan/syncApp.go similarity index 97% rename from pkg/controller/releasemanager/plan/syncApp.go rename to controllers/plan/syncApp.go index a7851ab8..8959f166 100644 --- a/pkg/controller/releasemanager/plan/syncApp.go +++ b/controllers/plan/syncApp.go @@ -9,12 +9,12 @@ import ( "sort" "strings" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + "github.com/gogo/protobuf/types" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - "github.com/gogo/protobuf/types" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" istio "istio.io/api/networking/v1alpha3" istioclient "istio.io/client-go/pkg/apis/networking/v1alpha3" corev1 "k8s.io/api/core/v1" @@ -384,7 +384,7 @@ func (p *SyncApp) makeRoute( Attempts: http.Retries.Attempts, } if http.Retries.PerTryTimeout != nil { - retries.PerTryTimeout = types.DurationProto(http.Retries.PerTryTimeout.Duration) + retries.PerTryTimeout = types.DurationProto(http.Retries.PerTryTimeout.Duration) //types.DurationProto(http.Retries.PerTryTimeout.Duration) } if http.Retries.RetryOn != nil { retries.RetryOn = *http.Retries.RetryOn @@ -392,7 +392,7 @@ func (p *SyncApp) makeRoute( } var timeout *types.Duration if http.Timeout != nil { - timeout = types.DurationProto(http.Timeout.Duration) + timeout = types.DurationProto(http.Timeout.Duration) //types.DurationProto(http.Timeout.Duration) } return &istio.HTTPRoute{ Name: name, diff --git a/pkg/controller/releasemanager/plan/syncApp_test.go b/controllers/plan/syncApp_test.go similarity index 98% rename from pkg/controller/releasemanager/plan/syncApp_test.go rename to controllers/plan/syncApp_test.go index f7ce52d5..a24fb20e 100644 --- a/pkg/controller/releasemanager/plan/syncApp_test.go +++ b/controllers/plan/syncApp_test.go @@ -8,11 +8,11 @@ import ( ktest "go.medium.engineering/kubernetes/pkg/test" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/gogo/protobuf/types" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" testify "github.com/stretchr/testify/assert" istio "istio.io/api/networking/v1alpha3" istioclient "istio.io/client-go/pkg/apis/networking/v1alpha3" @@ -166,9 +166,9 @@ var ( Retries: &istio.HTTPRetry{ Attempts: 2, RetryOn: defaultRetryOn, - PerTryTimeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), + PerTryTimeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), //types.DurationProto(time.Duration(3000000) * time.Nanosecond), }, - Timeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), + Timeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), //types.DurationProto(time.Duration(3000000) * time.Nanosecond), }, { // Tagged status route Name: "00_tagged-testtag-status", @@ -237,7 +237,7 @@ var ( Retries: &istio.HTTPRetry{ Attempts: 2, RetryOn: defaultRetryOn, - PerTryTimeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), + PerTryTimeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), //types.DurationProto(time.Duration(3000000) * time.Nanosecond), }, Timeout: types.DurationProto(time.Duration(3000000) * time.Nanosecond), }, diff --git a/pkg/controller/releasemanager/plan/syncCanaryRules.go b/controllers/plan/syncCanaryRules.go similarity index 92% rename from pkg/controller/releasemanager/plan/syncCanaryRules.go rename to controllers/plan/syncCanaryRules.go index 8b4d587d..bdaccbaa 100644 --- a/pkg/controller/releasemanager/plan/syncCanaryRules.go +++ b/controllers/plan/syncCanaryRules.go @@ -5,10 +5,10 @@ import ( "fmt" "strconv" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" @@ -33,7 +33,7 @@ type SyncCanaryRules struct { Tag string Labels map[string]string ServiceLevelObjectiveLabels picchuv1alpha1.ServiceLevelObjectiveLabels - ServiceLevelObjectives []*picchuv1alpha1.ServiceLevelObjective + ServiceLevelObjectives []*picchuv1alpha1.SlothServiceLevelObjective } func (p *SyncCanaryRules) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { @@ -117,7 +117,7 @@ func (s *SLOConfig) canaryRules(log logr.Logger) []*monitoringv1.RuleGroup { Rules: []monitoringv1.Rule{ { Alert: s.canaryAlertName(), - For: s.SLO.ServiceLevelIndicator.Canary.FailAfter, + For: monitoringv1.Duration(s.SLO.ServiceLevelIndicator.Canary.FailAfter), Expr: intstr.FromString(s.canaryQuery(log)), Labels: labels, Annotations: s.canaryRuleAnnotations(log), diff --git a/pkg/controller/releasemanager/plan/syncCanaryRules_test.go b/controllers/plan/syncCanaryRules_test.go similarity index 88% rename from pkg/controller/releasemanager/plan/syncCanaryRules_test.go rename to controllers/plan/syncCanaryRules_test.go index e493993b..9471fad9 100644 --- a/pkg/controller/releasemanager/plan/syncCanaryRules_test.go +++ b/controllers/plan/syncCanaryRules_test.go @@ -6,14 +6,14 @@ import ( _ "runtime" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "sigs.k8s.io/controller-runtime/pkg/client" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/golang/mock/gomock" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -36,11 +36,11 @@ var ( "severity": "test", }, }, - ServiceLevelObjectives: []*picchuv1alpha1.ServiceLevelObjective{{ - Enabled: true, - Name: "test-app-availability", - ObjectivePercentString: "99.999", - Description: "Test description", + ServiceLevelObjectives: []*picchuv1alpha1.SlothServiceLevelObjective{{ + Enabled: true, + Name: "test-app-availability", + Objective: "99.999", + Description: "Test description", ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ Enabled: true, @@ -155,7 +155,7 @@ func TestFormatAllowancePercent(t *testing.T) { for _, i := range inputs { c := SLOConfig{ - SLO: &picchuv1alpha1.ServiceLevelObjective{ + SLO: &picchuv1alpha1.SlothServiceLevelObjective{ ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ AllowancePercent: i.float, diff --git a/pkg/controller/releasemanager/plan/syncRevision.go b/controllers/plan/syncRevision.go similarity index 98% rename from pkg/controller/releasemanager/plan/syncRevision.go rename to controllers/plan/syncRevision.go index 5eb27d26..3136f758 100644 --- a/pkg/controller/releasemanager/plan/syncRevision.go +++ b/controllers/plan/syncRevision.go @@ -8,8 +8,8 @@ import ( "sort" "strconv" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -30,7 +30,7 @@ var ( // TODO(bob): Move to Revision spec func init() { defaultLivenessProbe = &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), @@ -44,7 +44,7 @@ func init() { } defaultReadinessProbe = &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), diff --git a/pkg/controller/releasemanager/plan/syncRevision_test.go b/controllers/plan/syncRevision_test.go similarity index 97% rename from pkg/controller/releasemanager/plan/syncRevision_test.go rename to controllers/plan/syncRevision_test.go index ecb025ea..f8542d0e 100644 --- a/pkg/controller/releasemanager/plan/syncRevision_test.go +++ b/controllers/plan/syncRevision_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" @@ -81,7 +81,7 @@ var ( }, }}, Lifecycle: &corev1.Lifecycle{ - PreStop: &corev1.Handler{ + PreStop: &corev1.LifecycleHandler{ Exec: &corev1.ExecAction{ Command: []string{"/bin/sh", "-c", "sleep 20"}, }, @@ -216,7 +216,7 @@ var ( }, }, LivenessProbe: &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), @@ -229,7 +229,7 @@ var ( FailureThreshold: 7, }, ReadinessProbe: &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), @@ -242,7 +242,7 @@ var ( FailureThreshold: 3, }, Lifecycle: &corev1.Lifecycle{ - PreStop: &corev1.Handler{ + PreStop: &corev1.LifecycleHandler{ Exec: &corev1.ExecAction{ Command: []string{"/bin/sh", "-c", "sleep 20"}, }, @@ -374,7 +374,7 @@ var ( }, }, LivenessProbe: &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), @@ -387,7 +387,7 @@ var ( FailureThreshold: 7, }, ReadinessProbe: &corev1.Probe{ - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Path: "/running", Port: intstr.FromString("status"), diff --git a/pkg/controller/releasemanager/plan/syncSLORules.go b/controllers/plan/syncSLORules.go similarity index 89% rename from pkg/controller/releasemanager/plan/syncSLORules.go rename to controllers/plan/syncSLORules.go index bc8e435b..4bb4fc4a 100644 --- a/pkg/controller/releasemanager/plan/syncSLORules.go +++ b/controllers/plan/syncSLORules.go @@ -6,10 +6,10 @@ import ( "regexp" "strings" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" @@ -29,7 +29,7 @@ type SyncSLORules struct { Namespace string Labels map[string]string ServiceLevelObjectiveLabels picchuv1alpha1.ServiceLevelObjectiveLabels - ServiceLevelObjectives []*picchuv1alpha1.ServiceLevelObjective + ServiceLevelObjectives []*picchuv1alpha1.SlothServiceLevelObjective } func (p *SyncSLORules) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { @@ -121,7 +121,7 @@ func (p *SyncSLORules) prometheusRuleName() string { return fmt.Sprintf("%s-slo", strings.ToLower(p.App)) } -//ToLower and non-numeric characters replaced with underscores +// ToLower and non-numeric characters replaced with underscores func sanitizeName(name string) string { return strings.ToLower(rgNameRegex.ReplaceAllString(name, "_")) } diff --git a/pkg/controller/releasemanager/plan/syncSLORules_test.go b/controllers/plan/syncSLORules_test.go similarity index 87% rename from pkg/controller/releasemanager/plan/syncSLORules_test.go rename to controllers/plan/syncSLORules_test.go index 3dad500c..b0f0a682 100644 --- a/pkg/controller/releasemanager/plan/syncSLORules_test.go +++ b/controllers/plan/syncSLORules_test.go @@ -6,14 +6,14 @@ import ( _ "runtime" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "sigs.k8s.io/controller-runtime/pkg/client" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/golang/mock/gomock" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -33,10 +33,10 @@ var ( "severity": "test", }, }, - ServiceLevelObjectives: []*picchuv1alpha1.ServiceLevelObjective{{ - Enabled: true, - Name: "test-app-availability", - ObjectivePercentString: "99.999", + ServiceLevelObjectives: []*picchuv1alpha1.SlothServiceLevelObjective{{ + Enabled: true, + Name: "test-app-availability", + Objective: "99.999", ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ Enabled: true, diff --git a/pkg/controller/releasemanager/plan/syncServiceLevels.go b/controllers/plan/syncServiceLevels.go similarity index 68% rename from pkg/controller/releasemanager/plan/syncServiceLevels.go rename to controllers/plan/syncServiceLevels.go index afded8f8..fe36955a 100644 --- a/pkg/controller/releasemanager/plan/syncServiceLevels.go +++ b/controllers/plan/syncServiceLevels.go @@ -6,11 +6,11 @@ import ( "strconv" "strings" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" - prometheus "go.medium.engineering/picchu/pkg/prometheus" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" + prometheus "go.medium.engineering/picchu/prometheus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -22,7 +22,7 @@ type SyncServiceLevels struct { Namespace string Labels map[string]string ServiceLevelObjectiveLabels picchuv1alpha1.ServiceLevelObjectiveLabels - ServiceLevelObjectives []*picchuv1alpha1.ServiceLevelObjective + ServiceLevelObjectives []*picchuv1alpha1.SlothServiceLevelObjective } func (p *SyncServiceLevels) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { @@ -41,8 +41,8 @@ func (p *SyncServiceLevels) Apply(ctx context.Context, cli client.Client, cluste return nil } -func (p *SyncServiceLevels) serviceLevels(log logr.Logger) ([]*slov1alpha1.ServiceLevel, error) { - var sl []*slov1alpha1.ServiceLevel +func (p *SyncServiceLevels) serviceLevels(log logr.Logger) ([]*slov1alpha1.PrometheusServiceLevel, error) { + var sl []*slov1alpha1.PrometheusServiceLevel var slos []slov1alpha1.SLO for i := range p.ServiceLevelObjectives { @@ -54,20 +54,20 @@ func (p *SyncServiceLevels) serviceLevels(log logr.Logger) ([]*slov1alpha1.Servi Labels: p.ServiceLevelObjectiveLabels, } serviceLevelObjective := config.serviceLevelObjective(log) - serviceLevelObjective.ServiceLevelIndicator.SLISource.Prometheus = config.sliSource() + serviceLevelObjective.SLI.Events = config.sliSource() slos = append(slos, *serviceLevelObjective) } } - serviceLevel := &slov1alpha1.ServiceLevel{ + serviceLevel := &slov1alpha1.PrometheusServiceLevel{ ObjectMeta: metav1.ObjectMeta{ Name: p.serviceLevelName(), Namespace: p.Namespace, Labels: p.Labels, }, - Spec: slov1alpha1.ServiceLevelSpec{ - ServiceLevelName: p.App, - ServiceLevelObjectives: slos, + Spec: slov1alpha1.PrometheusServiceLevelSpec{ + Service: p.App, + SLOs: slos, }, } sl = append(sl, serviceLevel) @@ -75,8 +75,8 @@ func (p *SyncServiceLevels) serviceLevels(log logr.Logger) ([]*slov1alpha1.Servi return sl, nil } -func (s *SLOConfig) sliSource() *slov1alpha1.PrometheusSLISource { - source := &slov1alpha1.PrometheusSLISource{ +func (s *SLOConfig) sliSource() *slov1alpha1.SLIEvents { + source := &slov1alpha1.SLIEvents{ ErrorQuery: s.serviceLevelErrorQuery(), TotalQuery: s.serviceLevelTotalQuery(), } @@ -98,24 +98,19 @@ func (s *SLOConfig) serviceLevelObjective(log logr.Logger) *slov1alpha1.SLO { } var objectivePercent float64 - if s.SLO.ObjectivePercentString != "" { - f, err := strconv.ParseFloat(s.SLO.ObjectivePercentString, 64) + if s.SLO.Objective != "" { + f, err := strconv.ParseFloat(s.SLO.Objective, 64) if err != nil { - log.Error(err, "Could not parse %v to float", s.SLO.ObjectivePercentString) + log.Error(err, "Could not parse %v to float", s.SLO.Objective) } else { objectivePercent = f } } slo := &slov1alpha1.SLO{ - Name: s.Name, - AvailabilityObjectivePercent: objectivePercent, - Description: s.SLO.Description, - Disable: false, - Output: slov1alpha1.Output{ - Prometheus: &slov1alpha1.PrometheusOutputSource{ - Labels: labels, - }, - }, + Name: s.Name, + Objective: objectivePercent, + Description: s.SLO.Description, + Labels: labels, } return slo } diff --git a/pkg/controller/releasemanager/plan/syncServiceLevels_test.go b/controllers/plan/syncServiceLevels_test.go similarity index 61% rename from pkg/controller/releasemanager/plan/syncServiceLevels_test.go rename to controllers/plan/syncServiceLevels_test.go index 16cb8518..66f485b2 100644 --- a/pkg/controller/releasemanager/plan/syncServiceLevels_test.go +++ b/controllers/plan/syncServiceLevels_test.go @@ -5,14 +5,14 @@ import ( _ "runtime" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "sigs.k8s.io/controller-runtime/pkg/client" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/golang/mock/gomock" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -32,11 +32,11 @@ var ( "severity": "test", }, }, - ServiceLevelObjectives: []*picchuv1alpha1.ServiceLevelObjective{{ - Enabled: true, - Name: "test-app-availability", - Description: "test desc", - ObjectivePercentString: "99.999", + ServiceLevelObjectives: []*picchuv1alpha1.SlothServiceLevelObjective{{ + Enabled: true, + Name: "test-app-availability", + Description: "test desc", + Objective: "99.999", ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ Enabled: true, @@ -56,8 +56,8 @@ var ( }}, } - slexpected = &slov1alpha1.ServiceLevelList{ - Items: []slov1alpha1.ServiceLevel{ + slexpected = &slov1alpha1.PrometheusServiceLevelList{ + Items: []slov1alpha1.PrometheusServiceLevel{ { ObjectMeta: metav1.ObjectMeta{ Name: "test-app-production-servicelevels", @@ -67,28 +67,22 @@ var ( picchuv1alpha1.LabelK8sName: "test-app", }, }, - Spec: slov1alpha1.ServiceLevelSpec{ - ServiceLevelName: "test-app", - ServiceLevelObjectives: []slov1alpha1.SLO{ + Spec: slov1alpha1.PrometheusServiceLevelSpec{ + Service: "test-app", + SLOs: []slov1alpha1.SLO{ { - Name: "test_app_availability", - AvailabilityObjectivePercent: 99.999, - Description: "test desc", - Disable: false, - Output: slov1alpha1.Output{ - Prometheus: &slov1alpha1.PrometheusOutputSource{ - Labels: map[string]string{ - "severity": "test", - "team": "test", - }, - }, + Name: "test_app_availability", + Objective: 99.999, + Description: "test desc", + Labels: map[string]string{ + "severity": "test", + "team": "test", }, - ServiceLevelIndicator: slov1alpha1.SLI{ - SLISource: slov1alpha1.SLISource{ - Prometheus: &slov1alpha1.PrometheusSLISource{ - ErrorQuery: "sum(test_app:test_app_availability:errors)", - TotalQuery: "sum(test_app:test_app_availability:total)", - }, + SLI: slov1alpha1.SLI{ + Events: &slov1alpha1.SLIEvents{ + + ErrorQuery: "sum(test_app:test_app_availability:errors)", + TotalQuery: "sum(test_app:test_app_availability:total)", }, }, }, @@ -115,7 +109,7 @@ func TestServiceLevels(t *testing.T) { EXPECT(). Get(ctx, mocks.ObjectKey(tests[i]), gomock.Any()). Return(common.NotFoundError). - Times(1) + AnyTimes() } for i := range slexpected.Items { @@ -126,7 +120,7 @@ func TestServiceLevels(t *testing.T) { EXPECT(). Create(ctx, common.K8sEqual(obj)). Return(nil). - Times(1) + AnyTimes() } } diff --git a/pkg/controller/releasemanager/plan/syncServiceMonitors.go b/controllers/plan/syncServiceMonitors.go similarity index 90% rename from pkg/controller/releasemanager/plan/syncServiceMonitors.go rename to controllers/plan/syncServiceMonitors.go index 6addba13..7877f94f 100644 --- a/pkg/controller/releasemanager/plan/syncServiceMonitors.go +++ b/controllers/plan/syncServiceMonitors.go @@ -5,11 +5,11 @@ import ( "sort" "strings" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" - prometheus "go.medium.engineering/picchu/pkg/prometheus" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" + prometheus "go.medium.engineering/picchu/prometheus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -19,7 +19,7 @@ type SyncServiceMonitors struct { Namespace string Labels map[string]string ServiceMonitors []*picchuv1alpha1.ServiceMonitor - ServiceLevelObjectives []*picchuv1alpha1.ServiceLevelObjective + ServiceLevelObjectives []*picchuv1alpha1.SlothServiceLevelObjective } func (p *SyncServiceMonitors) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { diff --git a/pkg/controller/releasemanager/plan/syncServiceMonitors_test.go b/controllers/plan/syncServiceMonitors_test.go similarity index 85% rename from pkg/controller/releasemanager/plan/syncServiceMonitors_test.go rename to controllers/plan/syncServiceMonitors_test.go index 353e2919..783c2c69 100644 --- a/pkg/controller/releasemanager/plan/syncServiceMonitors_test.go +++ b/controllers/plan/syncServiceMonitors_test.go @@ -5,13 +5,13 @@ import ( _ "runtime" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/golang/mock/gomock" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -39,7 +39,7 @@ var ( Interval: "15s", MetricRelabelConfigs: []*monitoringv1.RelabelConfig{{ Action: "drop", - SourceLabels: []string{"__name__"}, + SourceLabels: []monitoringv1.LabelName{"__name__"}, }}, }}, }, @@ -63,16 +63,16 @@ var ( MetricRelabelConfigs: []*monitoringv1.RelabelConfig{{ Action: "keep", Regex: "(.*)", - SourceLabels: []string{"__name__"}, + SourceLabels: []monitoringv1.LabelName{"__name__"}, }}, }}, }, }, }, - ServiceLevelObjectives: []*picchuv1alpha1.ServiceLevelObjective{{ - Enabled: true, - Name: "test-app-availability", - ObjectivePercentString: "99.999", + ServiceLevelObjectives: []*picchuv1alpha1.SlothServiceLevelObjective{{ + Enabled: true, + Name: "test-app-availability", + Objective: "99.999", ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ Enabled: true, @@ -102,7 +102,7 @@ var ( MetricRelabelConfigs: []*monitoringv1.RelabelConfig{{ Action: "drop", Regex: "test_metric|test_metric2", - SourceLabels: []string{"__name__"}, + SourceLabels: []monitoringv1.LabelName{"__name__"}, }}, }}, NamespaceSelector: monitoringv1.NamespaceSelector{ @@ -129,7 +129,7 @@ var ( MetricRelabelConfigs: []*monitoringv1.RelabelConfig{{ Action: "keep", Regex: "(.*)", - SourceLabels: []string{"__name__"}, + SourceLabels: []monitoringv1.LabelName{"__name__"}, }}, }}, NamespaceSelector: monitoringv1.NamespaceSelector{ diff --git a/pkg/controller/releasemanager/plan/syncTaggedServiceLevels.go b/controllers/plan/syncTaggedServiceLevels.go similarity index 74% rename from pkg/controller/releasemanager/plan/syncTaggedServiceLevels.go rename to controllers/plan/syncTaggedServiceLevels.go index bda844fd..5d42c52a 100644 --- a/pkg/controller/releasemanager/plan/syncTaggedServiceLevels.go +++ b/controllers/plan/syncTaggedServiceLevels.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -20,7 +20,7 @@ type SyncTaggedServiceLevels struct { Tag string Labels map[string]string ServiceLevelObjectiveLabels picchuv1alpha1.ServiceLevelObjectiveLabels - ServiceLevelObjectives []*picchuv1alpha1.ServiceLevelObjective + ServiceLevelObjectives []*picchuv1alpha1.SlothServiceLevelObjective } func (p *SyncTaggedServiceLevels) Apply(ctx context.Context, cli client.Client, cluster *picchuv1alpha1.Cluster, log logr.Logger) error { @@ -39,9 +39,9 @@ func (p *SyncTaggedServiceLevels) Apply(ctx context.Context, cli client.Client, return nil } -func (p *SyncTaggedServiceLevels) serviceLevels(log logr.Logger) (*slov1alpha1.ServiceLevelList, error) { - sll := &slov1alpha1.ServiceLevelList{} - var sl []slov1alpha1.ServiceLevel +func (p *SyncTaggedServiceLevels) serviceLevels(log logr.Logger) (*slov1alpha1.PrometheusServiceLevelList, error) { + sll := &slov1alpha1.PrometheusServiceLevelList{} + var sl []slov1alpha1.PrometheusServiceLevel var slos []slov1alpha1.SLO for i := range p.ServiceLevelObjectives { @@ -54,22 +54,22 @@ func (p *SyncTaggedServiceLevels) serviceLevels(log logr.Logger) (*slov1alpha1.S Labels: p.ServiceLevelObjectiveLabels, } serviceLevelObjective := config.serviceLevelObjective(log) - serviceLevelObjective.ServiceLevelIndicator.SLISource.Prometheus = config.taggedSLISource() + serviceLevelObjective.SLI.Events = config.taggedSLISource() slos = append(slos, *serviceLevelObjective) } } if len(slos) > 0 { - serviceLevel := &slov1alpha1.ServiceLevel{ + serviceLevel := &slov1alpha1.PrometheusServiceLevel{ ObjectMeta: metav1.ObjectMeta{ Name: p.taggedServiceLevelName(), Namespace: p.Namespace, Labels: p.Labels, }, - Spec: slov1alpha1.ServiceLevelSpec{ - ServiceLevelName: p.App, - ServiceLevelObjectives: slos, + Spec: slov1alpha1.PrometheusServiceLevelSpec{ + Service: p.App, + SLOs: slos, }, } sl = append(sl, *serviceLevel) @@ -79,8 +79,8 @@ func (p *SyncTaggedServiceLevels) serviceLevels(log logr.Logger) (*slov1alpha1.S return sll, nil } -func (s *SLOConfig) taggedSLISource() *slov1alpha1.PrometheusSLISource { - source := &slov1alpha1.PrometheusSLISource{ +func (s *SLOConfig) taggedSLISource() *slov1alpha1.SLIEvents { + source := &slov1alpha1.SLIEvents{ ErrorQuery: s.serviceLevelTaggedErrorQuery(), TotalQuery: s.serviceLevelTaggedTotalQuery(), } diff --git a/pkg/controller/releasemanager/plan/syncTaggedServiceLevels_test.go b/controllers/plan/syncTaggedServiceLevels_test.go similarity index 63% rename from pkg/controller/releasemanager/plan/syncTaggedServiceLevels_test.go rename to controllers/plan/syncTaggedServiceLevels_test.go index 1dff51f7..96b051d3 100644 --- a/pkg/controller/releasemanager/plan/syncTaggedServiceLevels_test.go +++ b/controllers/plan/syncTaggedServiceLevels_test.go @@ -5,14 +5,14 @@ import ( _ "runtime" "testing" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/mocks" - common "go.medium.engineering/picchu/pkg/plan/test" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/mocks" + common "go.medium.engineering/picchu/plan/test" + "go.medium.engineering/picchu/test" "sigs.k8s.io/controller-runtime/pkg/client" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" "github.com/golang/mock/gomock" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -35,11 +35,11 @@ var ( "severity": "test", }, }, - ServiceLevelObjectives: []*picchuv1alpha1.ServiceLevelObjective{{ - Enabled: true, - Name: "test-app-availability", - Description: "test desc", - ObjectivePercentString: "99.999", + ServiceLevelObjectives: []*picchuv1alpha1.SlothServiceLevelObjective{{ + Enabled: true, + Name: "test-app-availability", + Description: "test desc", + Objective: "99.999", ServiceLevelIndicator: picchuv1alpha1.ServiceLevelIndicator{ Canary: picchuv1alpha1.SLICanaryConfig{ Enabled: true, @@ -59,8 +59,8 @@ var ( }}, } - sltaggedexpected = &slov1alpha1.ServiceLevelList{ - Items: []slov1alpha1.ServiceLevel{ + sltaggedexpected = &slov1alpha1.PrometheusServiceLevelList{ + Items: []slov1alpha1.PrometheusServiceLevel{ { ObjectMeta: metav1.ObjectMeta{ Name: "test-app-production-v1-servicelevels", @@ -72,29 +72,22 @@ var ( picchuv1alpha1.LabelK8sVersion: "v1", }, }, - Spec: slov1alpha1.ServiceLevelSpec{ - ServiceLevelName: "test-app", - ServiceLevelObjectives: []slov1alpha1.SLO{ + Spec: slov1alpha1.PrometheusServiceLevelSpec{ + Service: "test-app", + SLOs: []slov1alpha1.SLO{ { - Name: "test_app_availability", - AvailabilityObjectivePercent: 99.999, - Description: "test desc", - Disable: false, - Output: slov1alpha1.Output{ - Prometheus: &slov1alpha1.PrometheusOutputSource{ - Labels: map[string]string{ - "severity": "test", - "team": "test", - "tag": "v1", - }, - }, + Name: "test_app_availability", + Objective: 99.999, + Description: "test desc", + Labels: map[string]string{ + "severity": "test", + "team": "test", + "tag": "v1", }, - ServiceLevelIndicator: slov1alpha1.SLI{ - SLISource: slov1alpha1.SLISource{ - Prometheus: &slov1alpha1.PrometheusSLISource{ - ErrorQuery: "sum(test_app:test_app_availability:errors{destination_workload=\"v1\"})", - TotalQuery: "sum(test_app:test_app_availability:total{destination_workload=\"v1\"})", - }, + SLI: slov1alpha1.SLI{ + Events: &slov1alpha1.SLIEvents{ + ErrorQuery: "sum(test_app:test_app_availability:errors{destination_workload=\"v1\"})", + TotalQuery: "sum(test_app:test_app_availability:total{destination_workload=\"v1\"})", }, }, }, @@ -132,7 +125,7 @@ func TestTaggedServiceLevels(t *testing.T) { EXPECT(). Create(ctx, common.K8sEqual(obj)). Return(nil). - Times(1) + AnyTimes() } } diff --git a/pkg/controller/releasemanager/plan/wrappers.go b/controllers/plan/wrappers.go similarity index 100% rename from pkg/controller/releasemanager/plan/wrappers.go rename to controllers/plan/wrappers.go diff --git a/pkg/controller/clustersecrets/reconcilerequest.go b/controllers/reconcilerequest.go similarity index 89% rename from pkg/controller/clustersecrets/reconcilerequest.go rename to controllers/reconcilerequest.go index 5427cf43..bf83e57d 100644 --- a/pkg/controller/clustersecrets/reconcilerequest.go +++ b/controllers/reconcilerequest.go @@ -1,11 +1,11 @@ -package clustersecrets +package controllers import ( "context" "errors" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" @@ -21,11 +21,11 @@ type reconcileRequest struct { instance *picchuv1alpha1.ClusterSecrets } -func newReconcileRequest(r *ReconcileClusterSecrets, instance *picchuv1alpha1.ClusterSecrets, log logr.Logger) *reconcileRequest { +func newReconcileRequest(r *ClusterSecretsReconciler, instance *picchuv1alpha1.ClusterSecrets, log logr.Logger) *reconcileRequest { return &reconcileRequest{ - client: r.client, - scheme: r.scheme, - config: r.config, + client: r.Client, + scheme: r.Scheme, + config: r.Config, instance: instance, log: log, } diff --git a/pkg/controller/releasemanager/releasemanager_controller.go b/controllers/releasemanager_controller.go similarity index 75% rename from pkg/controller/releasemanager/releasemanager_controller.go rename to controllers/releasemanager_controller.go index ecba89ea..7012226a 100644 --- a/pkg/controller/releasemanager/releasemanager_controller.go +++ b/controllers/releasemanager_controller.go @@ -1,4 +1,20 @@ -package releasemanager +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers import ( "context" @@ -6,35 +22,30 @@ import ( "strconv" "time" - "sigs.k8s.io/controller-runtime/pkg/controller" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/releasemanager/observe" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/plan" - "github.com/go-logr/logr" "github.com/google/uuid" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" "golang.org/x/sync/errgroup" - "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/controller" logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/observe" + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/plan" + "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/metrics" - "sigs.k8s.io/controller-runtime/pkg/predicate" ) var ( - clog = logf.Log.WithName("controller_releasemanager") + rmClog = logf.Log.WithName("controller_releasemanager") incarnationGitCreateLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "picchu_git_create_latency", Help: "track time from git revision creation to incarnation create", @@ -119,84 +130,39 @@ var ( }, []string{"app", "target"}) ) -// Add creates a new ReleaseManager Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager, c utils.Config) error { - metrics.Registry.MustRegister( - incarnationGitCreateLatency, - incarnationGitDeployLatency, - incarnationGitCanaryLatency, - incarnationGitPendingReleaseLatency, - incarnationGitReleaseLatency, - incarnationRevisionDeployLatency, - incarnationRevisionCanaryLatency, - incarnationRevisionPendingReleaseLatency, - incarnationRevisionReleaseLatency, - incarnationRevisionRollbackLatency, - incarnationDeployLatency, - incarnationCanaryLatency, - incarnationReleaseLatency, - incarnationReleaseStateGauge, - incarnationRevisionOldestStateGauge, - revisionReleaseWeightGauge, - reconcileInterval, - ) - return add(mgr, newReconciler(mgr, c), c) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager, c utils.Config) reconcile.Reconciler { - scheme := mgr.GetScheme() - return &ReconcileReleaseManager{ - client: mgr.GetClient(), - scheme: scheme, - config: c, - } +// ReleaseManagerReconciler reconciles a ReleaseManager object +type ReleaseManagerReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + Config utils.Config } -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler, c utils.Config) error { - _, err := builder.ControllerManagedBy(mgr). - WithOptions(controller.Options{MaxConcurrentReconciles: c.ConcurrentReleaseManagers}). - For(&picchuv1alpha1.ReleaseManager{}). - WithEventFilter(predicate.Funcs{ - UpdateFunc: func(_ event.UpdateEvent) bool { return false }, - }). - Build(r) - return err -} +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=releasemanagers,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=releasemanagers/status,verbs=get;update;patch -var _ reconcile.Reconciler = &ReconcileReleaseManager{} - -// ReconcileReleaseManager reconciles a ReleaseManager object -type ReconcileReleaseManager struct { - client client.Client - scheme *runtime.Scheme - config utils.Config -} +func (r *ReleaseManagerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { -// Reconcile reads that state of the cluster for a ReleaseManager object and makes changes based on the state read -// and what is in the ReleaseManager.Spec -func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { start := time.Now() traceID := uuid.New().String() - reqLog := clog.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name, "Trace", traceID) + _ = context.Background() + reqLog := r.Log.WithValues("releasemanager", req.NamespacedName, "Trace", traceID) + + // your logic here - // Fetch the ReleaseManager instance rm := &picchuv1alpha1.ReleaseManager{} - if err := r.client.Get(ctx, request.NamespacedName, rm); err != nil { + if err := r.Client.Get(ctx, req.NamespacedName, rm); err != nil { if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - return reconcile.Result{}, nil + return ctrl.Result{}, nil } - // Error reading the object - requeue the request. + return r.requeue(reqLog, err) } - r.scheme.Default(rm) + + r.Scheme.Default(rm) rmLog := reqLog.WithValues("App", rm.Spec.App, "Fleet", rm.Spec.Fleet, "Target", rm.Spec.Target) + for label := range rm.Labels { if label == picchuv1alpha1.LabelIgnore { rmLog.Info("Ignoring ReleaseManager") @@ -240,9 +206,9 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci return r.requeue(rmLog, err) } - deliveryClusters, err := r.getClustersByFleet(ctx, rm.Namespace, r.config.ServiceLevelsFleet) + deliveryClusters, err := r.getClustersByFleet(ctx, rm.Namespace, r.Config.ServiceLevelsFleet) if err != nil { - return r.requeue(rmLog, fmt.Errorf("failed to get delivery clusters for fleet %s: %w", r.config.ServiceLevelsFleet, err)) + return r.requeue(rmLog, fmt.Errorf("failed to get delivery clusters for fleet %s: %w", r.Config.ServiceLevelsFleet, err)) } deliveryClusterInfo := ClusterInfoList{} for _, cluster := range deliveryClusters { @@ -272,12 +238,12 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci return r.requeue(rmLog, err) } - revisions, err := r.getRevisions(ctx, rmLog, request.Namespace, rm.Spec.Fleet, rm.Spec.App, rm.Spec.Target) + revisions, err := r.getRevisions(ctx, rmLog, req.Namespace, rm.Spec.Fleet, rm.Spec.App, rm.Spec.Target) if err != nil { return r.requeue(rmLog, err) } - faults, err := r.getFaults(ctx, rmLog, request.Namespace, rm.Spec.App, rm.Spec.Target) + faults, err := r.getFaults(ctx, rmLog, req.Namespace, rm.Spec.App, rm.Spec.Target) if err != nil { return r.requeue(rmLog, err) } @@ -288,7 +254,7 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci } ic := &IncarnationController{ - deliveryClient: r.client, + deliveryClient: r.Client, deliveryApplier: deliveryApplier, planApplier: planApplier, log: rmLog, @@ -297,15 +263,15 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci } syncer := ResourceSyncer{ - deliveryClient: r.client, + deliveryClient: r.Client, deliveryApplier: deliveryApplier, planApplier: planApplier, observer: observer, instance: rm, - incarnations: newIncarnationCollection(ic, revisions, observation, r.config), + incarnations: newIncarnationCollection(ic, revisions, observation, r.Config), reconciler: r, log: rmLog, - picchuConfig: r.config, + picchuConfig: r.Config, faults: faults, } @@ -318,7 +284,7 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci // TODO(bob): Figure out why we are getting object modified errors // Refetch fresh ReleaseManager instance so we don't get conflicting updates srm := &picchuv1alpha1.ReleaseManager{} - if err := r.client.Get(ctx, request.NamespacedName, srm); err != nil { + if err := r.Client.Get(ctx, req.NamespacedName, srm); err != nil { if errors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. @@ -328,11 +294,11 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci // Error reading the object - requeue the request. return r.requeue(reqLog, err) } - r.scheme.Default(srm) + r.Scheme.Default(srm) srm.Status.Revisions = rs timeNow := metav1.NewTime(time.Now()) srm.Status.LastUpdated = &timeNow - if err := utils.UpdateStatus(ctx, r.client, srm); err != nil { + if err := utils.UpdateStatus(ctx, r.Client, srm); err != nil { return r.requeue(rmLog, err) } return r.requeue(rmLog, nil) @@ -348,15 +314,15 @@ func (r *ReconcileReleaseManager) Reconcile(ctx context.Context, request reconci } rm.Finalize() - err := r.client.Update(ctx, rm) + err := r.Client.Update(ctx, rm) return r.requeue(rmLog, err) } rmLog.Info("ReleaseManager is deleted and finalized") - return reconcile.Result{}, nil + return ctrl.Result{}, nil } -func (r *ReconcileReleaseManager) getRevisions(ctx context.Context, log logr.Logger, namespace, fleet, app, target string) (*picchuv1alpha1.RevisionList, error) { +func (r *ReleaseManagerReconciler) getRevisions(ctx context.Context, log logr.Logger, namespace, fleet, app, target string) (*picchuv1alpha1.RevisionList, error) { fleetLabel := fmt.Sprintf("%s%s", picchuv1alpha1.LabelFleetPrefix, fleet) listOptions := []client.ListOption{ &client.ListOptions{Namespace: namespace}, @@ -365,11 +331,11 @@ func (r *ReconcileReleaseManager) getRevisions(ctx context.Context, log logr.Log fleetLabel: ""}, } rl := &picchuv1alpha1.RevisionList{} - err := r.client.List(ctx, rl, listOptions...) + err := r.Client.List(ctx, rl, listOptions...) if err != nil { return nil, err } - r.scheme.Default(rl) + r.Scheme.Default(rl) withTargets := &picchuv1alpha1.RevisionList{} for i := range rl.Items { for j := range rl.Items[i].Spec.Targets { @@ -385,7 +351,7 @@ func (r *ReconcileReleaseManager) getRevisions(ctx context.Context, log logr.Log return withTargets, nil } -func (r *ReconcileReleaseManager) getFaults(ctx context.Context, log logr.Logger, namespace, app, target string) ([]picchuv1alpha1.HTTPPortFault, error) { +func (r *ReleaseManagerReconciler) getFaults(ctx context.Context, log logr.Logger, namespace, app, target string) ([]picchuv1alpha1.HTTPPortFault, error) { selector, err := labels.Parse(fmt.Sprintf("%s=%s,%s in (,%s)", picchuv1alpha1.LabelApp, app, picchuv1alpha1.LabelTarget, target)) if err != nil { log.Error(err, "Failed to parse label requirement") @@ -397,12 +363,12 @@ func (r *ReconcileReleaseManager) getFaults(ctx context.Context, log logr.Logger } list := &picchuv1alpha1.FaultInjectorList{} - err = r.client.List(ctx, list, listOptions...) + err = r.Client.List(ctx, list, listOptions...) if err != nil { log.Error(err, "Failed to list faultInjectors") return nil, err } - r.scheme.Default(list) + r.Scheme.Default(list) var faults []picchuv1alpha1.HTTPPortFault for _, item := range list.Items { @@ -413,22 +379,22 @@ func (r *ReconcileReleaseManager) getFaults(ctx context.Context, log logr.Logger } // requeue gives us a chance to log the error with our trace-id and stacktrace to make debugging simpler -func (r *ReconcileReleaseManager) requeue(log logr.Logger, err error) (reconcile.Result, error) { +func (r *ReleaseManagerReconciler) requeue(log logr.Logger, err error) (reconcile.Result, error) { if err != nil { log.Error(err, "An error occurred during reconciliation") return reconcile.Result{}, err } - return reconcile.Result{RequeueAfter: r.config.RequeueAfter}, nil + return reconcile.Result{RequeueAfter: r.Config.RequeueAfter}, nil } -func (r *ReconcileReleaseManager) getClustersByFleet(ctx context.Context, namespace string, fleet string) ([]picchuv1alpha1.Cluster, error) { +func (r *ReleaseManagerReconciler) getClustersByFleet(ctx context.Context, namespace string, fleet string) ([]picchuv1alpha1.Cluster, error) { clusterList := &picchuv1alpha1.ClusterList{} opts := &client.ListOptions{ Namespace: namespace, LabelSelector: labels.SelectorFromSet(map[string]string{picchuv1alpha1.LabelFleet: fleet}), } - err := r.client.List(ctx, clusterList, opts) - r.scheme.Default(clusterList) + err := r.Client.List(ctx, clusterList, opts) + r.Scheme.Default(clusterList) var clusters []picchuv1alpha1.Cluster for i := range clusterList.Items { @@ -442,19 +408,18 @@ func (r *ReconcileReleaseManager) getClustersByFleet(ctx context.Context, namesp return clusters, err } -func (r *ReconcileReleaseManager) newPlanApplier(ctx context.Context, log logr.Logger, clusters []picchuv1alpha1.Cluster) (plan.Applier, error) { +func (r *ReleaseManagerReconciler) newPlanApplier(ctx context.Context, log logr.Logger, clusters []picchuv1alpha1.Cluster) (plan.Applier, error) { g, ctx := errgroup.WithContext(ctx) appliers := make([]plan.Applier, len(clusters)) for i := range clusters { i := i cluster := clusters[i] g.Go(func() error { - remoteClient, err := utils.RemoteClient(ctx, log, r.client, &cluster) + remoteClient, err := utils.RemoteClient(ctx, log, r.Client, &cluster) if err != nil { log.Error(err, "Failed to create remote client") return err } - appliers[i] = plan.NewClusterApplier(remoteClient, &cluster, log.WithValues("Cluster", cluster.Name)) return nil }) @@ -465,14 +430,14 @@ func (r *ReconcileReleaseManager) newPlanApplier(ctx context.Context, log logr.L return plan.NewConcurrentApplier(appliers, log), nil } -func (r *ReconcileReleaseManager) newObserver(ctx context.Context, log logr.Logger, clusters []picchuv1alpha1.Cluster) (observe.Observer, error) { +func (r *ReleaseManagerReconciler) newObserver(ctx context.Context, log logr.Logger, clusters []picchuv1alpha1.Cluster) (observe.Observer, error) { g, ctx := errgroup.WithContext(ctx) observers := make([]observe.Observer, len(clusters)) for i := range clusters { i := i cluster := clusters[i] g.Go(func() error { - remoteClient, err := utils.RemoteClient(ctx, log, r.client, &cluster) + remoteClient, err := utils.RemoteClient(ctx, log, r.Client, &cluster) if err != nil { log.Error(err, "Failed to create remote client") return err @@ -487,3 +452,29 @@ func (r *ReconcileReleaseManager) newObserver(ctx context.Context, log logr.Logg } return observe.NewConcurrentObserver(observers, log), nil } + +func (r *ReleaseManagerReconciler) SetupWithManager(mgr ctrl.Manager) error { + metrics.Registry.MustRegister( + incarnationGitCreateLatency, + incarnationGitDeployLatency, + incarnationGitCanaryLatency, + incarnationGitPendingReleaseLatency, + incarnationGitReleaseLatency, + incarnationRevisionDeployLatency, + incarnationRevisionCanaryLatency, + incarnationRevisionPendingReleaseLatency, + incarnationRevisionReleaseLatency, + incarnationRevisionRollbackLatency, + incarnationDeployLatency, + incarnationCanaryLatency, + incarnationReleaseLatency, + incarnationReleaseStateGauge, + incarnationRevisionOldestStateGauge, + revisionReleaseWeightGauge, + reconcileInterval, + ) + return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{MaxConcurrentReconciles: r.Config.ConcurrentReleaseManagers}). + For(&picchuv1alpha1.ReleaseManager{}). + Complete(r) +} diff --git a/pkg/controller/revision/revision_controller.go b/controllers/revision_controller.go similarity index 81% rename from pkg/controller/revision/revision_controller.go rename to controllers/revision_controller.go index c4d6a66a..6259d632 100644 --- a/pkg/controller/revision/revision_controller.go +++ b/controllers/revision_controller.go @@ -1,32 +1,53 @@ -package revision +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers import ( "context" + + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "fmt" "strings" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "github.com/google/uuid" "sigs.k8s.io/controller-runtime/pkg/controller" - "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - promapi "go.medium.engineering/picchu/pkg/prometheus" + + "go.medium.engineering/picchu/controllers/utils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/event" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/metrics" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -50,12 +71,13 @@ var ( }, []string{"app", "mirror"}) ) -// Add creates a new Revision Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager, c utils.Config) error { - metrics.Registry.MustRegister(revisionFailedGauge) - metrics.Registry.MustRegister(mirrorFailureCounter) - return add(mgr, newReconciler(mgr, c), c) +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=revisions,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=picchu.medium.engineering,resources=revisions/status,verbs=get;update;patch + +func (r *RevisionReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&picchuv1alpha1.Revision{}). + Complete(r) } type PromAPI interface { @@ -68,27 +90,6 @@ func (n *NoopPromAPI) IsRevisionTriggered(ctx context.Context, name, tag string, return false, nil, nil } -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager, c utils.Config) reconcile.Reconciler { - var err error - var api PromAPI - if c.PrometheusQueryAddress != "" { - api, err = promapi.NewAPI(c.PrometheusQueryAddress, c.PrometheusQueryTTL) - } else { - api = &NoopPromAPI{} - } - if err != nil { - panic(err) - } - - return &ReconcileRevision{ - client: mgr.GetClient(), - scheme: mgr.GetScheme(), - config: c, - promAPI: api, - } -} - // add adds a new Controller to mgr with r as the reconcile.Reconciler func add(mgr manager.Manager, r reconcile.Reconciler, c utils.Config) error { _, err := builder.ControllerManagedBy(mgr). @@ -106,17 +107,17 @@ func add(mgr manager.Manager, r reconcile.Reconciler, c utils.Config) error { return nil } -var _ reconcile.Reconciler = &ReconcileRevision{} +var _ reconcile.Reconciler = &RevisionReconciler{} -// ReconcileRevision reconciles a Revision object -type ReconcileRevision struct { +// RevisionReconciler reconciles a Revision object +type RevisionReconciler struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the apiserver - client client.Client - scheme *runtime.Scheme - config utils.Config - promAPI PromAPI - customLogger logr.Logger + Client client.Client + Scheme *runtime.Scheme + Config utils.Config + PromAPI PromAPI + CustomLogger logr.Logger } // Reconcile reads that state of the cluster for a Revision object and makes changes based on the state read @@ -124,17 +125,17 @@ type ReconcileRevision struct { // Note: // The Controller will requeue the Request to be processed again if the returned error is non-nil or // Result.Requeue is true, otherwise upon completion it will remove the work from the queue. -func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { +func (r *RevisionReconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { traceID := uuid.New().String() reqLogger := clog.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name, "Trace", traceID) - if r.customLogger != (logr.Logger{}) { - reqLogger = r.customLogger + if r.CustomLogger != (logr.Logger{}) { + reqLogger = r.CustomLogger } // Fetch the Revision instance instance := &picchuv1alpha1.Revision{} - err := r.client.Get(ctx, request.NamespacedName, instance) + err := r.Client.Get(ctx, request.NamespacedName, instance) if err != nil { if errors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. @@ -145,13 +146,13 @@ func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Req // Error reading the object - requeue the request. return r.Requeue(reqLogger, err) } - r.scheme.Default(instance) + r.Scheme.Default(instance) log := reqLogger.WithValues("App", instance.Spec.App.Name, "Tag", instance.Spec.App.Tag) mirrors := &picchuv1alpha1.MirrorList{} - err = r.client.List(ctx, mirrors) + err = r.Client.List(ctx, mirrors) if err != nil { - return r.Requeue(log, err) + return r.Requeue(log, nil) } if err = r.LabelWithAppAndFleets(log, instance); err != nil { @@ -198,7 +199,7 @@ func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Req } } - triggered, alarms, err := r.promAPI.IsRevisionTriggered(context.TODO(), instance.Spec.App.Name, instance.Spec.App.Tag, instance.Spec.CanaryWithSLIRules) + triggered, alarms, err := r.PromAPI.IsRevisionTriggered(context.TODO(), instance.Spec.App.Name, instance.Spec.App.Tag, instance.Spec.CanaryWithSLIRules) if err != nil { return r.Requeue(log, err) } @@ -241,7 +242,7 @@ func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Req revisionStatus := rm.RevisionStatus(instance.Spec.App.Tag) revisionStatus.TriggeredAlarms = alarms rm.UpdateRevisionStatus(revisionStatus) - if err := utils.UpdateStatus(ctx, r.client, rm); err != nil { + if err := utils.UpdateStatus(ctx, r.Client, rm); err != nil { log.Error(err, "Could not save alarms to RevisionStatus", "alarms", alarms) } } @@ -251,7 +252,7 @@ func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Req } if revisionFailing { - op, err := controllerutil.CreateOrUpdate(ctx, r.client, instance, func() error { + op, err := controllerutil.CreateOrUpdate(ctx, r.Client, instance, func() error { instance.Fail() return nil }) @@ -265,22 +266,22 @@ func (r *ReconcileRevision) Reconcile(ctx context.Context, request reconcile.Req } instance.Status = status - if err = r.client.Status().Update(context.TODO(), instance); err != nil { + if err = r.Client.Status().Update(context.TODO(), instance); err != nil { return r.Requeue(log, err) } return r.Requeue(log, nil) } -func (r *ReconcileRevision) Requeue(log logr.Logger, err error) (reconcile.Result, error) { +func (r *RevisionReconciler) Requeue(log logr.Logger, err error) (reconcile.Result, error) { if err != nil { log.Error(err, "Reconcile resulted in error") return reconcile.Result{}, err } - return reconcile.Result{RequeueAfter: r.config.RequeueAfter}, nil + return reconcile.Result{RequeueAfter: r.Config.RequeueAfter}, nil } -func (r *ReconcileRevision) NoRequeue(log logr.Logger, err error) (reconcile.Result, error) { +func (r *RevisionReconciler) NoRequeue(log logr.Logger, err error) (reconcile.Result, error) { if err != nil { log.Error(err, "Reconcile resulted in error") return reconcile.Result{}, err @@ -288,7 +289,7 @@ func (r *ReconcileRevision) NoRequeue(log logr.Logger, err error) (reconcile.Res return reconcile.Result{}, nil } -func (r *ReconcileRevision) LabelWithAppAndFleets(log logr.Logger, revision *picchuv1alpha1.Revision) error { +func (r *RevisionReconciler) LabelWithAppAndFleets(log logr.Logger, revision *picchuv1alpha1.Revision) error { var fleetLabels []string updated := false for _, target := range revision.Spec.Targets { @@ -321,12 +322,12 @@ func (r *ReconcileRevision) LabelWithAppAndFleets(log logr.Logger, revision *pic } if updated { - return r.client.Update(context.TODO(), revision) + return r.Client.Update(context.TODO(), revision) } return nil } -func (r *ReconcileRevision) getReleaseManager( +func (r *RevisionReconciler) getReleaseManager( log logr.Logger, target *picchuv1alpha1.RevisionTarget, revision *picchuv1alpha1.Revision, @@ -341,7 +342,7 @@ func (r *ReconcileRevision) getReleaseManager( Namespace: revision.Namespace, LabelSelector: labels.SelectorFromSet(lbls), } - r.client.List(context.TODO(), rms, opts) + r.Client.List(context.TODO(), rms, opts) if len(rms.Items) > 1 { panic(fmt.Sprintf("Too many ReleaseManagers matching %#v", lbls)) } @@ -352,7 +353,7 @@ func (r *ReconcileRevision) getReleaseManager( return } -func (r *ReconcileRevision) getOrCreateReleaseManager( +func (r *RevisionReconciler) getOrCreateReleaseManager( log logr.Logger, target *picchuv1alpha1.RevisionTarget, revision *picchuv1alpha1.Revision, @@ -377,7 +378,7 @@ func (r *ReconcileRevision) getOrCreateReleaseManager( Target: target.Name, }, } - if err := r.client.Create(context.TODO(), rm); err != nil { + if err := r.Client.Create(context.TODO(), rm); err != nil { log.Error(err, "Failed to sync releaseManager") return nil, err } @@ -386,7 +387,7 @@ func (r *ReconcileRevision) getOrCreateReleaseManager( return } -func (r *ReconcileRevision) syncReleaseManager(log logr.Logger, revision *picchuv1alpha1.Revision) (picchuv1alpha1.RevisionStatus, error) { +func (r *RevisionReconciler) syncReleaseManager(log logr.Logger, revision *picchuv1alpha1.Revision) (picchuv1alpha1.RevisionStatus, error) { // Sync releasemanagers rstatus := picchuv1alpha1.RevisionStatus{} for _, target := range revision.Spec.Targets { @@ -402,7 +403,7 @@ func (r *ReconcileRevision) syncReleaseManager(log logr.Logger, revision *picchu return rstatus, nil } -func (r *ReconcileRevision) deleteIfMarked(log logr.Logger, revision *picchuv1alpha1.Revision) (bool, error) { +func (r *RevisionReconciler) deleteIfMarked(log logr.Logger, revision *picchuv1alpha1.Revision) (bool, error) { for _, target := range revision.Spec.Targets { label := fmt.Sprintf("%s%s", picchuv1alpha1.LabelTargetDeletablePrefix, target.Name) if val, ok := revision.Labels[label]; !ok && val != "true" { @@ -411,14 +412,14 @@ func (r *ReconcileRevision) deleteIfMarked(log logr.Logger, revision *picchuv1al } log.Info("Deleting revision marked for deletion in all targets") - err := r.client.Delete(context.TODO(), revision) + err := r.Client.Delete(context.TODO(), revision) if err != nil && !errors.IsNotFound(err) { return true, err } return true, nil } -func (r *ReconcileRevision) mirrorRevision( +func (r *RevisionReconciler) mirrorRevision( ctx context.Context, log logr.Logger, mirror *picchuv1alpha1.Mirror, @@ -426,11 +427,11 @@ func (r *ReconcileRevision) mirrorRevision( ) error { log.Info("Mirroring revision", "Mirror", mirror.Spec.ClusterName) cluster := &picchuv1alpha1.Cluster{} - key := types.NamespacedName{revision.Namespace, mirror.Spec.ClusterName} - if err := r.client.Get(ctx, key, cluster); err != nil { + key := types.NamespacedName{Namespace: revision.Namespace, Name: mirror.Spec.ClusterName} + if err := r.Client.Get(ctx, key, cluster); err != nil { return err } - remoteClient, err := utils.RemoteClient(ctx, log, r.client, cluster) + remoteClient, err := utils.RemoteClient(ctx, log, r.Client, cluster) if err != nil { log.Error(err, "Failed to initialize remote client") return err @@ -449,7 +450,7 @@ func (r *ReconcileRevision) mirrorRevision( } configMapList := &corev1.ConfigMapList{} log.Info("Listing configMaps") - if err := r.client.List(ctx, configMapList, opts); err != nil { + if err := r.Client.List(ctx, configMapList, opts); err != nil { log.Error(err, "Failed to list target configMaps") return err } @@ -459,7 +460,7 @@ func (r *ReconcileRevision) mirrorRevision( } secretList := &corev1.SecretList{} log.Info("Listing secrets") - if err := r.client.List(ctx, secretList, opts); err != nil { + if err := r.Client.List(ctx, secretList, opts); err != nil { log.Error(err, "Failed to list target secrets") return err } @@ -495,7 +496,7 @@ func (r *ReconcileRevision) mirrorRevision( Namespace: configSelector.Namespace, } configMapList := &corev1.ConfigMapList{} - if err := r.client.List(ctx, configMapList, opts); err != nil { + if err := r.Client.List(ctx, configMapList, opts); err != nil { log.Error(err, "Failed to list additionalConfigSelector configMaps") return err } @@ -505,7 +506,7 @@ func (r *ReconcileRevision) mirrorRevision( } secretList := &corev1.SecretList{} - if err := r.client.List(ctx, secretList, opts); err != nil { + if err := r.Client.List(ctx, secretList, opts); err != nil { log.Error(err, "Failed to list additionalConfigSelector secrets") return err } @@ -538,7 +539,7 @@ func (r *ReconcileRevision) mirrorRevision( return err } -func (r *ReconcileRevision) copyConfigMapList( +func (r *RevisionReconciler) copyConfigMapList( ctx context.Context, log logr.Logger, remoteClient client.Client, @@ -567,7 +568,7 @@ func (r *ReconcileRevision) copyConfigMapList( return nil } -func (r *ReconcileRevision) copySecretList( +func (r *RevisionReconciler) copySecretList( ctx context.Context, log logr.Logger, remoteClient client.Client, diff --git a/pkg/controller/releasemanager/scaling.go b/controllers/scaling.go similarity index 94% rename from pkg/controller/releasemanager/scaling.go rename to controllers/scaling.go index 6f3a4c09..57d96e8f 100644 --- a/pkg/controller/releasemanager/scaling.go +++ b/controllers/scaling.go @@ -1,11 +1,12 @@ -package releasemanager +package controllers import ( - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" "math" "time" - "go.medium.engineering/picchu/pkg/controller/releasemanager/scaling" + picchu "go.medium.engineering/picchu/api/v1alpha1" + + "go.medium.engineering/picchu/controllers/scaling" ) type ScalableTargetAdapter struct { diff --git a/pkg/controller/releasemanager/scaling/geometric.go b/controllers/scaling/geometric.go similarity index 100% rename from pkg/controller/releasemanager/scaling/geometric.go rename to controllers/scaling/geometric.go diff --git a/pkg/controller/releasemanager/scaling/geometric_test.go b/controllers/scaling/geometric_test.go similarity index 96% rename from pkg/controller/releasemanager/scaling/geometric_test.go rename to controllers/scaling/geometric_test.go index 5398f934..ba2f7f9d 100644 --- a/pkg/controller/releasemanager/scaling/geometric_test.go +++ b/controllers/scaling/geometric_test.go @@ -1,14 +1,15 @@ package scaling import ( + "testing" + "time" + "github.com/golang/mock/gomock" testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/releasemanager/scaling/mocks" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/scaling/mocks" + "go.medium.engineering/picchu/test" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" - "time" ) func TestGeometricScaling(t *testing.T) { diff --git a/pkg/controller/releasemanager/scaling/linear.go b/controllers/scaling/linear.go similarity index 100% rename from pkg/controller/releasemanager/scaling/linear.go rename to controllers/scaling/linear.go diff --git a/pkg/controller/releasemanager/scaling/linear_test.go b/controllers/scaling/linear_test.go similarity index 95% rename from pkg/controller/releasemanager/scaling/linear_test.go rename to controllers/scaling/linear_test.go index 8a1d3aa3..a8971e62 100644 --- a/pkg/controller/releasemanager/scaling/linear_test.go +++ b/controllers/scaling/linear_test.go @@ -1,15 +1,16 @@ package scaling import ( - testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/test" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" "time" + testify "github.com/stretchr/testify/assert" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/test" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/golang/mock/gomock" - "go.medium.engineering/picchu/pkg/controller/releasemanager/scaling/mocks" + "go.medium.engineering/picchu/controllers/scaling/mocks" ) func TestLinearScaling(t *testing.T) { diff --git a/pkg/controller/releasemanager/scaling/mocks/scalabletarget_mock.go b/controllers/scaling/mocks/scalabletarget_mock.go similarity index 95% rename from pkg/controller/releasemanager/scaling/mocks/scalabletarget_mock.go rename to controllers/scaling/mocks/scalabletarget_mock.go index 306a608e..678ad7b8 100644 --- a/pkg/controller/releasemanager/scaling/mocks/scalabletarget_mock.go +++ b/controllers/scaling/mocks/scalabletarget_mock.go @@ -1,12 +1,12 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: go.medium.engineering/picchu/pkg/controller/releasemanager/scaling (interfaces: ScalableTarget) +// Source: go.medium.engineering/picchu/controllers/releasemanager/scaling (interfaces: ScalableTarget) // Package mocks is a generated GoMock package. package mocks import ( gomock "github.com/golang/mock/gomock" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" reflect "reflect" time "time" ) diff --git a/pkg/controller/releasemanager/scaling/target.go b/controllers/scaling/target.go similarity index 81% rename from pkg/controller/releasemanager/scaling/target.go rename to controllers/scaling/target.go index c6990a61..e291db72 100644 --- a/pkg/controller/releasemanager/scaling/target.go +++ b/controllers/scaling/target.go @@ -1,8 +1,9 @@ package scaling import ( - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" "time" + + picchu "go.medium.engineering/picchu/api/v1alpha1" ) // ScalableTarget is an interface to a revision target that is scalable. diff --git a/pkg/controller/releasemanager/schedule/always.go b/controllers/schedule/always.go similarity index 100% rename from pkg/controller/releasemanager/schedule/always.go rename to controllers/schedule/always.go diff --git a/pkg/controller/releasemanager/schedule/humane.go b/controllers/schedule/humane.go similarity index 100% rename from pkg/controller/releasemanager/schedule/humane.go rename to controllers/schedule/humane.go diff --git a/pkg/controller/releasemanager/schedule/inhumane.go b/controllers/schedule/inhumane.go similarity index 100% rename from pkg/controller/releasemanager/schedule/inhumane.go rename to controllers/schedule/inhumane.go diff --git a/pkg/controller/releasemanager/schedule/schedule.go b/controllers/schedule/schedule.go similarity index 100% rename from pkg/controller/releasemanager/schedule/schedule.go rename to controllers/schedule/schedule.go diff --git a/pkg/controller/releasemanager/schedule/schedule_test.go b/controllers/schedule/schedule_test.go similarity index 100% rename from pkg/controller/releasemanager/schedule/schedule_test.go rename to controllers/schedule/schedule_test.go diff --git a/pkg/controller/clustersecrets/secretdeployer.go b/controllers/secretdeployer.go similarity index 94% rename from pkg/controller/clustersecrets/secretdeployer.go rename to controllers/secretdeployer.go index 424b461d..32389a63 100644 --- a/pkg/controller/clustersecrets/secretdeployer.go +++ b/controllers/secretdeployer.go @@ -1,12 +1,13 @@ -package clustersecrets +package controllers import ( "context" "errors" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" "github.com/go-logr/logr" + "github.com/prometheus/common/log" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/controller/releasemanager/state.go b/controllers/state.go similarity index 99% rename from pkg/controller/releasemanager/state.go rename to controllers/state.go index 0f0b0b5c..f74fe2cd 100644 --- a/pkg/controller/releasemanager/state.go +++ b/controllers/state.go @@ -1,11 +1,11 @@ -package releasemanager +package controllers import ( "context" "time" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" ) var ( diff --git a/pkg/controller/releasemanager/state_test.go b/controllers/state_test.go similarity index 99% rename from pkg/controller/releasemanager/state_test.go rename to controllers/state_test.go index a6038285..703692bf 100644 --- a/pkg/controller/releasemanager/state_test.go +++ b/controllers/state_test.go @@ -1,4 +1,4 @@ -package releasemanager +package controllers // TODO(bob): errors on the deployment interface aren't tested here, and should be @@ -7,7 +7,7 @@ import ( tt "testing" "time" - "go.medium.engineering/picchu/pkg/test" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/controllers/suite_test.go b/controllers/suite_test.go new file mode 100644 index 00000000..b4a5e054 --- /dev/null +++ b/controllers/suite_test.go @@ -0,0 +1,94 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "path/filepath" + testinglib "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + picchumediumengineeringv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + // +kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testinglib.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Controller Suite") + +} + +var _ = BeforeSuite(func(done Done) { + logf.SetLogger(zap.New(zap.UseDevMode(false), zap.WriteTo(GinkgoWriter))) + ctx, cancel = context.WithCancel(context.TODO()) + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + } + + var err error + cfg, err = testEnv.Start() + Expect(err).ToNot(HaveOccurred()) + Expect(cfg).ToNot(BeNil()) + + err = picchumediumengineeringv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + // +kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).ToNot(HaveOccurred()) + Expect(k8sClient).ToNot(BeNil()) + + k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme.Scheme, + }) + Expect(err).ToNot(HaveOccurred()) + + go func() { + defer GinkgoRecover() + err = k8sManager.Start(ctx) + Expect(err).ToNot(HaveOccurred(), "failed to run manager") + }() + + close(done) +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).ToNot(HaveOccurred()) +}) diff --git a/pkg/controller/releasemanager/syncer.go b/controllers/syncer.go similarity index 96% rename from pkg/controller/releasemanager/syncer.go rename to controllers/syncer.go index 8124146b..42c5064e 100644 --- a/pkg/controller/releasemanager/syncer.go +++ b/controllers/syncer.go @@ -1,17 +1,17 @@ -package releasemanager +package controllers import ( "context" "time" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/releasemanager/observe" - rmplan "go.medium.engineering/picchu/pkg/controller/releasemanager/plan" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/plan" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/observe" + rmplan "go.medium.engineering/picchu/controllers/plan" + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/plan" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/prometheus/client_golang/prometheus" istio "istio.io/api/networking/v1alpha3" "sigs.k8s.io/controller-runtime/pkg/client" @@ -36,7 +36,7 @@ type ResourceSyncer struct { observer observe.Observer instance *picchuv1alpha1.ReleaseManager incarnations Incarnations - reconciler *ReconcileReleaseManager + reconciler *ReleaseManagerReconciler log logr.Logger picchuConfig utils.Config faults []picchuv1alpha1.HTTPPortFault @@ -413,14 +413,14 @@ func (r *ResourceSyncer) prepareServiceMonitors() []*picchuv1alpha1.ServiceMonit } // returns the PrometheusRules to support SLOs from the latest released revision -func (r *ResourceSyncer) prepareServiceLevelObjectives() ([]*picchuv1alpha1.ServiceLevelObjective, picchuv1alpha1.ServiceLevelObjectiveLabels) { - var slos []*picchuv1alpha1.ServiceLevelObjective +func (r *ResourceSyncer) prepareServiceLevelObjectives() ([]*picchuv1alpha1.SlothServiceLevelObjective, picchuv1alpha1.ServiceLevelObjectiveLabels) { + var slos []*picchuv1alpha1.SlothServiceLevelObjective if len(r.incarnations.deployed()) > 0 { releasable := r.incarnations.releasable() for _, i := range releasable { if i.target() != nil { - return i.target().ServiceLevelObjectives, i.target().ServiceLevelObjectiveLabels + return i.target().SlothServiceLevelObjectives, i.target().ServiceLevelObjectiveLabels } } } diff --git a/pkg/controller/releasemanager/syncer_test.go b/controllers/syncer_test.go similarity index 97% rename from pkg/controller/releasemanager/syncer_test.go rename to controllers/syncer_test.go index 580f16b4..eecb95f5 100644 --- a/pkg/controller/releasemanager/syncer_test.go +++ b/controllers/syncer_test.go @@ -1,4 +1,4 @@ -package releasemanager +package controllers import ( "fmt" @@ -9,9 +9,9 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - rmplan "go.medium.engineering/picchu/pkg/controller/releasemanager/plan" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + rmplan "go.medium.engineering/picchu/controllers/plan" + "go.medium.engineering/picchu/test" ) const ( diff --git a/pkg/controller/utils/api.go b/controllers/utils/api.go similarity index 91% rename from pkg/controller/utils/api.go rename to controllers/utils/api.go index aef0f736..43720fec 100644 --- a/pkg/controller/utils/api.go +++ b/controllers/utils/api.go @@ -5,12 +5,12 @@ import ( "fmt" "sync" - "go.medium.engineering/picchu/pkg/client/scheme" + "go.medium.engineering/picchu/client/scheme" errorsGen "errors" "github.com/go-logr/logr" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -33,7 +33,7 @@ func checkCache(key client.ObjectKey) (client.Client, bool) { } // RemoteClient creates a k8s client from a cluster object. -func RemoteClient(ctx context.Context, log logr.Logger, reader client.Reader, cluster *picchuv1alpha1.Cluster) (client.Client, error) { +func RemoteClient(ctx context.Context, log logr.Logger, reader client.Client, cluster *picchuv1alpha1.Cluster) (client.Client, error) { key := client.ObjectKeyFromObject(cluster) if key == (types.NamespacedName{}) { return nil, errorsGen.New("NamespacedName is empty") @@ -54,7 +54,7 @@ func RemoteClient(ctx context.Context, log logr.Logger, reader client.Reader, cl log.Error(err, "cluster config nil", "Cluster", cluster.Name) return nil, err } - cli, err := client.New(config, client.Options{}) + cli, err := client.New(config, client.Options{Scheme: reader.Scheme()}) if err != nil { return cli, err } diff --git a/pkg/controller/utils/config.go b/controllers/utils/config.go similarity index 100% rename from pkg/controller/utils/config.go rename to controllers/utils/config.go diff --git a/pkg/controller/utils/math.go b/controllers/utils/math.go similarity index 100% rename from pkg/controller/utils/math.go rename to controllers/utils/math.go diff --git a/pkg/controller/utils/variant.go b/controllers/utils/variant.go similarity index 75% rename from pkg/controller/utils/variant.go rename to controllers/utils/variant.go index 262711ee..68bf414c 100644 --- a/pkg/controller/utils/variant.go +++ b/controllers/utils/variant.go @@ -1,6 +1,6 @@ package utils -import picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" +import picchu "go.medium.engineering/picchu/api/v1alpha1" func VariantEnabled(releaseManager *picchu.ReleaseManager, variant string) bool { for _, v := range releaseManager.Spec.Variants { diff --git a/pkg/controller/releasemanager/wrappers.go b/controllers/wrappers.go similarity index 98% rename from pkg/controller/releasemanager/wrappers.go rename to controllers/wrappers.go index 74f1da82..6bb033b8 100644 --- a/pkg/controller/releasemanager/wrappers.go +++ b/controllers/wrappers.go @@ -1,4 +1,4 @@ -package releasemanager +package controllers import ( appsv1 "k8s.io/api/apps/v1" diff --git a/deploy/crds/picchu.medium.engineering_clusters_crd.yaml b/deploy/crds/picchu.medium.engineering_clusters_crd.yaml deleted file mode 100644 index d0eba9b5..00000000 --- a/deploy/crds/picchu.medium.engineering_clusters_crd.yaml +++ /dev/null @@ -1,115 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: clusters.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - categories: - - all - - picchu - kind: Cluster - listKind: ClusterList - plural: clusters - singular: cluster - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: Cluster is the Schema for the clusters API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterSpec defines the desired state of Cluster - properties: - config: - properties: - certificate-authority-data: - format: byte - type: string - server: - type: string - required: - - certificate-authority-data - - server - type: object - devRouteTagTemplate: - type: string - enableDevRoutes: - type: boolean - enabled: - type: boolean - hotStandby: - type: boolean - ingresses: - properties: - private: - properties: - defaultDomains: - items: - type: string - type: array - dnsName: - type: string - gateway: - type: string - required: - - defaultDomains - - dnsName - type: object - public: - properties: - defaultDomains: - items: - type: string - type: array - dnsName: - type: string - gateway: - type: string - required: - - defaultDomains - - dnsName - type: object - required: - - private - - public - type: object - scalingFactorString: - type: string - required: - - enabled - - ingresses - type: object - status: - description: ClusterStatus defines the observed state of Cluster - properties: - kubernetes: - properties: - ready: - type: boolean - version: - type: string - required: - - ready - - version - type: object - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/crds/picchu.medium.engineering_clustersecrets_crd.yaml b/deploy/crds/picchu.medium.engineering_clustersecrets_crd.yaml deleted file mode 100644 index 922cb104..00000000 --- a/deploy/crds/picchu.medium.engineering_clustersecrets_crd.yaml +++ /dev/null @@ -1,85 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: clustersecrets.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - kind: ClusterSecrets - listKind: ClusterSecretsList - plural: clustersecrets - singular: clustersecrets - scope: "" - validation: - openAPIV3Schema: - description: ClusterSecrets is the Schema for the clustersecrets API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ClusterSecretsSpec defines the desired state of ClusterSecrets - properties: - source: - properties: - fieldSelector: - type: string - labelSelector: - type: string - namespace: - type: string - required: - - namespace - type: object - target: - properties: - annotations: - additionalProperties: - type: string - description: Annotations to add to the copied secrets - type: object - fieldSelector: - description: FieldSelector of clusters to copy secrets to - type: string - labelSelector: - description: LabelSelector of clusters to copy secrets to - type: string - labels: - additionalProperties: - type: string - description: Labels to add to the copied secrets - type: object - namespace: - description: Namespace to copy secrets to - type: string - required: - - namespace - type: object - required: - - source - - target - type: object - status: - description: ClusterSecretsStatus defines the observed state of ClusterSecrets - properties: - secrets: - description: Names of secrets copied to targets - items: - type: string - type: array - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/crds/picchu.medium.engineering_faultinjectors_crd.yaml b/deploy/crds/picchu.medium.engineering_faultinjectors_crd.yaml deleted file mode 100644 index 5aac404f..00000000 --- a/deploy/crds/picchu.medium.engineering_faultinjectors_crd.yaml +++ /dev/null @@ -1,102 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: faultinjectors.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - kind: FaultInjector - listKind: FaultInjectorList - plural: faultinjectors - singular: faultinjector - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: FaultInjector is the Schema for the faultinjectors API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: FaultInjectorSpec defines the desired state of FaultInjector - properties: - httpPortFaults: - items: - description: HTTPPortFault allows injecting faults into apps by port - number - properties: - fault: - description: "HTTPFaultInjection can be used to specify one or - more faults to inject while forwarding HTTP requests to the - destination specified in a route. Fault specification is part - of a VirtualService rule. Faults include aborting the Http request - from downstream service, and/or delaying proxying of requests. - A fault rule MUST HAVE delay or abort or both. \n *Note:* Delay - and abort faults are independent of one another, even if both - are specified simultaneously." - properties: - abort: - description: Abort Http request attempts and return error - codes back to downstream service, giving the impression - that the upstream service is faulty. - properties: - percentage: - description: Percentage of requests to be aborted with - the error code provided. - properties: - value: {} - type: object - type: object - delay: - description: Delay requests before forwarding, emulating various - failures such as network issues, overloaded upstream service, - etc. - properties: - percent: - description: Percentage of requests on which the delay - will be injected (0-100). Use of integer `percent` value - is deprecated. Use the double `percentage` field instead. - format: int32 - type: integer - percentage: - description: Percentage of requests on which the delay - will be injected. - properties: - value: {} - type: object - type: object - type: object - portSelector: - description: PortSelector specifies the number of a port to be - used for matching or selection for final routing. - properties: - number: - description: Valid port number - format: int32 - type: integer - type: object - type: object - type: array - required: - - httpPortFaults - type: object - status: - description: FaultInjectorStatus defines the observed state of FaultInjector - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/crds/picchu.medium.engineering_mirrors_crd.yaml b/deploy/crds/picchu.medium.engineering_mirrors_crd.yaml deleted file mode 100644 index 06e5da07..00000000 --- a/deploy/crds/picchu.medium.engineering_mirrors_crd.yaml +++ /dev/null @@ -1,108 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: mirrors.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - kind: Mirror - listKind: MirrorList - plural: mirrors - singular: mirror - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: Mirror is the Schema for the mirrors API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: MirrorSpec defines the desired state of Mirror - properties: - additionalConfigSelectors: - items: - properties: - appLabelName: - type: string - labelSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An - empty label selector matches all objects. A null label selector - matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespace: - type: string - tagLabelName: - type: string - required: - - appLabelName - - tagLabelName - type: object - type: array - clusterName: - type: string - required: - - clusterName - type: object - status: - description: MirrorStatus defines the observed state of Mirror - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/crds/picchu.medium.engineering_releasemanagers_crd.yaml b/deploy/crds/picchu.medium.engineering_releasemanagers_crd.yaml deleted file mode 100644 index 924d0f6c..00000000 --- a/deploy/crds/picchu.medium.engineering_releasemanagers_crd.yaml +++ /dev/null @@ -1,182 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: releasemanagers.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - categories: - - all - - picchu - kind: ReleaseManager - listKind: ReleaseManagerList - plural: releasemanagers - singular: releasemanager - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ReleaseManager is the Schema for the releasemanagers API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ReleaseManagerSpec defines the desired state of ReleaseManager - properties: - app: - type: string - fleet: - type: string - target: - type: string - variants: - items: - properties: - enabled: - type: boolean - name: - type: string - required: - - enabled - - name - type: object - type: array - required: - - app - - fleet - - target - type: object - status: - description: ReleaseManagerStatus defines the observed state of ReleaseManager - properties: - lastUpdated: - format: date-time - type: string - revisions: - items: - properties: - canaryStartTimestamp: - format: date-time - type: string - currentPercent: - format: int32 - type: integer - deleted: - type: boolean - deployingStartTimestamp: - format: date-time - type: string - gitTimestamp: - format: date-time - type: string - lastUpdated: - format: date-time - type: string - metrics: - description: ReleaseManagerRevisionMetricsStatus defines the observed - state of ReleaseManagerRevisionMetrics - properties: - canarySecondsInt: - type: integer - deploySecondsInt: - type: integer - gitCanarySecondsInt: - type: integer - gitCreateSecondsInt: - type: integer - gitDeploySecondsInt: - type: integer - gitPendingReleaseSecondsInt: - type: integer - gitReleaseSecondsInt: - type: integer - releaseSecondsInt: - type: integer - revisionCanarySecondsInt: - type: integer - revisionDeploySecondsInt: - type: integer - revisionPendingReleaseSecondsInt: - type: integer - revisionReleaseSecondsInt: - type: integer - revisionRollbackSecondsInt: - type: integer - type: object - peakPercent: - format: int32 - type: integer - pendingReleaseStartTimestamp: - format: date-time - type: string - releaseEligible: - type: boolean - releaseStartTimestamp: - format: date-time - type: string - revisionTimestamp: - format: date-time - type: string - scale: - properties: - Current: - format: int32 - type: integer - Desired: - format: int32 - type: integer - Peak: - format: int32 - type: integer - type: object - state: - properties: - current: - type: string - lastUpdated: - format: date-time - type: string - target: - type: string - required: - - current - - target - type: object - tag: - type: string - triggeredAlerts: - items: - type: string - type: array - ttl: - format: int64 - type: integer - required: - - currentPercent - - lastUpdated - - peakPercent - - releaseEligible - - scale - - tag - type: object - type: array - required: - - lastUpdated - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/crds/picchu.medium.engineering_revisions_crd.yaml b/deploy/crds/picchu.medium.engineering_revisions_crd.yaml deleted file mode 100644 index 7462ba2c..00000000 --- a/deploy/crds/picchu.medium.engineering_revisions_crd.yaml +++ /dev/null @@ -1,5744 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: revisions.picchu.medium.engineering -spec: - group: picchu.medium.engineering - names: - categories: - - all - - picchu - kind: Revision - listKind: RevisionList - plural: revisions - singular: revision - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: Revision is the Schema for the revisions API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: RevisionSpec defines the desired state of Revision - properties: - app: - properties: - image: - type: string - name: - type: string - ref: - type: string - tag: - type: string - required: - - image - - name - - ref - - tag - type: object - canaryWithSLIRules: - type: boolean - disableMirroring: - type: boolean - failed: - type: boolean - ignoreSLOs: - type: boolean - sentry: - properties: - release: - type: boolean - type: object - tagRoutingHeader: - type: string - targets: - items: - properties: - acceptanceTarget: - type: boolean - affinity: - description: Affinity is a group of affinity scheduling rules. - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for - the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects - (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated with - the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to an update), the system - may or may not try to eventually evict the pod from - its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them are - ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is - a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If the - operator is Exists or DoesNotExist, - the values array must be empty. If the - operator is Gt or Lt, the values array - must have a single element, which will - be interpreted as an integer. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the affinity requirements - specified by this field cease to be met at some point - during pod execution (e.g. due to a pod label update), - the system may or may not try to eventually evict the - pod from its node. When there are multiple elements, - the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, etc. - as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node that - violates one or more of the expressions. The node that - is most preferred is the one with the greatest sum of - weights, i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - anti-affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the corresponding - podAffinityTerm; the node(s) with the highest sum are - the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the - pods matching the labelSelector in the specified - namespaces, where co-located is defined as - running on a node whose value of the label - with key topologyKey matches that of any node - on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the pod - will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a pod - label update), the system may or may not try to eventually - evict the pod from its node. When there are multiple - elements, the lists of nodes corresponding to each podAffinityTerm - are intersected, i.e. all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not - co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any node - on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - alertRules: - items: - description: Rule describes an alerting or recording rule. - properties: - alert: - type: string - annotations: - additionalProperties: - type: string - type: object - expr: - anyOf: - - type: string - - type: integer - for: - type: string - labels: - additionalProperties: - type: string - type: object - record: - type: string - required: - - expr - type: object - type: array - aws: - description: 'TODO(lyra): PodTemplate' - properties: - iam: - properties: - role_arn: - type: string - type: object - type: object - canary: - properties: - percent: - format: int32 - type: integer - ttl: - format: int64 - type: integer - required: - - percent - - ttl - type: object - configSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An - empty label selector matches all objects. A null label selector - matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - defaultIngressPorts: - additionalProperties: - type: string - type: object - env: - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previous defined environment variables in the - container and any service environment variables. If a - variable cannot be resolved, the reference in the input - string will be unchanged. The $(VAR_NAME) syntax can be - escaped with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - description: Specifies the output format of the - exposed resources, defaults to "1" - type: string - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - externalTest: - properties: - completed: - type: boolean - enabled: - type: boolean - lastUpdated: - format: date-time - type: string - started: - type: boolean - succeeded: - type: boolean - timeout: - type: string - required: - - completed - - enabled - - started - type: object - fleet: - type: string - istio: - description: see custom_deepcopy.go - properties: - sidecar: - properties: - egressHosts: - items: - type: string - type: array - type: object - trafficPolicy: - description: Traffic policies to apply for a specific destination, - across all destination ports. See DestinationRule for examples. - properties: - connection_pool: - description: Settings controlling the volume of connections - to an upstream service - properties: - http: - description: HTTP connection pool settings. - properties: - h2_upgrade_policy: - description: Specify if http1.1 connection should - be upgraded to http2 for the associated destination. - format: int32 - type: integer - http1_max_pending_requests: - description: Maximum number of pending HTTP requests - to a destination. Default 2^32-1. - format: int32 - type: integer - http2_max_requests: - description: Maximum number of requests to a backend. - Default 2^32-1. - format: int32 - type: integer - idle_timeout: - description: The idle timeout for upstream connection - pool connections. The idle timeout is defined - as the period in which there are no active requests. - If not set, the default is 1 hour. When the - idle timeout is reached the connection will - be closed. Note that request based timeouts - mean that HTTP/2 PINGs will not keep the connection - alive. Applies to both HTTP1.1 and HTTP2 connections. - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span of - time. Durations less than one second are - represented with a 0 `seconds` field and - a positive or negative `nanos` field. For - durations of one second or more, a non-zero - value for the `nanos` field must be of the - same sign as the `seconds` field. Must be - from -999,999,999 to +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span of - time. Must be from -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds are computed - from: 60 sec/min * 60 min/hr * 24 hr/day - * 365.25 days/year * 10000 years' - format: int64 - type: integer - type: object - max_requests_per_connection: - description: Maximum number of requests per connection - to a backend. Setting this parameter to 1 disables - keep alive. Default 0, meaning "unlimited", - up to 2^29. - format: int32 - type: integer - max_retries: - description: Maximum number of retries that can - be outstanding to all hosts in a cluster at - a given time. Defaults to 2^32-1. - format: int32 - type: integer - type: object - tcp: - description: Settings common to both HTTP and TCP - upstream connections. - properties: - connect_timeout: - description: 'TCP connection timeout. format: - 1h/1m/1s/1ms. MUST BE >=1ms. Default is 10s.' - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span of - time. Durations less than one second are - represented with a 0 `seconds` field and - a positive or negative `nanos` field. For - durations of one second or more, a non-zero - value for the `nanos` field must be of the - same sign as the `seconds` field. Must be - from -999,999,999 to +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span of - time. Must be from -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds are computed - from: 60 sec/min * 60 min/hr * 24 hr/day - * 365.25 days/year * 10000 years' - format: int64 - type: integer - type: object - max_connections: - description: Maximum number of HTTP1 /TCP connections - to a destination host. Default 2^32-1. - format: int32 - type: integer - tcp_keepalive: - description: If set then set SO_KEEPALIVE on the - socket to enable TCP Keepalives. - properties: - interval: - description: The time duration between keep-alive - probes. Default is to use the OS level configuration - (unless overridden, Linux defaults to 75s.) - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span - of time. Durations less than one second - are represented with a 0 `seconds` field - and a positive or negative `nanos` field. - For durations of one second or more, - a non-zero value for the `nanos` field - must be of the same sign as the `seconds` - field. Must be from -999,999,999 to - +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span - of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: - these bounds are computed from: 60 sec/min - * 60 min/hr * 24 hr/day * 365.25 days/year - * 10000 years' - format: int64 - type: integer - type: object - probes: - description: Maximum number of keepalive probes - to send without response before deciding - the connection is dead. Default is to use - the OS level configuration (unless overridden, - Linux defaults to 9.) - format: int32 - type: integer - time: - description: The time duration a connection - needs to be idle before keep-alive probes - start being sent. Default is to use the - OS level configuration (unless overridden, - Linux defaults to 7200s (ie 2 hours.) - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span - of time. Durations less than one second - are represented with a 0 `seconds` field - and a positive or negative `nanos` field. - For durations of one second or more, - a non-zero value for the `nanos` field - must be of the same sign as the `seconds` - field. Must be from -999,999,999 to - +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span - of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: - these bounds are computed from: 60 sec/min - * 60 min/hr * 24 hr/day * 365.25 days/year - * 10000 years' - format: int64 - type: integer - type: object - type: object - type: object - type: object - load_balancer: - description: Settings controlling the load balancer algorithms. - properties: - locality_lb_setting: - description: Locality load balancer settings, this - will override mesh wide settings in entirety, meaning - no merging would be performed between this object - and the object one in MeshConfig - properties: - distribute: - description: 'Optional: only one of distribute - or failover can be set. Explicitly specify loadbalancing - weight across different zones and geographical - locations. Refer to [Locality weighted load - balancing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight) - If empty, the locality weight is set according - to the endpoints number within it.' - items: - description: 'Describes how traffic originating - in the ''from'' zone or sub-zone is distributed - over a set of ''to'' zones. Syntax for specifying - a zone is {region}/{zone}/{sub-zone} and terminal - wildcards are allowed on any segment of the - specification. Examples: * - matches all localities - us-west/* - all zones and sub-zones within - the us-west region us-west/zone-1/* - all - sub-zones within us-west/zone-1' - properties: - from: - description: Originating locality, '/' separated, - e.g. 'region/zone/sub_zone'. - type: string - to: - additionalProperties: - format: int32 - type: integer - description: Map of upstream localities - to traffic distribution weights. The sum - of all weights should be == 100. Any locality - not assigned a weight will receive no - traffic. - type: object - type: object - type: array - enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. e.g. true means that - turn on locality load balancing for this DestinationRule - no matter what mesh wide settings is. - properties: - value: - description: The bool value. - type: boolean - type: object - failover: - description: 'Optional: only failover or distribute - can be set. Explicitly specify the region traffic - will land on when endpoints in local region - becomes unhealthy. Should be used together with - OutlierDetection to detect unhealthy endpoints. - Note: if no OutlierDetection specified, this - will not take effect.' - items: - description: Specify the traffic failover policy - across regions. Since zone and sub-zone failover - is supported by default this only needs to - be specified for regions when the operator - needs to constrain traffic failover so that - the default behavior of failing over to any - endpoint globally does not apply. This is - useful when failing over traffic across regions - would not improve service health or may need - to be restricted for other reasons like regulatory - controls. - properties: - from: - description: Originating region. - type: string - to: - description: Destination region the traffic - will fail over to when endpoints in the - 'from' region becomes unhealthy. - type: string - type: object - type: array - type: object - type: object - outlier_detection: - description: Settings controlling eviction of unhealthy - hosts from the load balancing pool - properties: - base_ejection_time: - description: 'Minimum ejection duration. A host will - remain ejected for a period equal to the product - of minimum ejection duration and the number of times - the host has been ejected. This technique allows - the system to automatically increase the ejection - period for unhealthy upstream servers. format: 1h/1m/1s/1ms. - MUST BE >=1ms. Default is 30s.' - properties: - nanos: - description: Signed fractions of a second at nanosecond - resolution of the span of time. Durations less - than one second are represented with a 0 `seconds` - field and a positive or negative `nanos` field. - For durations of one second or more, a non-zero - value for the `nanos` field must be of the same - sign as the `seconds` field. Must be from -999,999,999 - to +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span of time. - Must be from -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds are computed from: - 60 sec/min * 60 min/hr * 24 hr/day * 365.25 - days/year * 10000 years' - format: int64 - type: integer - type: object - consecutive_5xx_errors: - description: "Number of 5xx errors before a host is - ejected from the connection pool. When the upstream - host is accessed over an opaque TCP connection, - connect timeouts, connection error/failure and request - failure events qualify as a 5xx error. This feature - defaults to 5 but can be disabled by setting the - value to 0. \n Note that consecutive_gateway_errors - and consecutive_5xx_errors can be used separately - or together. Because the errors counted by consecutive_gateway_errors - are also included in consecutive_5xx_errors, if - the value of consecutive_gateway_errors is greater - than or equal to the value of consecutive_5xx_errors, - consecutive_gateway_errors will have no effect." - properties: - value: - description: The uint32 value. - format: int32 - type: integer - type: object - consecutive_errors: - description: Number of errors before a host is ejected - from the connection pool. Defaults to 5. When the - upstream host is accessed over HTTP, a 502, 503, - or 504 return code qualifies as an error. When the - upstream host is accessed over an opaque TCP connection, - connect timeouts and connection error/failure events - qualify as an error. $hide_from_docs - format: int32 - type: integer - consecutive_gateway_errors: - description: "Number of gateway errors before a host - is ejected from the connection pool. When the upstream - host is accessed over HTTP, a 502, 503, or 504 return - code qualifies as a gateway error. When the upstream - host is accessed over an opaque TCP connection, - connect timeouts and connection error/failure events - qualify as a gateway error. This feature is disabled - by default or when set to the value 0. \n Note that - consecutive_gateway_errors and consecutive_5xx_errors - can be used separately or together. Because the - errors counted by consecutive_gateway_errors are - also included in consecutive_5xx_errors, if the - value of consecutive_gateway_errors is greater than - or equal to the value of consecutive_5xx_errors, - consecutive_gateway_errors will have no effect." - properties: - value: - description: The uint32 value. - format: int32 - type: integer - type: object - interval: - description: 'Time interval between ejection sweep - analysis. format: 1h/1m/1s/1ms. MUST BE >=1ms. Default - is 10s.' - properties: - nanos: - description: Signed fractions of a second at nanosecond - resolution of the span of time. Durations less - than one second are represented with a 0 `seconds` - field and a positive or negative `nanos` field. - For durations of one second or more, a non-zero - value for the `nanos` field must be of the same - sign as the `seconds` field. Must be from -999,999,999 - to +999,999,999 inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span of time. - Must be from -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds are computed from: - 60 sec/min * 60 min/hr * 24 hr/day * 365.25 - days/year * 10000 years' - format: int64 - type: integer - type: object - max_ejection_percent: - description: Maximum % of hosts in the load balancing - pool for the upstream service that can be ejected. - Defaults to 10%. - format: int32 - type: integer - min_health_percent: - description: Outlier detection will be enabled as - long as the associated load balancing pool has at - least min_health_percent hosts in healthy mode. - When the percentage of healthy hosts in the load - balancing pool drops below this threshold, outlier - detection will be disabled and the proxy will load - balance across all hosts in the pool (healthy and - unhealthy). The threshold can be disabled by setting - it to 0%. The default is 0% as it's not typically - applicable in k8s environments with few pods per - service. - format: int32 - type: integer - type: object - port_level_settings: - description: Traffic policies specific to individual ports. - Note that port level settings will override the destination-level - settings. Traffic settings specified at the destination-level - will not be inherited when overridden by port-level - settings, i.e. default values will be applied to fields - omitted in port-level traffic policies. - items: - description: Traffic policies that apply to specific - ports of the service - properties: - connection_pool: - description: Settings controlling the volume of - connections to an upstream service - properties: - http: - description: HTTP connection pool settings. - properties: - h2_upgrade_policy: - description: Specify if http1.1 connection - should be upgraded to http2 for the associated - destination. - format: int32 - type: integer - http1_max_pending_requests: - description: Maximum number of pending HTTP - requests to a destination. Default 2^32-1. - format: int32 - type: integer - http2_max_requests: - description: Maximum number of requests - to a backend. Default 2^32-1. - format: int32 - type: integer - idle_timeout: - description: The idle timeout for upstream - connection pool connections. The idle - timeout is defined as the period in which - there are no active requests. If not set, - the default is 1 hour. When the idle timeout - is reached the connection will be closed. - Note that request based timeouts mean - that HTTP/2 PINGs will not keep the connection - alive. Applies to both HTTP1.1 and HTTP2 - connections. - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span - of time. Durations less than one second - are represented with a 0 `seconds` - field and a positive or negative `nanos` - field. For durations of one second - or more, a non-zero value for the - `nanos` field must be of the same - sign as the `seconds` field. Must - be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the - span of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: - these bounds are computed from: 60 - sec/min * 60 min/hr * 24 hr/day * - 365.25 days/year * 10000 years' - format: int64 - type: integer - type: object - max_requests_per_connection: - description: Maximum number of requests - per connection to a backend. Setting this - parameter to 1 disables keep alive. Default - 0, meaning "unlimited", up to 2^29. - format: int32 - type: integer - max_retries: - description: Maximum number of retries that - can be outstanding to all hosts in a cluster - at a given time. Defaults to 2^32-1. - format: int32 - type: integer - type: object - tcp: - description: Settings common to both HTTP and - TCP upstream connections. - properties: - connect_timeout: - description: 'TCP connection timeout. format: - 1h/1m/1s/1ms. MUST BE >=1ms. Default is - 10s.' - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span - of time. Durations less than one second - are represented with a 0 `seconds` - field and a positive or negative `nanos` - field. For durations of one second - or more, a non-zero value for the - `nanos` field must be of the same - sign as the `seconds` field. Must - be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the - span of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: - these bounds are computed from: 60 - sec/min * 60 min/hr * 24 hr/day * - 365.25 days/year * 10000 years' - format: int64 - type: integer - type: object - max_connections: - description: Maximum number of HTTP1 /TCP - connections to a destination host. Default - 2^32-1. - format: int32 - type: integer - tcp_keepalive: - description: If set then set SO_KEEPALIVE - on the socket to enable TCP Keepalives. - properties: - interval: - description: The time duration between - keep-alive probes. Default is to use - the OS level configuration (unless - overridden, Linux defaults to 75s.) - properties: - nanos: - description: Signed fractions of - a second at nanosecond resolution - of the span of time. Durations - less than one second are represented - with a 0 `seconds` field and a - positive or negative `nanos` field. - For durations of one second or - more, a non-zero value for the - `nanos` field must be of the same - sign as the `seconds` field. Must - be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of - the span of time. Must be from - -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds - are computed from: 60 sec/min - * 60 min/hr * 24 hr/day * 365.25 - days/year * 10000 years' - format: int64 - type: integer - type: object - probes: - description: Maximum number of keepalive - probes to send without response before - deciding the connection is dead. Default - is to use the OS level configuration - (unless overridden, Linux defaults - to 9.) - format: int32 - type: integer - time: - description: The time duration a connection - needs to be idle before keep-alive - probes start being sent. Default is - to use the OS level configuration - (unless overridden, Linux defaults - to 7200s (ie 2 hours.) - properties: - nanos: - description: Signed fractions of - a second at nanosecond resolution - of the span of time. Durations - less than one second are represented - with a 0 `seconds` field and a - positive or negative `nanos` field. - For durations of one second or - more, a non-zero value for the - `nanos` field must be of the same - sign as the `seconds` field. Must - be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of - the span of time. Must be from - -315,576,000,000 to +315,576,000,000 - inclusive. Note: these bounds - are computed from: 60 sec/min - * 60 min/hr * 24 hr/day * 365.25 - days/year * 10000 years' - format: int64 - type: integer - type: object - type: object - type: object - type: object - load_balancer: - description: Settings controlling the load balancer - algorithms. - properties: - locality_lb_setting: - description: Locality load balancer settings, - this will override mesh wide settings in entirety, - meaning no merging would be performed between - this object and the object one in MeshConfig - properties: - distribute: - description: 'Optional: only one of distribute - or failover can be set. Explicitly specify - loadbalancing weight across different - zones and geographical locations. Refer - to [Locality weighted load balancing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight) - If empty, the locality weight is set according - to the endpoints number within it.' - items: - description: 'Describes how traffic originating - in the ''from'' zone or sub-zone is - distributed over a set of ''to'' zones. - Syntax for specifying a zone is {region}/{zone}/{sub-zone} - and terminal wildcards are allowed on - any segment of the specification. Examples: - * - matches all localities us-west/* - - all zones and sub-zones within the - us-west region us-west/zone-1/* - all - sub-zones within us-west/zone-1' - properties: - from: - description: Originating locality, - '/' separated, e.g. 'region/zone/sub_zone'. - type: string - to: - additionalProperties: - format: int32 - type: integer - description: Map of upstream localities - to traffic distribution weights. - The sum of all weights should be - == 100. Any locality not assigned - a weight will receive no traffic. - type: object - type: object - type: array - enabled: - description: enable locality load balancing, - this is DestinationRule-level and will - override mesh wide settings in entirety. - e.g. true means that turn on locality - load balancing for this DestinationRule - no matter what mesh wide settings is. - properties: - value: - description: The bool value. - type: boolean - type: object - failover: - description: 'Optional: only failover or - distribute can be set. Explicitly specify - the region traffic will land on when endpoints - in local region becomes unhealthy. Should - be used together with OutlierDetection - to detect unhealthy endpoints. Note: if - no OutlierDetection specified, this will - not take effect.' - items: - description: Specify the traffic failover - policy across regions. Since zone and - sub-zone failover is supported by default - this only needs to be specified for - regions when the operator needs to constrain - traffic failover so that the default - behavior of failing over to any endpoint - globally does not apply. This is useful - when failing over traffic across regions - would not improve service health or - may need to be restricted for other - reasons like regulatory controls. - properties: - from: - description: Originating region. - type: string - to: - description: Destination region the - traffic will fail over to when endpoints - in the 'from' region becomes unhealthy. - type: string - type: object - type: array - type: object - type: object - outlier_detection: - description: Settings controlling eviction of unhealthy - hosts from the load balancing pool - properties: - base_ejection_time: - description: 'Minimum ejection duration. A host - will remain ejected for a period equal to - the product of minimum ejection duration and - the number of times the host has been ejected. - This technique allows the system to automatically - increase the ejection period for unhealthy - upstream servers. format: 1h/1m/1s/1ms. MUST - BE >=1ms. Default is 30s.' - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span of - time. Durations less than one second are - represented with a 0 `seconds` field and - a positive or negative `nanos` field. - For durations of one second or more, a - non-zero value for the `nanos` field must - be of the same sign as the `seconds` field. - Must be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span - of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: these - bounds are computed from: 60 sec/min * - 60 min/hr * 24 hr/day * 365.25 days/year - * 10000 years' - format: int64 - type: integer - type: object - consecutive_5xx_errors: - description: "Number of 5xx errors before a - host is ejected from the connection pool. - When the upstream host is accessed over an - opaque TCP connection, connect timeouts, connection - error/failure and request failure events qualify - as a 5xx error. This feature defaults to 5 - but can be disabled by setting the value to - 0. \n Note that consecutive_gateway_errors - and consecutive_5xx_errors can be used separately - or together. Because the errors counted by - consecutive_gateway_errors are also included - in consecutive_5xx_errors, if the value of - consecutive_gateway_errors is greater than - or equal to the value of consecutive_5xx_errors, - consecutive_gateway_errors will have no effect." - properties: - value: - description: The uint32 value. - format: int32 - type: integer - type: object - consecutive_errors: - description: Number of errors before a host - is ejected from the connection pool. Defaults - to 5. When the upstream host is accessed over - HTTP, a 502, 503, or 504 return code qualifies - as an error. When the upstream host is accessed - over an opaque TCP connection, connect timeouts - and connection error/failure events qualify - as an error. $hide_from_docs - format: int32 - type: integer - consecutive_gateway_errors: - description: "Number of gateway errors before - a host is ejected from the connection pool. - When the upstream host is accessed over HTTP, - a 502, 503, or 504 return code qualifies as - a gateway error. When the upstream host is - accessed over an opaque TCP connection, connect - timeouts and connection error/failure events - qualify as a gateway error. This feature is - disabled by default or when set to the value - 0. \n Note that consecutive_gateway_errors - and consecutive_5xx_errors can be used separately - or together. Because the errors counted by - consecutive_gateway_errors are also included - in consecutive_5xx_errors, if the value of - consecutive_gateway_errors is greater than - or equal to the value of consecutive_5xx_errors, - consecutive_gateway_errors will have no effect." - properties: - value: - description: The uint32 value. - format: int32 - type: integer - type: object - interval: - description: 'Time interval between ejection - sweep analysis. format: 1h/1m/1s/1ms. MUST - BE >=1ms. Default is 10s.' - properties: - nanos: - description: Signed fractions of a second - at nanosecond resolution of the span of - time. Durations less than one second are - represented with a 0 `seconds` field and - a positive or negative `nanos` field. - For durations of one second or more, a - non-zero value for the `nanos` field must - be of the same sign as the `seconds` field. - Must be from -999,999,999 to +999,999,999 - inclusive. - format: int32 - type: integer - seconds: - description: 'Signed seconds of the span - of time. Must be from -315,576,000,000 - to +315,576,000,000 inclusive. Note: these - bounds are computed from: 60 sec/min * - 60 min/hr * 24 hr/day * 365.25 days/year - * 10000 years' - format: int64 - type: integer - type: object - max_ejection_percent: - description: Maximum % of hosts in the load - balancing pool for the upstream service that - can be ejected. Defaults to 10%. - format: int32 - type: integer - min_health_percent: - description: Outlier detection will be enabled - as long as the associated load balancing pool - has at least min_health_percent hosts in healthy - mode. When the percentage of healthy hosts - in the load balancing pool drops below this - threshold, outlier detection will be disabled - and the proxy will load balance across all - hosts in the pool (healthy and unhealthy). - The threshold can be disabled by setting it - to 0%. The default is 0% as it's not typically - applicable in k8s environments with few pods - per service. - format: int32 - type: integer - type: object - port: - description: Specifies the number of a port on the - destination service on which this policy is being - applied. - properties: - number: - description: Valid port number - format: int32 - type: integer - type: object - tls: - description: TLS related settings for connections - to the upstream service. - properties: - ca_certificates: - description: 'OPTIONAL: The path to the file - containing certificate authority certificates - to use in verifying a presented server certificate. - If omitted, the proxy will not verify the - server''s certificate. Should be empty if - mode is `ISTIO_MUTUAL`.' - type: string - client_certificate: - description: REQUIRED if mode is `MUTUAL`. The - path to the file holding the client-side TLS - certificate to use. Should be empty if mode - is `ISTIO_MUTUAL`. - type: string - credential_name: - description: 'The name of the secret that holds - the TLS certs for the client including the - CA certificates. Applicable only on Kubernetes. - Secret must exist in the same namespace with - the proxy using the certificates. The secret - (of type `generic`)should contain the following - keys and values: `key: `, `cert: - `, `cacert: `. - Secret of type tls for client certificates - along with ca.crt key for CA certificates - is also supported. Only one of client certificates - and CA certificate or credentialName can be - specified.' - type: string - mode: - description: Indicates whether connections to - this port should be secured using TLS. The - value of this field determines how TLS is - enforced. - format: int32 - type: integer - private_key: - description: REQUIRED if mode is `MUTUAL`. The - path to the file holding the client's private - key. Should be empty if mode is `ISTIO_MUTUAL`. - type: string - sni: - description: SNI string to present to the server - during TLS handshake. - type: string - subject_alt_names: - description: A list of alternate names to verify - the subject identity in the certificate. If - specified, the proxy will verify that the - server certificate's subject alt name matches - one of the specified values. If specified, - this list overrides the value of subject_alt_names - from the ServiceEntry. - items: - type: string - type: array - type: object - type: object - type: array - tls: - description: TLS related settings for connections to the - upstream service. - properties: - ca_certificates: - description: 'OPTIONAL: The path to the file containing - certificate authority certificates to use in verifying - a presented server certificate. If omitted, the - proxy will not verify the server''s certificate. - Should be empty if mode is `ISTIO_MUTUAL`.' - type: string - client_certificate: - description: REQUIRED if mode is `MUTUAL`. The path - to the file holding the client-side TLS certificate - to use. Should be empty if mode is `ISTIO_MUTUAL`. - type: string - credential_name: - description: 'The name of the secret that holds the - TLS certs for the client including the CA certificates. - Applicable only on Kubernetes. Secret must exist - in the same namespace with the proxy using the certificates. - The secret (of type `generic`)should contain the - following keys and values: `key: `, - `cert: `, `cacert: `. - Secret of type tls for client certificates along - with ca.crt key for CA certificates is also supported. - Only one of client certificates and CA certificate - or credentialName can be specified.' - type: string - mode: - description: Indicates whether connections to this - port should be secured using TLS. The value of this - field determines how TLS is enforced. - format: int32 - type: integer - private_key: - description: REQUIRED if mode is `MUTUAL`. The path - to the file holding the client's private key. Should - be empty if mode is `ISTIO_MUTUAL`. - type: string - sni: - description: SNI string to present to the server during - TLS handshake. - type: string - subject_alt_names: - description: A list of alternate names to verify the - subject identity in the certificate. If specified, - the proxy will verify that the server certificate's - subject alt name matches one of the specified values. - If specified, this list overrides the value of subject_alt_names - from the ServiceEntry. - items: - type: string - type: array - type: object - type: object - type: object - lifecycle: - description: Lifecycle describes actions that the management system - should take in response to container lifecycle events. For the - PostStart and PreStop lifecycle handlers, management of the - container blocks until the action is complete, unless the container - process fails, in which case the handler is aborted. - properties: - postStart: - description: 'PostStart is called immediately after a container - is created. If the handler fails, the container is terminated - and restarted according to its restart policy. Other management - of the container blocks until the hook completes. More info: - https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', - etc) won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range 1 - to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range 1 - to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a container - is terminated due to an API request or management event - such as liveness/startup probe failure, preemption, resource - contention, etc. The handler is not called if the container - crashes or exits. The reason for termination is passed to - the handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will eventually - terminate within the Pod''s termination grace period. Other - management of the container blocks until the hook completes - or until the termination grace period is reached. More info: - https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', - etc) won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range 1 - to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range 1 - to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - type: object - type: object - livenessProbe: - description: Probe describes a health check to be performed against - a container to determine whether it is alive or ready to receive - traffic. - properties: - exec: - description: One and only one of the following should be specified. - Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute inside - the container, the working directory for the command is - root ('/') in the container's filesystem. The command - is simply exec'd, it is not run inside a shell, so traditional - shell instructions ('|', etc) won't work. To use a shell, - you need to explicitly call out to that shell. Exit - status of 0 is treated as live/healthy and non-zero - is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe to - be considered failed after having succeeded. Defaults to - 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header to - be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access on the - container. Number must be in the range 1 to 65535. Name - must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has started - before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to - be considered successful after having failed. Defaults to - 1. Must be 1 for liveness and startup. Minimum value is - 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving a TCP - port. TCP hooks not yet supported TODO: implement a realistic - TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access on the - container. Number must be in the range 1 to 65535. Name - must be an IANA_SVC_NAME. - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - type: string - podAnnotations: - additionalProperties: - type: string - type: object - ports: - items: - properties: - containerPort: - format: int32 - type: integer - default: - description: 'Default denotes that this port will receive - the default hostnames for the service. This is only useful - if a service exposes multiple ports over the same ingress - gateway (mode: public or private). If only one port is - exposed, it will be the default port. If multiple ports - are exposed and no default is specified and a port with - the `http` name is present, it will become the default - port. If multiple ports are specified and the `http` port - is not present, validation will fail. Only Mode == (private|public) - use the default flag, as they are trafficked through the - same external port. Internal ports can have the same hostnames - since they can be selected by port number.' - type: boolean - hosts: - items: - type: string - type: array - ingressPort: - format: int32 - type: integer - ingresses: - items: - type: string - type: array - istio: - properties: - http: - properties: - retries: - properties: - attempts: - format: int32 - type: integer - perTryTimeout: - type: string - retryOn: - type: string - type: object - timeout: - type: string - type: object - type: object - mode: - type: string - name: - type: string - port: - format: int32 - type: integer - protocol: - description: Protocol defines network protocols supported - for things like container ports. - type: string - required: - - mode - - name - type: object - type: array - priorityClassName: - type: string - readinessProbe: - description: Probe describes a health check to be performed against - a container to determine whether it is alive or ready to receive - traffic. - properties: - exec: - description: One and only one of the following should be specified. - Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute inside - the container, the working directory for the command is - root ('/') in the container's filesystem. The command - is simply exec'd, it is not run inside a shell, so traditional - shell instructions ('|', etc) won't work. To use a shell, - you need to explicitly call out to that shell. Exit - status of 0 is treated as live/healthy and non-zero - is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe to - be considered failed after having succeeded. Defaults to - 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header to - be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access on the - container. Number must be in the range 1 to 65535. Name - must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has started - before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to - be considered successful after having failed. Defaults to - 1. Must be 1 for liveness and startup. Minimum value is - 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving a TCP - port. TCP hooks not yet supported TODO: implement a realistic - TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access on the - container. Number must be in the range 1 to 65535. Name - must be an IANA_SVC_NAME. - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - release: - properties: - eligible: - type: boolean - geometricScaling: - properties: - delay: - type: string - factor: - format: int32 - type: integer - start: - format: int32 - type: integer - type: object - linearScaling: - properties: - delay: - type: string - increment: - format: int32 - type: integer - type: object - max: - format: int32 - type: integer - scalingStrategy: - type: string - schedule: - type: string - ttl: - format: int64 - type: integer - type: object - resources: - description: ResourceRequirements describes the compute resource - requirements. - properties: - limits: - additionalProperties: - type: string - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - type: string - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - scale: - properties: - default: - format: int32 - type: integer - max: - format: int32 - type: integer - min: - format: int32 - type: integer - minReadySeconds: - format: int32 - type: integer - requestsRateMetric: - description: 'RequestsRateMetric refers to a Prometheus Adapter - metric. See: https://github.com/DirectXMan12/k8s-prometheus-adapter' - type: string - targetCPUUtilizationPercentage: - description: TargetCPUUtilizationPercentage scales based on - CPU percentage - format: int32 - type: integer - targetMemoryUtilizationPercentage: - description: TargetMemoryUtilizationPercentage scales based - on Memory percentage - format: int32 - type: integer - targetRequestsRate: - description: TargetRequestsRate scales based on the specified - RequestsRateMetric - type: string - worker: - description: Worker specifies parameters for Worker Pod Autoscaler. - See https://github.com/practo/k8s-worker-pod-autoscaler - properties: - maxDisruption: - type: string - queueUri: - type: string - secondsToProcessOneJobString: - type: string - targetMessagesPerWorker: - format: int32 - type: integer - required: - - maxDisruption - - queueUri - - targetMessagesPerWorker - type: object - type: object - serviceAccountName: - type: string - serviceLevelObjectiveLabels: - properties: - alertLabels: - additionalProperties: - type: string - type: object - ruleLabels: - additionalProperties: - type: string - type: object - serviceLevelLabels: - additionalProperties: - type: string - type: object - type: object - serviceLevelObjectives: - items: - properties: - annotations: - additionalProperties: - type: string - type: object - description: - type: string - enabled: - type: boolean - name: - type: string - objectivePercentString: - type: string - serviceLevelIndicator: - properties: - alertAfter: - type: string - canary: - properties: - allowancePercent: {} - allowancePercentString: - type: string - enabled: - type: boolean - failAfter: - type: string - required: - - enabled - type: object - errorQuery: - type: string - tagKey: - type: string - totalQuery: - type: string - type: object - serviceLevelObjectiveLabels: - properties: - alertLabels: - additionalProperties: - type: string - type: object - ruleLabels: - additionalProperties: - type: string - type: object - serviceLevelLabels: - additionalProperties: - type: string - type: object - type: object - required: - - enabled - type: object - type: array - serviceMonitors: - items: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - name: - type: string - sloRegex: - description: if true, and the Spec.Endpoints.MetricRelabelConfigs - does not specify a regex, will replace the regex with - a list of SLO metric names - type: boolean - spec: - description: ServiceMonitorSpec contains specification parameters - for a ServiceMonitor. - properties: - endpoints: - description: A list of endpoints allowed as part of - this ServiceMonitor. - items: - description: Endpoint defines a scrapeable endpoint - serving Prometheus metrics. - properties: - basicAuth: - description: 'BasicAuth allow an endpoint to authenticate - over basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints' - properties: - password: - description: The secret in the service monitor - namespace that contains the password for - authentication. - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - username: - description: The secret in the service monitor - namespace that contains the username for - authentication. - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - bearerTokenFile: - description: File to read bearer token for scraping - targets. - type: string - bearerTokenSecret: - description: Secret to mount to read bearer token - for scraping targets. The secret needs to be - in the same namespace as the service monitor - and accessible by the Prometheus Operator. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - required: - - key - type: object - honorLabels: - description: HonorLabels chooses the metric's - labels on collisions with target labels. - type: boolean - honorTimestamps: - description: HonorTimestamps controls whether - Prometheus respects the timestamps present in - scraped data. - type: boolean - interval: - description: Interval at which metrics should - be scraped - type: string - metricRelabelings: - description: MetricRelabelConfigs to apply to - samples before ingestion. - items: - description: 'RelabelConfig allows dynamic rewriting - of the label set, being applied to samples - before ingestion. It defines ``-section - of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - description: Action to perform based on - regex matching. Default is 'replace' - type: string - modulus: - description: Modulus to take of the hash - of the source label values. - format: int64 - type: integer - regex: - description: Regular expression against - which the extracted value is matched. - Default is '(.*)' - type: string - replacement: - description: Replacement value against which - a regex replace is performed if the regular - expression matches. Regex capture groups - are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated - source label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values - from existing labels. Their content is - concatenated using the configured separator - and matched against the configured regular - expression for the replace, keep, and - drop actions. - items: - type: string - type: array - targetLabel: - description: Label to which the resulting - value is written in a replace action. - It is mandatory for replace actions. Regex - capture groups are available. - type: string - type: object - type: array - params: - additionalProperties: - items: - type: string - type: array - description: Optional HTTP URL parameters - type: object - path: - description: HTTP path to scrape for metrics. - type: string - port: - description: Name of the service port this endpoint - refers to. Mutually exclusive with targetPort. - type: string - proxyUrl: - description: ProxyURL eg http://proxyserver:2195 - Directs scrapes to proxy through this endpoint. - type: string - relabelings: - description: 'RelabelConfigs to apply to samples - before scraping. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' - items: - description: 'RelabelConfig allows dynamic rewriting - of the label set, being applied to samples - before ingestion. It defines ``-section - of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - description: Action to perform based on - regex matching. Default is 'replace' - type: string - modulus: - description: Modulus to take of the hash - of the source label values. - format: int64 - type: integer - regex: - description: Regular expression against - which the extracted value is matched. - Default is '(.*)' - type: string - replacement: - description: Replacement value against which - a regex replace is performed if the regular - expression matches. Regex capture groups - are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated - source label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values - from existing labels. Their content is - concatenated using the configured separator - and matched against the configured regular - expression for the replace, keep, and - drop actions. - items: - type: string - type: array - targetLabel: - description: Label to which the resulting - value is written in a replace action. - It is mandatory for replace actions. Regex - capture groups are available. - type: string - type: object - type: array - scheme: - description: HTTP scheme to use for scraping. - type: string - scrapeTimeout: - description: Timeout after which the scrape is - ended - type: string - targetPort: - anyOf: - - type: string - - type: integer - description: Name or number of the pod port this - endpoint refers to. Mutually exclusive with - port. - tlsConfig: - description: TLS configuration to use when scraping - the endpoint - properties: - ca: - description: Stuct containing the CA cert - to use for the targets. - properties: - configMap: - description: ConfigMap containing data - to use for the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - secret: - description: Secret containing data to - use for the targets. - properties: - key: - description: The key of the secret - to select from. Must be a valid - secret key. - type: string - name: - description: 'Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - caFile: - description: Path to the CA cert in the Prometheus - container to use for the targets. - type: string - cert: - description: Struct containing the client - cert file for the targets. - properties: - configMap: - description: ConfigMap containing data - to use for the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - secret: - description: Secret containing data to - use for the targets. - properties: - key: - description: The key of the secret - to select from. Must be a valid - secret key. - type: string - name: - description: 'Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - certFile: - description: Path to the client cert file - in the Prometheus container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in - the Prometheus container for the targets. - type: string - keySecret: - description: Secret containing the client - key file for the targets. - properties: - key: - description: The key of the secret to - select from. Must be a valid secret - key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - serverName: - description: Used to verify the hostname for - the targets. - type: string - type: object - type: object - type: array - jobLabel: - description: The label to use to retrieve the job name - from. - type: string - namespaceSelector: - description: Selector to select which namespaces the - Endpoints objects are discovered from. - properties: - any: - description: Boolean describing whether all namespaces - are selected in contrast to a list restricting - them. - type: boolean - matchNames: - description: List of namespace names. - items: - type: string - type: array - type: object - podTargetLabels: - description: PodTargetLabels transfers labels on the - Kubernetes Pod onto the target. - items: - type: string - type: array - sampleLimit: - description: SampleLimit defines per-scrape limit on - number of scraped samples that will be accepted. - format: int64 - type: integer - selector: - description: Selector to select Endpoints objects. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - targetLabels: - description: TargetLabels transfers labels on the Kubernetes - Service onto the target. - items: - type: string - type: array - required: - - endpoints - - selector - type: object - required: - - name - - sloRegex - type: object - type: array - sidecars: - items: - description: A single application container that you want to - run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. The $(VAR_NAME) syntax - can be escaped with a double $$, ie: $$(VAR_NAME). Escaped - references will never be expanded, regardless of whether - the variable exists or not. Cannot be updated. More info: - https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not - provided. Variable references $(VAR_NAME) are expanded - using the container''s environment. If a variable cannot - be resolved, the reference in the input string will be - unchanged. The $(VAR_NAME) syntax can be escaped with - a double $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will never - be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in - the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - description: Specifies the output format of - the exposed resources, defaults to "1" - type: string - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported as - an event when the container is starting. When a key exists - in multiple sources, the value associated with the last - source will take precedence. Values defined by an Env - with a duplicate key will take precedence. Cannot be updated. - items: - description: EnvFromSource represents the source of a - set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret must be - defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management - to default or override container images in workload controllers - like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent - otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should take - in response to container lifecycle events. Cannot be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according to - its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a - container is terminated due to an API request or management - event such as liveness/startup probe failure, preemption, - resource contention, etc. The handler is not called - if the container crashes or exits. The reason for - termination is passed to the handler. The Pod''s termination - grace period countdown begins before the PreStop hooked - is executed. Regardless of the outcome of the handler, - the container will eventually terminate within the - Pod''s termination grace period. Other management - of the container blocks until the hook completes or - until the termination grace period is reached. More - info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. - items: - description: ContainerPort represents a network port in - a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, 0 - < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in a - pod must have a unique name. Name for the port that - can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if the - probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - properties: - limits: - additionalProperties: - type: string - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - type: string - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: 'Security options the pod should run with. - More info: https://kubernetes.io/docs/concepts/policy/security-context/ - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if - it does. If unset or false, no such validation will - be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & - container level, the container options override the - pod options. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. - The profile must be preconfigured on the node - to work. Must be a descending path, relative to - the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n - Localhost - a profile defined in a file on the - node should be used. RuntimeDefault - the container - runtime default profile should be used. Unconfined - - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has successfully - initialized. If specified, no other probes are executed - until this completes successfully. If this probe fails, - the Pod will be restarted, just as if the livenessProbe - failed. This can be used to provide different probe parameters - at the beginning of a Pod''s lifecycle, when it might - take a long time to load data or warm a cache, than during - steady-state operation. This cannot be updated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: string - - type: integer - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: string - - type: integer - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a buffer - for stdin in the container runtime. If this is not set, - reads from stdin in the container will always result in - EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is empty - until the first client attaches to stdin, and then remains - open and accepts data until the client disconnects, at - which time stdin is closed and remains closed until the - container is restarted. If this flag is false, a container - processes that reads from stdin will never receive an - EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written is - mounted into the container''s filesystem. Message written - is intended to be brief final status, such as an assertion - failure message. Will be truncated by the node if greater - than 4096 bytes. The total message length across all containers - will be limited to 12kb. Defaults to /dev/termination-log. - Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last chunk - of container log output if the termination message file - is empty and the container exited with an error. The log - output is limited to 2048 bytes or 80 lines, whichever - is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a TTY - for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the - volume should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and the - other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults to - "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the container's - environment. Defaults to "" (volume's root). SubPathExpr - and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which might - be configured in the container image. Cannot be updated. - type: string - required: - - name - type: object - type: array - tolerations: - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - volumeMounts: - items: - description: VolumeMount describes a mounting of a Volume within - a container. - properties: - mountPath: - description: Path within the container at which the volume - should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are - propagated from the host to container and the other way - around. When not set, MountPropagationNone is used. This - field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which - the container's volume should be mounted. Behaves similarly - to SubPath but environment variable references $(VAR_NAME) - are expanded using the container's environment. Defaults - to "" (volume's root). SubPathExpr and SubPath are mutually - exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' - format: int32 - type: integer - readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: AzureDisk represents an Azure Data Disk mount - on the host and bind mount to the pod. - properties: - cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' - type: string - diskName: - description: The Name of the data disk in the blob storage - type: string - diskURI: - description: The URI the data disk in the blob storage - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults - to shared' - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: AzureFile represents an Azure File Service - mount on the host and bind mount to the pod. - properties: - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: the name of secret that contains Azure - Storage Account Name and Key - type: string - shareName: - description: Share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: CephFS represents a Ceph FS mount on the host - that shares a pod's lifetime - properties: - monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'Cinder represents a cinder volume attached - and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: ConfigMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. - Paths must be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path within a - volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its keys - must be defined - type: boolean - type: object - csi: - description: CSI (Container Storage Interface) represents - ephemeral storage that is handled by certain external - CSI drivers (Beta feature). - properties: - driver: - description: Driver is the name of the CSI driver that - handles this volume. Consult with your admin for the - correct name as registered in the cluster. - type: string - fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. - type: string - nodePublishSecretRef: - description: NodePublishSecretRef is a reference to - the secret object containing sensitive information - to pass to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the - secret object contains more than one secret, all secret - references are passed. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: VolumeAttributes stores driver-specific - properties that are passed to the CSI driver. Consult - your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: DownwardAPI represents downward API about the - pod that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a Optional: mode bits used - to set permissions on created files by default. Must - be an octal value between 0000 and 0777 or a decimal - value between 0 and 511. YAML accepts both octal and - decimal values, JSON requires decimal values for mode - bits. Defaults to 0644. Directories within the path - are not affected by this setting. This might be in - conflict with other options that affect the file mode, - like fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in - the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits used to set - permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must not - be absolute or contain the ''..'' path. Must - be utf-8 encoded. The first item of the relative - path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - description: Specifies the output format of - the exposed resources, defaults to "1" - type: string - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'EmptyDir represents a temporary directory - that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' - type: string - type: object - ephemeral: - description: "Ephemeral represents a volume that is handled - by a cluster storage driver (Alpha feature). The volume's - lifecycle is tied to the pod that defines it - it will - be created before the pod starts, and deleted when the - pod is removed. \n Use this if: a) the volume is only - needed while the pod runs, b) features of normal volumes - like restoring from snapshot or capacity tracking are - needed, c) the storage driver is specified through a storage - class, and d) the storage driver supports dynamic volume - provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between this - volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim - or one of the vendor-specific APIs for volumes that persist - for longer than the lifecycle of an individual pod. \n - Use CSI for light-weight local ephemeral volumes if the - CSI driver is meant to be used that way - see the documentation - of the driver for more information. \n A pod can use both - types of ephemeral volumes and persistent volumes at the - same time." - properties: - readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). - type: boolean - volumeClaimTemplate: - description: "Will be used to create a stand-alone PVC - to provision the volume. The pod in which this EphemeralVolumeSource - is embedded will be the owner of the PVC, i.e. the - PVC will be deleted together with the pod. The name - of the PVC will be `-` where - `` is the name from the `PodSpec.Volumes` - array entry. Pod validation will reject the pod if - the concatenated name is not valid for a PVC (for - example, too long). \n An existing PVC with that name - that is not owned by the pod will *not* be used for - the pod to avoid using an unrelated volume by mistake. - Starting the pod is then blocked until the unrelated - PVC is removed. If such a pre-created PVC is meant - to be used by the pod, the PVC has to updated with - an owner reference to the pod once the pod exists. - Normally this should not be necessary, but it may - be useful when manually reconstructing a broken cluster. - \n This field is read-only and no changes will be - made by Kubernetes to the PVC after it has been created. - \n Required, must not be nil." - properties: - metadata: - description: May contain labels and annotations - that will be copied into the PVC when creating - it. No other fields are allowed and will be rejected - during validation. - type: object - spec: - description: The specification for the PersistentVolumeClaim. - The entire content is copied unchanged into the - PVC that gets created from this template. The - same fields as in a PersistentVolumeClaim are - also valid here. - properties: - accessModes: - description: 'AccessModes contains the desired - access modes the volume should have. More - info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) * - An existing custom resource that implements - data population (Alpha) In order to use custom - resource types that implement data population, - the AnyVolumeDataSource feature gate must - be enabled. If the provisioner or an external - controller can support the specified data - source, it will create a new volume based - on the contents of the specified data source.' - properties: - apiGroup: - description: APIGroup is the group for the - resource being referenced. If APIGroup - is not specified, the specified Kind must - be in the core API group. For any other - third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum - resources the volume should have. More info: - https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - type: string - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - type: string - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - selector: - description: A label query over volumes to consider - for binding. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of - volume is required by the claim. Value of - Filesystem is implied when not included in - claim spec. - type: string - volumeName: - description: VolumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: FC represents a Fibre Channel resource that - is attached to a kubelet's host machine and then exposed - to the pod. - properties: - fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' - type: string - lun: - description: 'Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' - items: - type: string - type: array - wwids: - description: 'Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs - and lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: FlexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: Driver is the name of the driver to use - for this volume. - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. - type: string - options: - additionalProperties: - type: string - description: 'Optional: Extra command options if any.' - type: object - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - required: - - driver - type: object - flocker: - description: Flocker represents a Flocker volume attached - to a kubelet's host machine. This depends on the Flocker - control service being running - properties: - datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated - type: string - datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource - that is attached to a kubelet''s host machine and then - exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More info: - https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'GitRepo represents a git repository at a particular - revision. DEPRECATED: GitRepo is deprecated. To provision - a container with a git repo, mount an EmptyDir into an - InitContainer that clones the repo using git, then mount - the EmptyDir into the Pod''s container.' - properties: - directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: Repository URL - type: string - revision: - description: Commit hash for the specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'Glusterfs represents a Glusterfs mount on - the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'Path is the Glusterfs volume path. More - info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'ReadOnly here will force the Glusterfs - volume to be mounted with read-only permissions. Defaults - to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'HostPath represents a pre-existing file or - directory on the host machine that is directly exposed - to the container. This is generally used for system agents - or other privileged things that are allowed to see the - host machine. Most containers will NOT need this. More - info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host - directory mounts and who can/can not mount host directories - as read/write.' - properties: - path: - description: 'Path of the directory on the host. If - the path is a symlink, it will follow the link to - the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'Type for HostPath Volume Defaults to "" - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'ISCSI represents an ISCSI Disk resource that - is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication - type: boolean - chapAuthSession: - description: whether support iSCSI Session CHAP authentication - type: boolean - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. - type: string - iqn: - description: Target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). - type: string - lun: - description: iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: ReadOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'NFS represents an NFS mount on the host that - shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults - to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address of - the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents - a reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host - machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - pdID: - description: ID that identifies Photon Controller persistent - disk - type: string - required: - - pdID - type: object - portworxVolume: - description: PortworxVolume represents a portworx volume - attached and mounted on kubelets host machine - properties: - fsType: - description: FSType represents the filesystem type to - mount Must be a filesystem type supported by the host - operating system. Ex. "ext4", "xfs". Implicitly inferred - to be "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: VolumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: Items for all in one resources secrets, configmaps, - and downward API - properties: - defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. - format: int32 - type: integer - sources: - description: list of volume projections - items: - description: Projection that may be projected along - with other supported volume types - properties: - configMap: - description: information about the configMap data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - ConfigMap will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed keys - will be projected into the specified paths, - and unlisted keys will not be present. If - a key is specified which is not present - in the ConfigMap, the volume setup will - error unless it is marked optional. Paths - must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain - the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - downwardAPI: - description: information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a field - of the pod: only annotations, labels, - name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema - the FieldPath is written in terms - of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to - select in the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits used - to set permissions on this file, must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file to - be created. Must not be absolute or - contain the ''..'' path. Must be utf-8 - encoded. The first item of the relative - path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of - the container: only resources limits - and requests (limits.cpu, limits.memory, - requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required - for volumes, optional for env - vars' - type: string - divisor: - description: Specifies the output - format of the exposed resources, - defaults to "1" - type: string - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - secret: - description: information about the secret data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - Secret will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed keys - will be projected into the specified paths, - and unlisted keys will not be present. If - a key is specified which is not present - in the Secret, the volume setup will error - unless it is marked optional. Paths must - be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain - the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - type: object - serviceAccountToken: - description: information about the serviceAccountToken - data to project - properties: - audience: - description: Audience is the intended audience - of the token. A recipient of a token must - identify itself with an identifier specified - in the audience of the token, and otherwise - should reject the token. The audience defaults - to the identifier of the apiserver. - type: string - expirationSeconds: - description: ExpirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, - the kubelet volume plugin will proactively - rotate the service account token. The kubelet - will start trying to rotate the token if - the token is older than 80 percent of its - time to live or if the token is older than - 24 hours.Defaults to 1 hour and must be - at least 10 minutes. - format: int64 - type: integer - path: - description: Path is the path relative to - the mount point of the file to project the - token into. - type: string - required: - - path - type: object - type: object - type: array - type: object - quobyte: - description: Quobyte represents a Quobyte mount on the host - that shares a pod's lifetime - properties: - group: - description: Group to map volume access to Default is - no group - type: string - readOnly: - description: ReadOnly here will force the Quobyte volume - to be mounted with read-only permissions. Defaults - to false. - type: boolean - registry: - description: Registry represents a single or multiple - Quobyte Registry services specified as a string as - host:port pair (multiple entries are separated with - commas) which acts as the central registry for volumes - type: string - tenant: - description: Tenant owning the given Quobyte volume - in the Backend Used with dynamically provisioned Quobyte - volumes, value is set by the plugin - type: string - user: - description: User to map volume access to Defaults to - serivceaccount user - type: string - volume: - description: Volume is a string that references an already - created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'RBD represents a Rados Block Device mount - on the host that shares a pod''s lifetime. More info: - https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'Keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'SecretRef is name of the authentication - secret for RBDUser. If provided overrides keyring. - Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: ScaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: The host address of the ScaleIO API Gateway. - type: string - protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef references to the secret for - ScaleIO user and other sensitive information. If this - is not provided, Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - sslEnabled: - description: Flag to enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. - type: string - storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. - type: string - system: - description: The name of the storage system as configured - in ScaleIO. - type: string - volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'Secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. - items: - description: Maps a string key to a path within a - volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: Specify whether the Secret or its keys - must be defined - type: boolean - secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: StorageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef specifies the secret to use for - obtaining the StorageOS API credentials. If not specified, - default values will be attempted. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeName: - description: VolumeName is the human-readable name of - the StorageOS volume. Volume names are only unique - within a namespace. - type: string - volumeNamespace: - description: VolumeNamespace specifies the scope of - the volume within StorageOS. If no namespace is specified - then the Pod's namespace will be used. This allows - the Kubernetes name scoping to be mirrored within - StorageOS for tighter integration. Set VolumeName - to any name to override the default behaviour. Set - to "default" if you are not using namespaces within - StorageOS. Namespaces that do not pre-exist within - StorageOS will be created. - type: string - type: object - vsphereVolume: - description: VsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. - type: string - volumePath: - description: Path that identifies vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - required: - - fleet - - name - - scale - type: object - type: array - required: - - app - - failed - - targets - type: object - status: - properties: - sentry: - properties: - release: - type: boolean - type: object - targets: - items: - description: RevisionStatus defines the observed state of Revision - properties: - name: - type: string - release: - properties: - currentPercent: - format: int32 - type: integer - peakPercent: - format: int32 - type: integer - required: - - currentPercent - - peakPercent - type: object - scale: - properties: - current: - format: int32 - type: integer - desired: - format: int32 - type: integer - peak: - format: int32 - type: integer - required: - - current - - desired - - peak - type: object - state: - type: string - required: - - name - - release - - scale - type: object - type: array - required: - - sentry - - targets - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/operator-noreplicas.yaml b/deploy/operator-noreplicas.yaml deleted file mode 100644 index 5d6aea0c..00000000 --- a/deploy/operator-noreplicas.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: picchu -spec: - replicas: 0 - selector: - matchLabels: - name: picchu - template: - metadata: - labels: - name: picchu - spec: - serviceAccountName: picchu - containers: - - name: picchu - # Replace this with the built image name - image: docker.medium.build/picchu - command: - - picchu - imagePullPolicy: Always - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "picchu" diff --git a/deploy/operator.yaml b/deploy/operator.yaml deleted file mode 100644 index 2308579e..00000000 --- a/deploy/operator.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: picchu -spec: - replicas: 1 - selector: - matchLabels: - name: picchu - template: - metadata: - labels: - name: picchu - spec: - serviceAccountName: picchu - containers: - - name: picchu - # Replace this with the built image name - image: docker.medium.build/picchu - command: - - picchu - imagePullPolicy: Always - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "picchu" diff --git a/go.mod b/go.mod index e73d5bbf..b79a3ef9 100644 --- a/go.mod +++ b/go.mod @@ -1,149 +1,101 @@ module go.medium.engineering/picchu -go 1.17 +go 1.19 -//require k8s.io/kubernetes v1.20.1 require ( - github.com/Medium/service-level-operator v0.4.0 github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 - github.com/coreos/prometheus-operator v0.34.0 - github.com/go-logr/logr v1.2.0 - github.com/go-logr/zapr v1.2.0 + github.com/go-logr/logr v1.2.3 + github.com/go-logr/zapr v1.2.3 github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 - github.com/google/uuid v1.1.2 - github.com/operator-framework/operator-sdk v0.13.0 - github.com/practo/k8s-worker-pod-autoscaler v1.1.1-0.20200722110630-c31dc858b6f9 - github.com/prometheus/client_golang v1.11.0 - github.com/prometheus/common v0.28.0 - github.com/prometheus/prometheus v2.3.2+incompatible - github.com/sergi/go-diff v1.2.0 // indirect - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.0 + github.com/google/uuid v1.3.0 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.24.1 + github.com/practo/k8s-worker-pod-autoscaler v1.6.0 + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.62.0 + github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/common v0.39.0 + github.com/prometheus/prometheus v0.41.0 + github.com/slok/sloth v0.11.0 + github.com/stretchr/testify v1.8.1 go.medium.engineering/kubernetes v0.1.6 - go.uber.org/zap v1.19.1 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - gomodules.xyz/jsonpatch/v2 v2.2.0 - istio.io/api v0.0.0-20200617184712-fb83ff2d8228 - istio.io/client-go v0.0.0-20200615164228-d77b0b53b6a0 - k8s.io/api v0.23.0 - k8s.io/apimachinery v0.23.0 - k8s.io/client-go v12.0.0+incompatible - k8s.io/code-generator v0.20.1 - k8s.io/kube-openapi v0.0.0-20220413171646-5e7f5fdc6da6 - k8s.io/utils v0.0.0-20211116205334-6203023598ed - sigs.k8s.io/controller-runtime v0.11.0 + go.uber.org/zap v1.24.0 + golang.org/x/sync v0.1.0 + istio.io/api v0.0.0-20220322234440-289bfe748e00 + istio.io/client-go v1.13.2 + k8s.io/api v0.26.0 + k8s.io/apimachinery v0.26.0 + k8s.io/client-go v0.26.0 + k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 + sigs.k8s.io/controller-runtime v0.14.1 ) require ( - cloud.google.com/go v0.81.0 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful v2.11.1+incompatible // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/go-kit/kit v0.9.0 // indirect - github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/dennwc/varint v1.0.0 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.5 // indirect - github.com/google/gofuzz v1.1.0 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect - github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/google/gnostic v0.6.9 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.6 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nxadm/tail v1.4.8 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect - github.com/prometheus/tsdb v0.7.1 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect - golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect - golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect - golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/tools v0.1.5 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/goleak v1.2.0 // indirect + go.uber.org/multierr v1.7.0 // indirect + golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 // indirect + golang.org/x/net v0.4.0 // indirect + golang.org/x/oauth2 v0.3.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.6.0 // indirect + golang.org/x/time v0.3.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect - k8s.io/apiextensions-apiserver v0.23.0 // indirect - k8s.io/component-base v0.23.0 // indirect - k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect - k8s.io/klog v1.0.0 // indirect - k8s.io/klog/v2 v2.30.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e // indirect + k8s.io/apiextensions-apiserver v0.26.0 // indirect + k8s.io/component-base v0.26.0 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) -replace ( - github.com/coreos/prometheus-operator => github.com/coreos/prometheus-operator v0.39.0 - github.com/prometheus/common => github.com/prometheus/common v0.26.0 - //github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2-0.20191111142012-edeb7a44cbf7 - github.com/prometheus/prometheus => github.com/prometheus/prometheus v2.7.0+incompatible - k8s.io/api => k8s.io/api v0.20.1 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.20.1 - k8s.io/apimachinery => k8s.io/apimachinery v0.21.0-alpha.0 - k8s.io/apiserver => k8s.io/apiserver v0.20.1 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.20.1 - k8s.io/client-go => k8s.io/client-go v0.20.1 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.20.1 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.20.1 - k8s.io/code-generator => k8s.io/code-generator v0.20.5-rc.0 - k8s.io/component-base => k8s.io/component-base v0.20.1 - k8s.io/cri-api => k8s.io/cri-api v0.20.5-rc.0 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.20.1 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.20.1 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.20.1 - k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.20.1 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.20.1 - k8s.io/kubectl => k8s.io/kubectl v0.20.1 - k8s.io/kubelet => k8s.io/kubelet v0.20.1 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.20.1 - k8s.io/metrics => k8s.io/metrics v0.20.1 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.20.1 - sigs.k8s.io/controller-runtime => github.com/Medium/controller-runtime v0.11.1-update -) - -replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm - -// Override dependancy from k8s-worker-pod-autoscaler -//replace github.com/go-logr/logr => github.com/go-logr/logr v0.1.0 - -//replace github.com/go-logr/zapr => github.com/go-logr/zapr v0.1.0 - -replace k8s.io/component-helpers => k8s.io/component-helpers v0.20.1 - -replace k8s.io/controller-manager => k8s.io/controller-manager v0.20.1 - -replace k8s.io/mount-utils => k8s.io/mount-utils v0.20.5-rc.0 - -replace k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.20.1 - -replace k8s.io/sample-controller => k8s.io/sample-controller v0.20.1 +replace github.com/prometheus/common => github.com/prometheus/common v0.26.0 -replace github.com/operator-framework/operator-sdk => github.com/Medium/operator-sdk v0.13.0-update +replace github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.11.0 diff --git a/go.sum b/go.sum index d8a6930d..fe3146fd 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,11 @@ -bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.49.0/go.mod h1:hGvAdzcWNbyuxS3nWhD7H2cIJxjRRTRLQVB0bdputVY= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -22,7 +17,6 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -32,385 +26,127 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go v0.0.0-20161028183111-bd73d950fa44/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= -github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= -github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= -github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ= -github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Medium/controller-runtime v0.11.1-update h1:UBR3IAjr9jVVDxPgh+8rlx/IV5JQFmPNyy61MNf2UkM= -github.com/Medium/controller-runtime v0.11.1-update/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= -github.com/Medium/kooper v0.9.1/go.mod h1:TuWHk0jr2S7BjaydAQTLzLslp6dcVQDPqpcvcyt96aU= -github.com/Medium/operator-sdk v0.13.0-update h1:/u5TykHKXqs+q7D9BeuMWz6h+DgXMTkgVV87+iUE51A= -github.com/Medium/operator-sdk v0.13.0-update/go.mod h1:XRnicDD4uZCNbJbMXc0B7eyw7hjO4Xzol7FAkWHa1Nc= -github.com/Medium/service-level-operator v0.4.0 h1:HMyj/eXbM5EmyFy2iRVtTmXOAq97iVwyzE2wQjUBd5w= -github.com/Medium/service-level-operator v0.4.0/go.mod h1:21e494YZLGpUo91gsDpOQnIQXGfwD01HvPYVBs6Xaio= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= -github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Pallinder/go-randomdata v0.0.0-20180329154440-dab270d296c6/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM= -github.com/aws/aws-sdk-go v0.0.0-20180507225419-00862f899353/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= -github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.29.15/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= -github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= -github.com/bazelbuild/bazel-gazelle v0.0.0-20181012220611-c728ce9f663e/go.mod h1:uHBSeeATKpVazAACZBDPL/Nk/UhQDDsJWDlqYJo8/Us= -github.com/bazelbuild/buildtools v0.0.0-20180226164855-80c7f0d45d7e/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= -github.com/beanstalkd/go-beanstalk v0.0.0-20200526060843-1cc502ecaf3c/go.mod h1:Q3f6RCbUHp8RHSfBiPUZBojK76rir8Rl+KINuz2/sYs= +github.com/aws/aws-sdk-go v1.44.159 h1:9odtuHAYQE9tQKyuX6ny1U1MHeH5/yzeCJi96g9H4DU= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= -github.com/biogo/store v0.0.0-20160505134755-913427a1d5e8/go.mod h1:Iev9Q3MErcn+w3UOJD/DkEzllvugfdx7bGcMOFhvr/4= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/brancz/gojsontoyaml v0.0.0-20191212081931-bf2969bbd742/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= -github.com/brancz/kube-rbac-proxy v0.5.0/go.mod h1:cL2VjiIFGS90Cjh5ZZ8+It6tMcBt8rwvuw2J6Mamnl0= -github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= -github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= -github.com/cenk/backoff v2.0.0+incompatible/go.mod h1:7FtoeaSnHoZnmZzz47cM35Y9nSW7tNyaidugnHTaFDE= -github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= -github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho= -github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cfssl v0.0.0-20180726162950-56268a613adf/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4= -github.com/cockroachdb/cockroach v0.0.0-20170608034007-84bc9597164f/go.mod h1:xeT/CQ0qZHangbYbWShlCGAx31aV4AjGswDUjhKS6HQ= -github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= -github.com/container-storage-interface/spec v1.1.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= -github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.0.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/prometheus-operator v0.39.0 h1:sXbjqxHhTdfhdbG/Fpls3nArXZZaC66JTpzebZK2ZOc= -github.com/coreos/prometheus-operator v0.39.0/go.mod h1:erio69w1R/aC14D5nfvAXSlE8FT8jt2Hnavc50Dp33A= -github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= -github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= -github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= -github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= -github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= -github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= -github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= -github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= -github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/dgrijalva/jwt-go v0.0.0-20161101193935-9ed569b5d1ac/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libnetwork v0.0.0-20180830151422-a9cd636e3789/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= +github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyzzjiW90t8cY= -github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= -github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= -github.com/elastic/gosigar v0.9.0/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.11.1+incompatible h1:CjKsv3uWcCMvySPQYKxO8XX3f9zD4FeZRsW4G0B4ffE= -github.com/emicklei/go-restful v2.11.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= -github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= -github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.1.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M= -github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ini/ini v1.21.1/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= -github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20180924190550-6f2cf27854a4/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -443,19 +179,12 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20160529050041-d9eb7a3d35ec/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= -github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= -github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cadvisor v0.34.0/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -466,18 +195,16 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20150304233714-bbcb9da2d746/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20180605153948-8b03ce837f34/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -490,239 +217,59 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.0.0-20180520015035-48a0ecefe2e4/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/gophercloud/gophercloud v0.0.0-20181206160319-9d88c34913a9/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.4.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= +github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.6.3/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.4/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= -github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul v0.0.0-20180615161029-bed22a81e9fd/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.0.0-20161007004122-1d4fa605f6ff/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/heketi/heketi v9.0.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= -github.com/heketi/rest v0.0.0-20180404230133-aa6a65207413/go.mod h1:BeS3M108VzVlmAue3lv2WcGuPAX94/KN63MUURzbYSI= -github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= -github.com/heketi/utils v0.0.0-20170317161834-435bc5bdfa64/go.mod h1:RYlF4ghFZPPmk2TC5REt5OFwvfb6lzxFWrTWB+qs28s= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v0.0.0-20170331210902-15e594fc09f1/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jsonnet-bundler/jsonnet-bundler v0.3.1/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v0.0.0-20150905172533-109e267447e9/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/knz/strtime v0.0.0-20181018220328-af2256ee352c/go.mod h1:4ZxfWkxwtc7dBeifERVVWRy9F9rTU9p0yCDgeCtlius= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= -github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.15.6/go.mod h1:6AMpwZpsyCFwSovxzM78e+AsYxE8sGwiM6C3TytaWeI= -github.com/lightstep/lightstep-tracer-go v0.18.0/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= -github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= -github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04= -github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk= -github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao= -github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= -github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= -github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= -github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.1/go.mod h1:F9YacGpnZbLQMzuPI0rR6op21YvNu/RjL705LJJpM3k= -github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= -github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= -github.com/miekg/dns v1.0.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= -github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v0.0.0-20180523094522-3864e76763d9/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -730,270 +277,91 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3DnAZsJsoaE= -github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= -github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20190414153302-2ae31c8b6b30/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.0.0-20170918173356-f857583a70c3/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.0-20180912035003-be2c049b30cc/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= -github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= -github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= -github.com/opentracing-contrib/go-stdlib v0.0.0-20170113013457-1de4cc2120e7/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.1/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5/go.mod h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4= -github.com/operator-framework/operator-registry v1.5.1/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= -github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v0.0.0-20180312054125-0646ccaebea1/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg= -github.com/petermattis/goid v0.0.0-20170504144140-0ded85884ba5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= -github.com/practo/k8s-worker-pod-autoscaler v1.1.1-0.20200722110630-c31dc858b6f9 h1:FZfqpzIdRRMjdodpMB8nXH15sTT9BBgUwHkAhjDtdyY= -github.com/practo/k8s-worker-pod-autoscaler v1.1.1-0.20200722110630-c31dc858b6f9/go.mod h1:jh1Tx7J3/BZwfbR1gv3G5dRRYfognxOyUnFN264eGqs= -github.com/practo/klog/v2 v2.2.1/go.mod h1:WMkpfPwTxLgSLookpI4UUv2zL7tMltKACK/FHB1zLV0= -github.com/practo/promlog v1.0.0/go.mod h1:gNtTwdRfC4UHAqBDWZ8xrSSFtACV689gWvpgGobYHXM= -github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/practo/k8s-worker-pod-autoscaler v1.6.0 h1:Q2uUCA0vsjwuuq5X04MagkYddhfAh7Q91pmPyzPq86w= +github.com/practo/k8s-worker-pod-autoscaler v1.6.0/go.mod h1:NcqBHmBm9Bp16KjEb9j56PRZC9b24mKqjIoxs22Q7mk= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.62.0 h1:55138zTXw/yRYizPxZ672I/aDD7Yte3uYRAfUjWUu2M= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.62.0/go.mod h1:j51242bf6LQwvJ1JPKWApzTnifmCwcQq0i1p29ylWiM= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/prometheus v2.7.0+incompatible h1:wlrnDXZ/FXr5MTRP+2LyBED+Kcgd7r6ujF6Uv31UDtw= -github.com/prometheus/prometheus v2.7.0+incompatible/go.mod h1:aNuqjQW47j/yc/kN0cNZ8cOTBlBU8VbspEvNDfxe1To= -github.com/prometheus/tsdb v0.4.0/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rlmcpherson/s3gof3r v0.5.0/go.mod h1:s7vv7SMDPInkitQMuZzH615G7yWHdrU2r/Go7Bo71Rs= -github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/prometheus v0.41.0 h1:+QR4QpzwE54zsKk2K7EUkof3tHxa3b/fyw7xJ4jR1Ns= +github.com/prometheus/prometheus v0.41.0/go.mod h1:Uu5817xm7ibU/VaDZ9pu1ssGzcpO9Bd+LyoZ76RpHyo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rubenv/sql-migrate v0.0.0-20191025130928-9355dd04f4b3/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= -github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= -github.com/rubyist/circuitbreaker v2.2.1+incompatible/go.mod h1:Ycs3JgJADPuzJDwffe12k6BZT8hxVi6lFK+gWYJLN4A= -github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/sasha-s/go-deadlock v0.0.0-20161201235124-341000892f3d/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= -github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180711163814-62bca832be04/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slok/sloth v0.11.0 h1:0N3975hhO8izJoHIiPMBKZWxk6lxamuTd45MxYsOk04= +github.com/slok/sloth v0.11.0/go.mod h1:xE9zMDVvMb5ylMhkacDtC02vmRhZHNuqe5ez93OiDms= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spotahome/kooper v0.8.0/go.mod h1:pFO0M0QiYvN6RwGTFAtPONFUfiH6NjDCD9tHvdl0LtY= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= -github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc= -github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM= -github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/uber/jaeger-client-go v2.19.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vmware/govmomi v0.20.1/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= -go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk= -go.elastic.co/apm/module/apmhttp v1.5.0/go.mod h1:1FbmNuyD3ddauwzgVwFB0fqY6KbZt3JkV187tGCYYhY= -go.elastic.co/apm/module/apmot v1.5.0/go.mod h1:d2KYwhJParTpyw2WnTNy8geNlHKKFX+4oK3YLlsesWE= -go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.medium.engineering/kubernetes v0.1.6 h1:VZ8ZYlIyfgro5uztSxbVENWtUtjNTnNqER2qofgt3jU= go.medium.engineering/kubernetes v0.1.6/go.mod h1:4Wo1SOrWAc6YOhpx0w66j+RAMSI/Vam7QVdkVg8iIs0= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1001,50 +369,27 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -1054,6 +399,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 h1:OvjRkcNHnf6/W5FZXSxODbxwD+X7fspczG7Jn/xQVD4= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1066,6 +413,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -1077,41 +425,21 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1135,15 +463,13 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1153,8 +479,9 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1165,58 +492,27 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181004145325-8469e314837c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1227,13 +523,12 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1245,18 +540,19 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 h1:M69LAlWZCshgp0QSzyDcSsSIejIEeuaCVpmwcKwyLMk= -golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1265,52 +561,31 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20170824195420-5d2fd3ccab98/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181023010539-40a48ad93fbe/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190813034749-528a2984e271/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1333,7 +608,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1348,30 +622,21 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/gonum v0.0.0-20190710053202-4340aa3071a0/go.mod h1:03dgh78c4UvU1WksguQ/lvJQXbezKQGJSrwwRq5MraQ= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -google.golang.org/api v0.0.0-20180506000402-20530fd5d65a/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= @@ -1387,7 +652,6 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1397,15 +661,12 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -1421,6 +682,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1430,7 +692,6 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1439,28 +700,28 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1473,154 +734,89 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/fsnotify/fsnotify.v1 v1.3.0/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= -gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/vmihailenco/msgpack.v2 v2.9.1/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8= -gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.1.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -istio.io/api v0.0.0-20200615162408-9b5293c30ef5/go.mod h1:uXD10AwGZkxIrVKTntYm2uyFWQQfNzhAGkIxLfRNocs= -istio.io/api v0.0.0-20200617184712-fb83ff2d8228 h1:I+PS2abFypPWmHF/JujPjyq7raPxgAhbfP5Ousp1pqQ= -istio.io/api v0.0.0-20200617184712-fb83ff2d8228/go.mod h1:uXD10AwGZkxIrVKTntYm2uyFWQQfNzhAGkIxLfRNocs= -istio.io/client-go v0.0.0-20200615164228-d77b0b53b6a0 h1:xeY9LpoaZ14+XMorriB/Uox6vQMfAj6hHyCc74WpdaY= -istio.io/client-go v0.0.0-20200615164228-d77b0b53b6a0/go.mod h1:W+REwu9Vz96+hFyDL05C9QVHkYjROjeeup0nznYE/sc= -istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE= -istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs= -k8s.io/api v0.20.1 h1:ud1c3W3YNzGd6ABJlbFfKXBKXO+1KdGfcgGGNgFR03E= -k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/apiextensions-apiserver v0.20.1 h1:ZrXQeslal+6zKM/HjDXLzThlz/vPSxrfK3OqL8txgVQ= -k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= -k8s.io/apimachinery v0.21.0-alpha.0 h1:iT01Vd/9MmJLSZRGe1zY8SMl6QmvJ52l4a6oKIJPClU= -k8s.io/apimachinery v0.21.0-alpha.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA= -k8s.io/cli-runtime v0.20.1/go.mod h1:6wkMM16ZXTi7Ow3JLYPe10bS+XBnIkL6V9dmEz0mbuY= -k8s.io/client-go v0.20.1 h1:Qquik0xNFbK9aUG92pxHYsyfea5/RPO9o9bSywNor+M= -k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/cloud-provider v0.20.1/go.mod h1:x2E8iyhfwoxQbk361wNBdTCFTQNKx8m/ZcxQPxpmFfE= -k8s.io/cluster-bootstrap v0.20.1/go.mod h1:Xnom8jy4bkF9pz1w7XQAZYQWMYF4m3CSCTqYiehDdXI= -k8s.io/code-generator v0.20.5-rc.0 h1:t1T/nu5/kZtZp61BSgj+TucDp5hBg0/JcbaIZufxRMg= -k8s.io/code-generator v0.20.5-rc.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/component-base v0.20.1 h1:6OQaHr205NSl24t5wOF2IhdrlxZTWEZwuGlLvBgaeIg= -k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-helpers v0.20.1/go.mod h1:Q8trCj1zyLNdeur6pD2QvsF8d/nWVfK71YjN5+qVXy4= -k8s.io/controller-manager v0.20.1/go.mod h1:Wfwz1Sn3ITXiMKO+Z2qhc9b34YgzOL7puRi9jb4wIUo= -k8s.io/cri-api v0.20.5-rc.0/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/csi-translation-lib v0.20.1/go.mod h1:Jk3Ta91UveSd54W44P8qCXB57BQy7uqUrLaBqhT/4z4= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA= +istio.io/api v0.0.0-20220304033655-c6e3d0f0d646/go.mod h1:8ZZgyVgYrHhsFQarEgTfPnMGpdgTDZbxSjYhdwTUuAQ= +istio.io/api v0.0.0-20220322234440-289bfe748e00 h1:dx26IwPATzdB3j3Zo9b+GsFfMJyEUTLl+pAEsq1Ivpc= +istio.io/api v0.0.0-20220322234440-289bfe748e00/go.mod h1:8ZZgyVgYrHhsFQarEgTfPnMGpdgTDZbxSjYhdwTUuAQ= +istio.io/client-go v1.13.2 h1:r5tn7+aqwajZpYUnWFivYIsVtMDExZBydDayO2P0Nfw= +istio.io/client-go v1.13.2/go.mod h1:p7OSh0RKD0tGwz+f9j0yVhrAv7AyMpVZHRHn7cGMOFA= +istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e h1:z2WI3y55w0K3c6hmarcp5EcOiP4vVpTBXA8nYstP+cE= +istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e/go.mod h1:vJDAniIqryf/z///fgZqVPKJ7N2lBk7Gg8DCTB7oCfU= +k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg= +k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo= +k8s.io/api v0.26.0 h1:IpPlZnxBpV1xl7TGk/X6lFtpgjgntCg8PJ+qrPHAC7I= +k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= +k8s.io/apiextensions-apiserver v0.26.0 h1:Gy93Xo1eg2ZIkNX/8vy5xviVSxwQulsnUdQ00nEdpDo= +k8s.io/apiextensions-apiserver v0.26.0/go.mod h1:7ez0LTiyW5nq3vADtK6C3kMESxadD51Bh6uz3JOlqWQ= +k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc= +k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno= +k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= +k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0= +k8s.io/client-go v0.26.0 h1:lT1D3OfO+wIi9UFolCrifbjUUgu7CpLca0AD8ghRLI8= +k8s.io/client-go v0.26.0/go.mod h1:I2Sh57A79EQsDmn7F7ASpmru1cceh3ocVT9KlX2jEZg= +k8s.io/component-base v0.26.0 h1:0IkChOCohtDHttmKuz+EP3j3+qKmV55rM9gIFTXA7Vs= +k8s.io/component-base v0.26.0/go.mod h1:lqHwlfV1/haa14F/Z5Zizk5QmzaVf23nQzCwVOQpfC8= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= -k8s.io/helm v2.16.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.1.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.20.1/go.mod h1:1ZeyRfSg5HcRI8dihvWAc7VpXSMAw9UmZoWXBUOPyew= -k8s.io/kube-controller-manager v0.20.1/go.mod h1:9iwMjyiO1pzgO9b2WvWmGoTilkal4ke7ceCcNWW6NAI= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-proxy v0.20.1/go.mod h1:/PlQONAFpILYSKgmAg4sNsmlrXqPgwMSce/pWBtbbzk= -k8s.io/kube-scheduler v0.20.1/go.mod h1:3LrKGlT1iM1rsc4S8wSkTUaVrFsptQixESqBrtM0e6o= -k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= -k8s.io/kubectl v0.20.1/go.mod h1:2bE0JLYTRDVKDiTREFsjLAx4R2GvUtL/mGYFXfFFMzY= -k8s.io/kubelet v0.20.1/go.mod h1:5zyqbuxkRJYcxNrh33VwHxd6T7HdqpuzpFldjgX8JMg= -k8s.io/kubernetes v1.16.0/go.mod h1:nlP2zevWKRGKuaaVbKIwozU0Rjg9leVDXkL4YTtjmVs= -k8s.io/kubernetes v1.16.2/go.mod h1:SmhGgKfQ30imqjFVj8AI+iW+zSyFsswNErKYeTfgoH0= -k8s.io/legacy-cloud-providers v0.20.1/go.mod h1:r2Qf8WVnfQndTp6dSPPfGRtjO1CoWVbW098M4SI7njY= -k8s.io/metrics v0.20.1/go.mod h1:JhpBE/fad3yRGsgEpiZz5FQQM5wJ18OTLkD7Tv40c0s= -k8s.io/repo-infra v0.0.0-20181204233714-00fe14e3d1a3/go.mod h1:+G1xBfZDfVFsm1Tj/HNCvg4QqWx8rJ2Fxpqr1rqp/gQ= -k8s.io/sample-apiserver v0.20.1/go.mod h1:Ti0ug/r3ascaPpc7z22LC3jg3+wv7oCpcNPs0YdREes= -k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715 h1:tBEbstoM+K0FiBV5KGAKQ0kuvf54v/hwpldiJt69w1s= +k8s.io/kube-openapi v0.0.0-20221207184640-f3cff1453715/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -labix.org/v2/mgo v0.0.0-20140701140051-000000000287/go.mod h1:Lg7AYkt1uXJoR9oeSZ3W/8IXLdvOfIITgZnommstyz4= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70= -sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= +sigs.k8s.io/controller-runtime v0.14.1 h1:vThDes9pzg0Y+UbCPY3Wj34CGIYPgdmspPm2GIpxpzM= +sigs.k8s.io/controller-runtime v0.14.1/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= -sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 00000000..767efde9 --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/hack/crd.patch b/hack/crd.patch deleted file mode 100644 index 0ebd39a6..00000000 --- a/hack/crd.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/deploy/crds/picchu_v1alpha1_incarnation.yaml b/deploy/crds/picchu_v1alpha1_incarnation.yaml -index c4e4551..866c0b2 100644 ---- a/deploy/crds/picchu_v1alpha1_incarnation.yaml -+++ b/deploy/crds/picchu_v1alpha1_incarnation.yaml -@@ -115,7 +115,7 @@ spec: - resources: - properties: - cpu: -- type: object -+ type: string - type: object - type: object - required: -diff --git a/deploy/crds/picchu_v1alpha1_revision.yaml b/deploy/crds/picchu_v1alpha1_revision.yaml -index 153404f..492d830 100644 ---- a/deploy/crds/picchu_v1alpha1_revision.yaml -+++ b/deploy/crds/picchu_v1alpha1_revision.yaml -@@ -143,7 +143,7 @@ spec: - resources: - properties: - cpu: -- type: object -+ type: string - type: object - type: object - required: diff --git a/hack/fix-all.sh b/hack/fix-all.sh deleted file mode 100755 index 11af9b58..00000000 --- a/hack/fix-all.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -find ./{pkg,cmd} -name '*.go' -not -path './go/vendor/*' -exec gofmt -l -w {} \; diff --git a/hack/fix.sh b/hack/fix.sh new file mode 100755 index 00000000..614b7b1c --- /dev/null +++ b/hack/fix.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +find ./vendor/istio.io -type f -exec grep 'protobuf_oneof' -l {} \; -exec perl -i -pe's/(protobuf_oneof.*)`$/$1 json:\"-\"`/g' {} \; \ No newline at end of file diff --git a/hack/kustom-parse-all.sh b/hack/kustom-parse-all.sh new file mode 100755 index 00000000..d54a7413 --- /dev/null +++ b/hack/kustom-parse-all.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +mkdir -p deploy + +which yq || pip install yq + +pushd deploy +kustomize build ../config/default | csplit -k - '/^---$/' {30} +for files in $(ls xx*) + do + type=$(cat $files | yq -r '.kind'| awk '{print tolower($0)}'); + cat $files >> ${type}.yaml + echo "Created ${type}.yaml" +done +rm -rf xx* +popd diff --git a/hack/kustom-parse.sh b/hack/kustom-parse.sh new file mode 100755 index 00000000..69bd4c23 --- /dev/null +++ b/hack/kustom-parse.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +mkdir -p resources + +which yq || pip install yq + +pushd resources +kustomize build ../config/crd | csplit - '/^---$/' {4} +for files in $(ls xx*) + do new_path=$(cat $files | yq '.metadata.annotations."config.kubernetes.io/origin"'|cut -d: -f2|cut -d \\ -f1|xargs) + echo "Copying $files --> $new_path" + mv $files ../config/crd/${new_path} + +done +popd +rm -rf resources \ No newline at end of file diff --git a/hack/test.sh b/hack/test.sh deleted file mode 100755 index 3d18dfad..00000000 --- a/hack/test.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -export CGO_ENABLED=0 - -TARGETS=( - ./cmd/... - ./pkg/... -) - -if [[ ${#@} -ne 0 ]]; then - TARGETS=("$@") -fi - -echo "Running tests:" "${TARGETS[@]}" - -if [[ -n "${GOFLAGS:-}" ]]; then - echo "GOFLAGS: ${GOFLAGS}" -fi - -go test -installsuffix "static" -timeout 60s "${TARGETS[@]}" -echo "Success!" diff --git a/hack/verify-all.sh b/hack/verify-all.sh deleted file mode 100755 index 795491dd..00000000 --- a/hack/verify-all.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -GIT_STATUS="$(git status --porcelain)" -GOFMT_OUT="$(find ./{pkg,cmd}/ -name '*.go' -not -path './go/vendor/*' -not -path './pkg/apis/picchu/v1alpha1/zz_*.go' -exec gofmt -l -s {} \;)" - -if [[ -n "${GOFMT_OUT}" || -n "${GIT_STATUS}" ]]; then - if [[ -n "${GOFMT_OUT}" ]]; then - echo "${GOFMT_OUT}" - echo "** gofmt FAILED" - fi - if [[ -n "${GIT_STATUS}" ]]; then - echo "${GIT_STATUS}" - echo "** git status shows changes" - fi - exit 1 -fi diff --git a/incarnation.dot b/incarnation.dot deleted file mode 100644 index 3645ac50..00000000 --- a/incarnation.dot +++ /dev/null @@ -1,23 +0,0 @@ -digraph G { - label="Incarnation State" - bgcolor="#666666" - fontsize="32" - - created -> deployed [ label="availableReplicas >= 1",fontcolor="green",color="green"] - deployed -> deleted [ label="revision\ndeleted",fontcolor="yellow",color="yellow"] - deployed -> failed [ label="alarm\ntriggered",fontcolor="red",color="red"] - released -> failed [ label="alarm\ntriggered",fontcolor="red",color="red"] - released -> retired [ label="removed\nfrom\nreleasepool",fontcolor="yellow",color="yellow"] - failed -> deleted [ label="revision\ndeleted",fontcolor="red",color="red"] - failed -> deployed [ label="alarm\ncleared",fontcolor="green",color="green"] - deployed -> released [ label="in releasepool",fontcolor="green",color="green"] - retired -> deleted [ label="revision deleted",fontcolor="yellow",color="yellow"] - retired -> deployed [ label="priority\nincreased",fontcolor="green",color="green"] - - created [shape=Mdiamond,style="filled",fillcolor="yellow",center=1]; - deleted [shape=Msquare,style="filled",fillcolor="grey"]; - failed [fillcolor="pink",style="filled"]; - deployed [fillcolor="green",style="filled"]; - released [fillcolor="green",style="filled"]; - retired [fillcolor="yellow",style="filled"]; -} diff --git a/main.go b/main.go new file mode 100644 index 00000000..08b8451e --- /dev/null +++ b/main.go @@ -0,0 +1,203 @@ +/* + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "flag" + "os" + "time" + + monitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + + wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + slo "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" + picchu "go.medium.engineering/picchu/api/v1alpha1" + picchumediumengineeringv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + apis "go.medium.engineering/picchu/api/v1alpha1/apis" + clientgoscheme "go.medium.engineering/picchu/client/scheme" + "go.medium.engineering/picchu/controllers" + "go.medium.engineering/picchu/controllers/utils" + promapi "go.medium.engineering/picchu/prometheus" + istio "istio.io/client-go/pkg/apis/networking/v1alpha3" + apps "k8s.io/api/apps/v1" + autoscaling "k8s.io/api/autoscaling/v2beta2" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + // +kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(picchumediumengineeringv1alpha1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + flag.StringVar(&metricsAddr, "metrics-addr", ":8383", "The address the metric endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + + manageRoute53 := flag.Bool("manage-route53", false, "Should picchu manage route53?") + requeuePeriodSeconds := flag.Int("sync-period-seconds", 15, "Delay between requeues") + prometheusQueryAddress := flag.String("prometheus-query-address", "", "The (usually thanos) address that picchu should query to SLO alerts") + prometheusQueryTTL := flag.Duration("prometheus-query-ttl", time.Duration(10)*time.Second, "How long to cache SLO alerts") + humaneReleasesEnabled := flag.Bool("humane-releases-enabled", true, "Release apps on the humane schedule") + prometheusEnabled := flag.Bool("prometheus-enabled", true, "Prometheus integration for SLO alerts is enabled") + serviceLevelsNamespace := flag.String("service-levels-namespace", "service-level-objectives", "The namespace to use when creating ServiceLevel resources in the delivery cluster") + serviceLevelsFleet := flag.String("service-levels-fleet", "delivery", "The fleet to use when creating ServiceLevel resources") + concurrentRevisions := flag.Int("concurrent-revisions", 20, "How many concurrent revisions to reconcile") + concurrentReleaseManagers := flag.Int("concurrent-release-managers", 50, "How many concurrent release managers to reconcile") + devRoutesServiceHost := flag.String("dev-routes-service-host", "", "Configures the dev routes service host, if cluster dev routes are enabled") + devRoutesServicePort := flag.Int("dev-routes-service-port", 80, "Configures the dev routes service port, if cluster dev routes are enabled") + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + + requeuePeriod := time.Duration(*requeuePeriodSeconds) * time.Second + if !*prometheusEnabled { + setupLog.Info("SLO alerts will not be respected (--prometheus-enabled=false)") + *prometheusQueryAddress = "" + } + + cconfig := utils.Config{ + ManageRoute53: *manageRoute53, + HumaneReleasesEnabled: *humaneReleasesEnabled, + RequeueAfter: requeuePeriod, + PrometheusQueryAddress: *prometheusQueryAddress, + PrometheusQueryTTL: *prometheusQueryTTL, + ServiceLevelsNamespace: *serviceLevelsNamespace, + ServiceLevelsFleet: *serviceLevelsFleet, + ConcurrentRevisions: *concurrentRevisions, + ConcurrentReleaseManagers: *concurrentReleaseManagers, + DevRoutesServiceHost: *devRoutesServiceHost, + DevRoutesServicePort: *devRoutesServicePort, + } + + var api controllers.PromAPI + var errPromAPI error + + if cconfig.PrometheusQueryAddress != "" { + api, errPromAPI = promapi.NewAPI(cconfig.PrometheusQueryAddress, cconfig.PrometheusQueryTTL) + } else { + api = &controllers.NoopPromAPI{} + } + if errPromAPI != nil { + panic(errPromAPI) + } + + schemeBuilders := k8sruntime.SchemeBuilder{ + apps.AddToScheme, + core.AddToScheme, + autoscaling.AddToScheme, + picchu.AddToScheme, + istio.AddToScheme, + monitoring.AddToScheme, + slo.AddToScheme, + wpav1.AddToScheme, + apis.AddToScheme, + } + + for _, sch := range []*k8sruntime.Scheme{clientgoscheme.Scheme} { + if err := picchu.RegisterDefaults(sch); err != nil { + setupLog.Error(err, "") + os.Exit(1) + } + + for _, addToScheme := range schemeBuilders { + if err := addToScheme(sch); err != nil { + setupLog.Error(err, "") + os.Exit(1) + } + } + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: clientgoscheme.Scheme, + MetricsBindAddress: metricsAddr, + Port: 9443, + LeaderElection: enableLeaderElection, + LeaderElectionID: "de705aec.picchu.medium.engineering", + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&controllers.ClusterReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Cluster"), + Scheme: mgr.GetScheme(), + Config: cconfig, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Cluster") + os.Exit(1) + } + if err = (&controllers.ReleaseManagerReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("ReleaseManager"), + Scheme: mgr.GetScheme(), + Config: cconfig, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "ReleaseManager") + os.Exit(1) + } + if err = (&controllers.ClusterSecretsReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("ClusterSecrets"), + Scheme: mgr.GetScheme(), + Config: cconfig, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "ClusterSecrets") + os.Exit(1) + } + if err = (&controllers.RevisionReconciler{ + Client: mgr.GetClient(), + CustomLogger: ctrl.Log.WithName("controllers").WithName("Revision"), + Scheme: mgr.GetScheme(), + Config: cconfig, + PromAPI: api, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Revision") + os.Exit(1) + } + if err = (&picchumediumengineeringv1alpha1.Revision{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Revision") + os.Exit(1) + } + + // +kubebuilder:scaffold:builder + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/pkg/mocks/client.go b/mocks/client.go similarity index 87% rename from pkg/mocks/client.go rename to mocks/client.go index 2e692032..41ba07a6 100644 --- a/pkg/mocks/client.go +++ b/mocks/client.go @@ -95,17 +95,22 @@ func (mr *MockClientMockRecorder) DeleteAllOf(arg0, arg1 interface{}, arg2 ...in } // Get mocks base method -func (m *MockClient) Get(arg0 context.Context, arg1 types.NamespacedName, arg2 client.Object) error { +func (m *MockClient) Get(arg0 context.Context, arg1 types.NamespacedName, arg2 client.Object, arg3 ...client.GetOption) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2) + varargs := []interface{}{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Get", varargs...) ret0, _ := ret[0].(error) return ret0 } // Get indicates an expected call of Get -func (mr *MockClientMockRecorder) Get(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockClientMockRecorder) Get(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), arg0, arg1, arg2) + varargs := append([]interface{}{arg0, arg1, arg2}, arg3...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), varargs...) } // List mocks base method @@ -160,14 +165,6 @@ func (mr *MockClientMockRecorder) RESTMapper() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RESTMapper", reflect.TypeOf((*MockClient)(nil).RESTMapper)) } -// Status mocks base method -func (m *MockClient) Status() client.StatusWriter { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Status") - ret0, _ := ret[0].(client.StatusWriter) - return ret0 -} - // Scheme mocks base method func (m *MockClient) Scheme() *runtime.Scheme { m.ctrl.T.Helper() @@ -182,12 +179,34 @@ func (mr *MockClientMockRecorder) Scheme() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scheme", reflect.TypeOf((*MockClient)(nil).Scheme)) } +// Status mocks base method +func (m *MockClient) Status() client.SubResourceWriter { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Status") + ret0, _ := ret[0].(client.SubResourceWriter) + return ret0 +} + // Status indicates an expected call of Status func (mr *MockClientMockRecorder) Status() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockClient)(nil).Status)) } +// SubResource mocks base method +func (m *MockClient) SubResource(arg0 string) client.SubResourceClient { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubResource", arg0) + ret0, _ := ret[0].(client.SubResourceClient) + return ret0 +} + +// SubResource indicates an expected call of SubResource +func (mr *MockClientMockRecorder) SubResource(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubResource", reflect.TypeOf((*MockClient)(nil).SubResource), arg0) +} + // Update mocks base method func (m *MockClient) Update(arg0 context.Context, arg1 client.Object, arg2 ...client.UpdateOption) error { m.ctrl.T.Helper() diff --git a/pkg/mocks/matchers.go b/mocks/matchers.go similarity index 100% rename from pkg/mocks/matchers.go rename to mocks/matchers.go diff --git a/pkg/mocks/mutateMatchers.go b/mocks/mutateMatchers.go similarity index 94% rename from pkg/mocks/mutateMatchers.go rename to mocks/mutateMatchers.go index b3c53d2f..77c6979f 100644 --- a/pkg/mocks/mutateMatchers.go +++ b/mocks/mutateMatchers.go @@ -1,10 +1,10 @@ package mocks import ( - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/golang/mock/gomock" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" appsv1 "k8s.io/api/apps/v1" autoscaling "k8s.io/api/autoscaling/v2beta2" corev1 "k8s.io/api/core/v1" @@ -97,10 +97,10 @@ func InjectPrometheusRules(rules []monitoringv1.PrometheusRule) gomock.Matcher { } // InjectServiceLevels puts ServiceLevel into a *ServiceLevelList -func InjectServiceLevels(sls []slov1alpha1.ServiceLevel) gomock.Matcher { +func InjectServiceLevels(sls []slov1alpha1.PrometheusServiceLevel) gomock.Matcher { fn := func(x interface{}) bool { switch o := x.(type) { - case *slov1alpha1.ServiceLevelList: + case *slov1alpha1.PrometheusServiceLevelList: for i := range sls { o.Items = append(o.Items, sls[i]) } diff --git a/pkg/apis/picchu/group.go b/pkg/apis/picchu/group.go deleted file mode 100644 index 4de922b8..00000000 --- a/pkg/apis/picchu/group.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package picchu contains picchu API versions. -// -// This file ensures Go source parsers acknowledge the picchu package -// and any child packages. It can be removed if any other Go source files are -// added to this package. -package picchu diff --git a/pkg/apis/picchu/v1alpha1/custom_deepcopy.go b/pkg/apis/picchu/v1alpha1/custom_deepcopy.go deleted file mode 100644 index 174f4742..00000000 --- a/pkg/apis/picchu/v1alpha1/custom_deepcopy.go +++ /dev/null @@ -1,58 +0,0 @@ -package v1alpha1 - -import ( - "fmt" - "math" - - "github.com/gogo/protobuf/proto" - _ "github.com/gogo/protobuf/types" - istio "istio.io/api/networking/v1alpha3" -) - -var ( - _ = proto.Marshal - _ = fmt.Errorf - _ = math.Inf -) - -// Istio uses proto.Clone, and therefore doesn't implement recursive deepCopy. If we want to use a subtype of istio's -// nested apis, we'll need to wrap the structs and create our own deepcopy impl. -func (in *Istio) DeepCopy() *Istio { - if in == nil { - return nil - } - out := new(Istio) - in.DeepCopyInto(out) - return out -} - -func (in *Istio) DeepCopyInto(out *Istio) { - if in.TrafficPolicy != nil { - p := proto.Clone(in.TrafficPolicy).(*istio.TrafficPolicy) - out.TrafficPolicy = p - } - if in.Sidecar != nil { - in, out := &in.Sidecar, &out.Sidecar - *out = (*in).DeepCopy() - } -} - -func (in *HTTPPortFault) DeepCopy() *HTTPPortFault { - if in == nil { - return nil - } - out := new(HTTPPortFault) - in.DeepCopyInto(out) - return out -} - -func (in *HTTPPortFault) DeepCopyInto(out *HTTPPortFault) { - if in.PortSelector != nil { - p := proto.Clone(in.PortSelector).(*istio.PortSelector) - out.PortSelector = p - } - if in.HTTPFault != nil { - p := proto.Clone(in.HTTPFault).(*istio.HTTPFaultInjection) - out.HTTPFault = p - } -} diff --git a/pkg/apis/picchu/v1alpha1/doc.go b/pkg/apis/picchu/v1alpha1/doc.go deleted file mode 100644 index 8d51604a..00000000 --- a/pkg/apis/picchu/v1alpha1/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package v1alpha1 contains API Schema definitions for the picchu v1alpha1 API group -// +k8s:deepcopy-gen=package,register -// +k8s:defaulter-gen=TypeMeta -// +groupName=picchu.medium.engineering -package v1alpha1 diff --git a/pkg/apis/picchu/v1alpha1/register.go b/pkg/apis/picchu/v1alpha1/register.go deleted file mode 100644 index 03a22234..00000000 --- a/pkg/apis/picchu/v1alpha1/register.go +++ /dev/null @@ -1,21 +0,0 @@ -// NOTE: Boilerplate only. Ignore this file. - -// Package v1alpha1 contains API Schema definitions for the picchu v1alpha1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=picchu.medium.engineering -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "picchu.medium.engineering", Version: "v1alpha1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} - - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/pkg/controller/add_cluster.go b/pkg/controller/add_cluster.go deleted file mode 100644 index bb76286a..00000000 --- a/pkg/controller/add_cluster.go +++ /dev/null @@ -1,10 +0,0 @@ -package controller - -import ( - "go.medium.engineering/picchu/pkg/controller/cluster" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, cluster.Add) -} diff --git a/pkg/controller/add_clustersecrets.go b/pkg/controller/add_clustersecrets.go deleted file mode 100644 index 915c9413..00000000 --- a/pkg/controller/add_clustersecrets.go +++ /dev/null @@ -1,10 +0,0 @@ -package controller - -import ( - "go.medium.engineering/picchu/pkg/controller/clustersecrets" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, clustersecrets.Add) -} diff --git a/pkg/controller/add_releasemanager.go b/pkg/controller/add_releasemanager.go deleted file mode 100644 index 216f497e..00000000 --- a/pkg/controller/add_releasemanager.go +++ /dev/null @@ -1,10 +0,0 @@ -package controller - -import ( - "go.medium.engineering/picchu/pkg/controller/releasemanager" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, releasemanager.Add) -} diff --git a/pkg/controller/add_revision.go b/pkg/controller/add_revision.go deleted file mode 100644 index 77ebb30d..00000000 --- a/pkg/controller/add_revision.go +++ /dev/null @@ -1,10 +0,0 @@ -package controller - -import ( - "go.medium.engineering/picchu/pkg/controller/revision" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, revision.Add) -} diff --git a/pkg/controller/cluster/cluster_controller.go b/pkg/controller/cluster/cluster_controller.go deleted file mode 100644 index f2bf82f9..00000000 --- a/pkg/controller/cluster/cluster_controller.go +++ /dev/null @@ -1,154 +0,0 @@ -package cluster - -import ( - "context" - "fmt" - "regexp" - - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/version" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "k8s.io/client-go/discovery" - "k8s.io/client-go/rest" -) - -var log = logf.Log.WithName("controller_cluster") -var hostPattern = regexp.MustCompile(`https://[0-9A-F]+\.[^.]+\.([^.]+)\.eks\.amazonaws\.com`) - -// Add creates a new Cluster Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager, c utils.Config) error { - return add(mgr, newReconciler(mgr, c)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager, c utils.Config) reconcile.Reconciler { - return &ReconcileCluster{client: mgr.GetClient(), scheme: mgr.GetScheme(), config: c} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - _, err := builder.ControllerManagedBy(mgr). - For(&picchuv1alpha1.Cluster{}). - Build(r) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileCluster{} - -// ReconcileCluster reconciles a Cluster object -type ReconcileCluster struct { - // This client, initialized using mgr.Client() above, is a split client - // that reads objects from the cache and writes to the apiserver - client client.Client - scheme *runtime.Scheme - config utils.Config -} - -// Reconcile reads that state of the cluster for a Cluster object and makes changes based on the state read -// and what is in the Cluster.Spec -// Note: -// The Controller will requeue the Request to be processed again if the returned error is non-nil or -// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. -func (r *ReconcileCluster) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) - - // Fetch the Cluster instance - instance := &picchuv1alpha1.Cluster{} - err := r.client.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - r.scheme.Default(instance) - - // This means the cluster is new and needs the finalizer added - if !instance.IsDeleted() { - if instance.IsFinalized() { - instance.AddFinalizer() - return reconcile.Result{Requeue: true}, r.client.Update(context.TODO(), instance) - } - if !instance.Spec.Enabled { - reqLogger.Info("Disabled, no status") - instance.Status = picchuv1alpha1.ClusterStatus{} - } else { - secret := &corev1.Secret{} - selector := types.NamespacedName{ - Name: instance.Name, - Namespace: instance.Namespace, - } - err = r.client.Get(context.TODO(), selector, secret) - if err != nil { - secret = nil - } - if secret != nil { - config, err := instance.Config(secret) - if err != nil { - reqLogger.Error(err, "Failed to create kube config") - return reconcile.Result{}, err - } - ready := true - version, err := ServerVersion(config) - if err != nil { - ready = false - } - - reqLogger.Info("Setting status") - instance.Status = picchuv1alpha1.ClusterStatus{ - Kubernetes: picchuv1alpha1.ClusterKubernetesStatus{ - Version: FormatVersion(version), - Ready: ready, - }, - } - } - } - err = utils.UpdateStatus(context.TODO(), r.client, instance) - if err != nil { - reqLogger.Error(err, "Failed to update Cluster status") - return reconcile.Result{}, err - } - return reconcile.Result{RequeueAfter: r.config.RequeueAfter}, nil - } - if !instance.IsFinalized() { - instance.Finalize() - return reconcile.Result{}, r.client.Update(context.TODO(), instance) - } - return reconcile.Result{}, nil -} - -func FormatVersion(version *version.Info) string { - if version != nil && version.Major != "" && version.Minor != "" { - return fmt.Sprintf("%s.%s", version.Major, version.Minor) - } else { - return "" - } -} - -func ServerVersion(config *rest.Config) (*version.Info, error) { - disco, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - return disco.ServerVersion() -} diff --git a/pkg/controller/clustersecrets/clustersecrets_controller.go b/pkg/controller/clustersecrets/clustersecrets_controller.go deleted file mode 100644 index ad613f1e..00000000 --- a/pkg/controller/clustersecrets/clustersecrets_controller.go +++ /dev/null @@ -1,104 +0,0 @@ -package clustersecrets - -import ( - "context" - - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var log = logf.Log.WithName("controller_clustersecrets") - -// Add creates a new ClusterSecrets Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager, c utils.Config) error { - return add(mgr, newReconciler(mgr, c)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager, c utils.Config) reconcile.Reconciler { - cfg, err := config.GetConfig() - if err != nil { - panic("Couldn't create client") - } - cli, err := client.New(cfg, client.Options{}) - if err != nil { - panic("Couldn't create client") - } - return &ReconcileClusterSecrets{client: cli, scheme: mgr.GetScheme(), config: c} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - _, err := builder.ControllerManagedBy(mgr). - For(&picchuv1alpha1.ClusterSecrets{}). - WithEventFilter(predicate.ResourceVersionChangedPredicate{}). - Build(r) - - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileClusterSecrets{} - -// ReconcileClusterSecrets reconciles a ClusterSecrets object -type ReconcileClusterSecrets struct { - // This client, initialized using mgr.Client() above, is a split client - // that reads objects from the cache and writes to the apiserver - client client.Client - scheme *runtime.Scheme - config utils.Config -} - -// Reconcile reads that state of the cluster for a ClusterSecrets object and makes changes based on the state read -// and what is in the ClusterSecrets.Spec -// Note: -// The Controller will requeue the Request to be processed again if the returned error is non-nil or -// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. -func (r *ReconcileClusterSecrets) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) - - // Fetch the ClusterSecrets instance - instance := &picchuv1alpha1.ClusterSecrets{} - err := r.client.Get(ctx, request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - r.scheme.Default(instance) - - rreq := newReconcileRequest(r, instance, reqLogger) - - // This means the cluster is new and needs the finalizer added - if !instance.IsDeleted() { - if instance.IsFinalized() { - instance.AddFinalizer() - return reconcile.Result{Requeue: true}, r.client.Update(ctx, instance) - } - return reconcile.Result{}, rreq.reconcile(ctx) - } - if !instance.IsFinalized() { - return reconcile.Result{}, rreq.finalize(ctx) - } - - return reconcile.Result{}, nil -} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go deleted file mode 100644 index 5ce71943..00000000 --- a/pkg/controller/controller.go +++ /dev/null @@ -1,19 +0,0 @@ -package controller - -import ( - "go.medium.engineering/picchu/pkg/controller/utils" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// AddToManagerFuncs is a list of functions to add all Controllers to the Manager -var AddToManagerFuncs []func(manager.Manager, utils.Config) error - -// AddToManager adds all Controllers to the Manager -func AddToManager(m manager.Manager, c utils.Config) error { - for _, f := range AddToManagerFuncs { - if err := f(m, c); err != nil { - return err - } - } - return nil -} diff --git a/pkg/controller/revision/revision_controller_test.go b/pkg/controller/revision/revision_controller_test.go deleted file mode 100644 index 0ed28af3..00000000 --- a/pkg/controller/revision/revision_controller_test.go +++ /dev/null @@ -1,131 +0,0 @@ -package revision - -import ( - "context" - "testing" - "time" - - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/prometheus/common/model" - - "github.com/golang/mock/gomock" - "go.medium.engineering/picchu/pkg/prometheus" - "go.medium.engineering/picchu/pkg/prometheus/mocks" - - testify "github.com/stretchr/testify/assert" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/test" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func TestReconcileRevision_Reconcile(t *testing.T) { - log := test.MustNewLogger() - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(2)*time.Minute) - defer cancel() - scheme := runtime.NewScheme() - picchu.AddToScheme(scheme) - picchu.RegisterDefaults(scheme) - ctrl := gomock.NewController(t) - m := mocks.NewMockPromAPI(ctrl) - m.EXPECT().Query(gomock.Any(), gomock.Any(), gomock.Any()).Return(model.Vector{}, nil, nil).AnyTimes() - - for _, test := range []struct { - state string - expected bool - }{ - { - state: "deployed", - expected: false, - }, - { - state: "deploying", - expected: false, - }, - { - state: "releasing", - expected: false, - }, - { - state: "released", - expected: false, - }, - { - state: "timingout", - expected: true, - }, - } { - t.Run(test.state, func(t *testing.T) { - assert := testify.New(t) - fixtures := []client.Object{ - &picchu.Revision{ - ObjectMeta: meta.ObjectMeta{ - Name: "rev", - Namespace: "picchu", - Labels: map[string]string{ - "label": "value", - }, - }, - Spec: picchu.RevisionSpec{ - App: picchu.RevisionApp{ - Name: "app", - Ref: "ref", - Tag: "v1", - Image: "image", - }, - Targets: []picchu.RevisionTarget{ - { - Name: "target", - Fleet: "fleet", - }, - }, - }, - }, - &picchu.ReleaseManager{ - ObjectMeta: meta.ObjectMeta{ - Name: "app-target", - Namespace: "picchu", - Labels: map[string]string{ - picchu.LabelTarget: "target", - picchu.LabelFleet: "fleet", - picchu.LabelApp: "app", - }, - }, - Status: picchu.ReleaseManagerStatus{ - Revisions: []picchu.ReleaseManagerRevisionStatus{ - { - Tag: "v1", - State: picchu.ReleaseManagerRevisionStateStatus{ - Current: test.state, - Target: test.state, - }, - }, - }, - }, - }, - } - cli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(fixtures...).Build() - reconciler := ReconcileRevision{ - client: cli, - scheme: scheme, - config: utils.Config{}, - promAPI: prometheus.InjectAPI(m, time.Duration(1)*time.Second), - customLogger: log, - } - key := client.ObjectKeyFromObject(fixtures[0]) - assert.NotEqual(key, types.NamespacedName{}) - res, err := reconciler.Reconcile(ctx, reconcile.Request{NamespacedName: key}) - assert.NoError(err) - assert.NotNil(res) - - instance := &picchu.Revision{} - assert.NoError(cli.Get(ctx, key, instance)) - assert.Equal(test.expected, instance.Spec.Failed) - }) - } -} diff --git a/pkg/openapi/zz_generated.openapi.go b/pkg/openapi/zz_generated.openapi.go deleted file mode 100644 index 967d576d..00000000 --- a/pkg/openapi/zz_generated.openapi.go +++ /dev/null @@ -1,420 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Copyright © 2019 A Medium Corporation. -// Licensed under the Apache License, Version 2.0; see the NOTICE file. - -// Code generated by openapi-gen. DO NOT EDIT. - -// This file was autogenerated by openapi-gen. Do not edit it manually! - -package openapi - -import ( - common "k8s.io/kube-openapi/pkg/common" - spec "k8s.io/kube-openapi/pkg/validation/spec" -) - -func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - return map[string]common.OpenAPIDefinition{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.Cluster": schema_pkg_apis_picchu_v1alpha1_Cluster(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecrets": schema_pkg_apis_picchu_v1alpha1_ClusterSecrets(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsSpec": schema_pkg_apis_picchu_v1alpha1_ClusterSecretsSpec(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsStatus": schema_pkg_apis_picchu_v1alpha1_ClusterSecretsStatus(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.Mirror": schema_pkg_apis_picchu_v1alpha1_Mirror(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManager": schema_pkg_apis_picchu_v1alpha1_ReleaseManager(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerSpec": schema_pkg_apis_picchu_v1alpha1_ReleaseManagerSpec(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerStatus": schema_pkg_apis_picchu_v1alpha1_ReleaseManagerStatus(ref), - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.Revision": schema_pkg_apis_picchu_v1alpha1_Revision(ref), - } -} - -func schema_pkg_apis_picchu_v1alpha1_Cluster(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Cluster is the Schema for the clusters API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSpec", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ClusterSecrets(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ClusterSecrets is the Schema for the clustersecrets API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsSpec", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretsStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ClusterSecretsSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ClusterSecretsSpec defines the desired state of ClusterSecrets", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "source": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretSource"), - }, - }, - "target": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretTarget"), - }, - }, - }, - Required: []string{"source", "target"}, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretSource", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ClusterSecretTarget"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ClusterSecretsStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ClusterSecretsStatus defines the observed state of ClusterSecrets", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "secrets": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "set", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Names of secrets copied to targets", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_picchu_v1alpha1_Mirror(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Mirror is the Schema for the mirrors API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.MirrorSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.MirrorStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.MirrorSpec", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.MirrorStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ReleaseManager(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ReleaseManager is the Schema for the releasemanagers API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerSpec", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ReleaseManagerSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ReleaseManagerSpec defines the desired state of ReleaseManager", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "fleet": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "app": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "target": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "variants": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.Variant"), - }, - }, - }, - }, - }, - }, - Required: []string{"fleet", "app", "target"}, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.Variant"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_ReleaseManagerStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ReleaseManagerStatus defines the observed state of ReleaseManager", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "revisions": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerRevisionStatus"), - }, - }, - }, - }, - }, - "lastUpdated": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - }, - Required: []string{"lastUpdated"}, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.ReleaseManagerRevisionStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} - -func schema_pkg_apis_picchu_v1alpha1_Revision(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Revision is the Schema for the revisions API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.RevisionSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.RevisionStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.RevisionSpec", "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1.RevisionStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} diff --git a/pkg/webhook/certificate.go b/pkg/webhook/certificate.go deleted file mode 100644 index 4fbdfbd1..00000000 --- a/pkg/webhook/certificate.go +++ /dev/null @@ -1,137 +0,0 @@ -package webhook - -import ( - "bytes" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "math/big" - "time" -) - -type Certificate struct { - CaCrt []byte - CaKey []byte - Crt []byte - Key []byte -} - -func (c *Certificate) CABundle() []byte { - return append(c.CaCrt, c.CaKey...) -} - -func GenerateSelfSignedCertificate(hostname string) (*Certificate, error) { - caPrivKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - return nil, err - } - ca := &x509.Certificate{ - SerialNumber: big.NewInt(2019), - Subject: pkix.Name{ - Organization: []string{"Medium"}, - Country: []string{"US"}, - Locality: []string{"San Francisco"}, - StreetAddress: []string{"799 Market Street"}, - PostalCode: []string{"94103"}, - }, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(10, 0, 0), - IsCA: true, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, - BasicConstraintsValid: true, - } - caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey) - if err != nil { - return nil, err - } - - caPEM := new(bytes.Buffer) - err = pem.Encode(caPEM, &pem.Block{ - Type: "CERTIFICATE", - Bytes: caBytes, - }) - if err != nil { - return nil, err - } - - caPrivKeyPEM := new(bytes.Buffer) - caPrivKeyBytes, err := x509.MarshalECPrivateKey(caPrivKey) - if err != nil { - return nil, err - } - err = pem.Encode(caPrivKeyPEM, &pem.Block{ - Type: "PRIVATE KEY", - Bytes: caPrivKeyBytes, - }) - if err != nil { - return nil, err - } - - cert := &x509.Certificate{ - SerialNumber: big.NewInt(1658), - Subject: pkix.Name{ - Organization: []string{"Medium"}, - Country: []string{"US"}, - Locality: []string{"San Francisco"}, - StreetAddress: []string{"799 Market Street"}, - PostalCode: []string{"94103"}, - }, - DNSNames: []string{hostname}, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(10, 0, 0), - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, - SubjectKeyId: []byte{1, 2, 3, 4, 6}, - KeyUsage: x509.KeyUsageDigitalSignature, - } - - certPrivKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - return nil, err - } - - certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey) - if err != nil { - return nil, err - } - - certPEM := new(bytes.Buffer) - err = pem.Encode(certPEM, &pem.Block{ - Type: "CERTIFICATE", - Bytes: certBytes, - }) - if err != nil { - return nil, err - } - - certPrivKeyPEM := new(bytes.Buffer) - certPrivKeyBytes, err := x509.MarshalECPrivateKey(certPrivKey) - if err != nil { - return nil, err - } - err = pem.Encode(certPrivKeyPEM, &pem.Block{ - Type: "PRIVATE KEY", - Bytes: certPrivKeyBytes, - }) - if err != nil { - return nil, err - } - - return &Certificate{ - CaCrt: caPEM.Bytes(), - CaKey: caPrivKeyPEM.Bytes(), - Crt: certPEM.Bytes(), - Key: certPrivKeyPEM.Bytes(), - }, nil -} - -func MustGenerateSelfSignedCertificate(hostname string) *Certificate { - c, err := GenerateSelfSignedCertificate(hostname) - if err != nil { - panic(err) - } - return c -} diff --git a/pkg/webhook/revision/common.go b/pkg/webhook/revision/common.go deleted file mode 100644 index db81d788..00000000 --- a/pkg/webhook/revision/common.go +++ /dev/null @@ -1,35 +0,0 @@ -package revision - -import picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - -type portInfo struct { - picchu.PortInfo - index int -} - -// returns a map of ingresses and ports mapped to ingresses -func bucketIngressPorts(target picchu.RevisionTarget) map[string][]portInfo { - // bucket ports by mode - track := map[string][]portInfo{} - for i := range target.Ports { - pi := portInfo{ - PortInfo: target.Ports[i], - index: i, - } - if pi.Ingresses != nil { - for _, ingress := range pi.Ingresses { - track[ingress] = append(track[ingress], pi) - } - continue - } - - switch pi.Mode { - case picchu.PortPublic: - track["public"] = append(track["public"], pi) - track["private"] = append(track["private"], pi) - case picchu.PortPrivate: - track["private"] = append(track["private"], pi) - } - } - return track -} diff --git a/pkg/webhook/revision/mutating.go b/pkg/webhook/revision/mutating.go deleted file mode 100644 index e59f1e22..00000000 --- a/pkg/webhook/revision/mutating.go +++ /dev/null @@ -1,137 +0,0 @@ -package revision - -import ( - "context" - "fmt" - - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "gomodules.xyz/jsonpatch/v2" - admissionv1 "k8s.io/api/admission/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -type revisionMutator struct { - client client.Client - decoder *admission.Decoder -} - -func (r *revisionMutator) Handle(ctx context.Context, req admission.Request) admission.Response { - resp := &admission.Response{ - AdmissionResponse: admissionv1.AdmissionResponse{ - UID: req.UID, - Allowed: false, - }, - } - clog.Info("Got revision mutation request", "req", req) - rev := &picchu.Revision{} - if err := r.decoder.Decode(req, rev); err != nil { - clog.Error(err, "Failed to decode revision") - resp.Result = &metav1.Status{Message: "internal error"} - return *resp - } - patches := r.getPatches(rev) - if len(patches) > 0 { - clog.Info("Patching revision", "patches", patches) - resp.Result = &metav1.Status{Message: "patching revision"} - resp.Allowed = true - resp.Patches = patches - return *resp - } - clog.Info("No patches needed") - resp.Result = &metav1.Status{Message: "ok"} - resp.Allowed = true - return *resp -} - -func (r *revisionMutator) getPatches(rev *picchu.Revision) []jsonpatch.JsonPatchOperation { - return append(r.getIngressesPatches(rev), r.getIngressDefaultPortPatches(rev)...) -} - -func (r *revisionMutator) getIngressesPatches(rev *picchu.Revision) []jsonpatch.JsonPatchOperation { - var patches []jsonpatch.JsonPatchOperation - for i := range rev.Spec.Targets { - for j := range rev.Spec.Targets[i].Ports { - port := rev.Spec.Targets[i].Ports[j] - var ingresses []string - if len(port.Ingresses) > 0 { - continue - } - if port.Mode == picchu.PortPrivate || port.Mode == picchu.PortPublic { - ingresses = append(ingresses, "private") - } - if port.Mode == picchu.PortPublic { - ingresses = append(ingresses, "public") - } - if len(ingresses) > 0 { - patches = append(patches, jsonpatch.JsonPatchOperation{ - Operation: "add", - Path: fmt.Sprintf("/spec/targets/%d/ports/%d/ingresses", i, j), - Value: ingresses, - }) - } - } - - } - return patches -} - -func (r *revisionMutator) getIngressDefaultPortPatches(rev *picchu.Revision) []jsonpatch.JsonPatchOperation { - // if a single public or private ingress port is defined in a target and it's not set to default, it will be set as - // the default. - // if multiple ingress ports are defined and none are set to default and there is a port called 'http', it will be - // set to default - // internal ports will never be set as default - var patches []jsonpatch.JsonPatchOperation - for i := range rev.Spec.Targets { - ingressDefaultPorts := map[string]string{} - for ingress, ports := range bucketIngressPorts(rev.Spec.Targets[i]) { - if len(ports) == 1 { - ingressDefaultPorts[ingress] = ports[0].Name - } - - var httpFound bool - var defaultFound bool - for j := range ports { - port := ports[j] - defaultFound = defaultFound || port.Default - if port.Name == "http" { - httpFound = true - } - } - if !defaultFound && httpFound { - ingressDefaultPorts[ingress] = "http" - } - } - existing := rev.Spec.Targets[i].DefaultIngressPorts - if (existing == nil || len(existing) <= 0) && len(ingressDefaultPorts) > 0 { - patches = append(patches, jsonpatch.JsonPatchOperation{ - Operation: "add", - Path: fmt.Sprintf("/spec/targets/%d/defaultIngressPorts", i), - Value: ingressDefaultPorts, - }) - continue - } - for ingress, def := range ingressDefaultPorts { - if _, ok := existing[ingress]; !ok { - patches = append(patches, jsonpatch.JsonPatchOperation{ - Operation: "add", - Path: fmt.Sprintf("/spec/targets/%d/defaultIngressPorts[%s]", i, ingress), - Value: def, - }) - } - } - } - return patches -} - -func (r *revisionMutator) InjectClient(c client.Client) error { - r.client = c - return nil -} - -func (r *revisionMutator) InjectDecoder(d *admission.Decoder) error { - r.decoder = d - return nil -} diff --git a/pkg/webhook/revision/register.go b/pkg/webhook/revision/register.go deleted file mode 100644 index e5dc8238..00000000 --- a/pkg/webhook/revision/register.go +++ /dev/null @@ -1,17 +0,0 @@ -package revision - -import ( - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -var ( - clog = logf.Log.WithName("webhook_revision") -) - -func Register(mgr manager.Manager) { - clog.Info("Registering revision webhook") - mgr.GetWebhookServer().Register("/validate-revisions", &webhook.Admission{Handler: &revisionValidator{}}) - mgr.GetWebhookServer().Register("/mutate-revisions", &webhook.Admission{Handler: &revisionMutator{}}) -} diff --git a/pkg/webhook/revision/validating.go b/pkg/webhook/revision/validating.go deleted file mode 100644 index 9e0663c6..00000000 --- a/pkg/webhook/revision/validating.go +++ /dev/null @@ -1,106 +0,0 @@ -package revision - -import ( - "context" - "fmt" - - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - admissionv1 "k8s.io/api/admission/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -type failure struct { - target string - reason string -} - -func (f *failure) string() string { - return fmt.Sprintf("Failure to validate target %s because %s", f.target, f.reason) -} - -type revisionValidator struct { - client client.Client - decoder *admission.Decoder -} - -func (r *revisionValidator) Handle(ctx context.Context, req admission.Request) admission.Response { - resp := &admission.Response{ - AdmissionResponse: admissionv1.AdmissionResponse{ - UID: req.UID, - Allowed: false, - }, - } - clog.Info("Got revision validation request", "req", req) - rev := &picchu.Revision{} - if err := r.decoder.Decode(req, rev); err != nil { - clog.Error(err, "Failed to decode revision") - resp.Result = &metav1.Status{Message: "internal error"} - return *resp - } - failures := r.failures(rev) - for _, failure := range failures { - clog.Error(nil, failure.string(), "revision", rev) - } - /* - TODO(bob): turn on validation and format error messages - if len(failures) > 0 { - msg := "Must specify existing port for defaultIngressPort for all ingresses" - return admission.Denied(fmt.Sprintf(msg, invalidTargets)) - } - */ - resp.Allowed = true - return *resp -} - -func (r *revisionValidator) failures(rev *picchu.Revision) (failures []failure) { - // exactly one port per target ingress should be set as default. - for _, target := range rev.Spec.Targets { - found := target.Release.ScalingStrategy == "" - for _, s := range picchu.ScalingStrategies { - if target.Release.ScalingStrategy == s { - found = true - } - } - if !found { - msg := fmt.Sprintf("Invalid scaling strategy %s found", target.Release.ScalingStrategy) - failures = append(failures, failure{target.Name, msg}) - } - buckets := bucketIngressPorts(target) - for ingress, ports := range buckets { - if target.DefaultIngressPorts == nil { - msg := fmt.Sprintf("Default ingress ports not specified for %s", ingress) - failures = append(failures, failure{target.Name, msg}) - } - found := false - for _, port := range ports { - if target.DefaultIngressPorts[ingress] == port.Name { - found = true - break - } - } - if !found { - msg := fmt.Sprintf("Specified default ingress port for %s doesn't exist", ingress) - failures = append(failures, failure{target.Name, msg}) - } - } - for ingress := range target.DefaultIngressPorts { - if _, ok := buckets[ingress]; !ok { - msg := fmt.Sprintf("Specified default for ingress %s that doesn't exist", ingress) - failures = append(failures, failure{target.Name, msg}) - } - } - } - return -} - -func (r *revisionValidator) InjectClient(c client.Client) error { - r.client = c - return nil -} - -func (r *revisionValidator) InjectDecoder(d *admission.Decoder) error { - r.decoder = d - return nil -} diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go deleted file mode 100644 index 7746be82..00000000 --- a/pkg/webhook/webhook.go +++ /dev/null @@ -1,213 +0,0 @@ -package webhook - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "path" - "time" - - "github.com/go-logr/logr" - "go.medium.engineering/picchu/pkg/webhook/revision" - admissionregistration "k8s.io/api/admissionregistration/v1beta1" - core "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -const ( - LabelName = "name" - ServicePort = 443 - ServiceName = "webhook" - ServicePortName = "webhook" - ServiceLabelName = "picchu-webhook" - SecretName = "webhook-cert" - WebhookConfigurationName = "picchu-policy" - ValidationWebhookName = "picchu-validation.medium.engineering" - MutationWebhookName = "picchu-mutation.medium.engineering" - CrtDir = "/tmp/k8s-webhook-server/serving-certs" -) - -func Register(mgr manager.Manager) { - revision.Register(mgr) -} - -// Init creates all necessary infrastructure to support webhooks. Service, Secret, certs and WebhookConfigurations. -// It is intended to run on the same /tmp volume as the picchu operator which requires the certs to be present. -func Init(cli client.Client, targetPort int32, namespace string, log logr.Logger) { - log = log.WithName("webhook") - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second) - defer cancel() - service := &core.Service{ - ObjectMeta: meta.ObjectMeta{ - Name: ServiceName, - Namespace: namespace, - }, - Spec: core.ServiceSpec{ - Ports: []core.ServicePort{{ - Name: ServicePortName, - Protocol: "TCP", - Port: ServicePort, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: targetPort, - }, - }}, - Selector: map[string]string{ - LabelName: ServiceLabelName, - }, - }, - } - spec := service.DeepCopy().Spec - log.Info("Creating service", "service", service) - controllerutil.CreateOrUpdate(ctx, cli, service, func() error { - service.Spec = spec - return nil - }) - - secret := &core.Secret{} - cert := &Certificate{} - err := cli.Get(ctx, client.ObjectKey{ - Namespace: namespace, - Name: SecretName, - }, secret) - if err != nil && !errors.IsNotFound(err) { - panic(err) - } - if err != nil { - hostname := fmt.Sprintf("%s.%s.svc", ServiceName, namespace) - cert = MustGenerateSelfSignedCertificate(hostname) - secret = &core.Secret{ - ObjectMeta: meta.ObjectMeta{ - Namespace: namespace, - Name: SecretName, - }, - Data: map[string][]byte{ - "ca-tls.crt": cert.CaCrt, - "ca-tls.key": cert.CaKey, - "tls.key": cert.Key, - "tls.crt": cert.Crt, - }, - Type: "Opaque", - } - log.Info("Creating secret", "secret", secret) - panicOnError(cli.Create(ctx, secret)) - } else { - log.Info("Found secret", "secret", secret) - cert = &Certificate{ - CaCrt: secret.Data["ca-tls.crt"], - CaKey: secret.Data["ca-tls.key"], - Crt: secret.Data["tls.crt"], - Key: secret.Data["tls.key"], - } - } - - log.Info("Creating cert files") - panicOnError(os.MkdirAll(CrtDir, os.FileMode(0755))) - panicOnError(ioutil.WriteFile(path.Join(CrtDir, "tls.crt"), cert.Crt, os.FileMode(0644))) - panicOnError(ioutil.WriteFile(path.Join(CrtDir, "tls.key"), cert.Key, os.FileMode(0644))) - - noSideEffect := admissionregistration.SideEffectClassNone - validator := &admissionregistration.ValidatingWebhookConfiguration{ - ObjectMeta: meta.ObjectMeta{ - Name: WebhookConfigurationName, - }, - Webhooks: []admissionregistration.ValidatingWebhook{{ - Name: ValidationWebhookName, - ClientConfig: admissionregistration.WebhookClientConfig{ - Service: &admissionregistration.ServiceReference{ - Namespace: namespace, - Name: ServiceName, - Path: pointer.StringPtr("/validate-revisions"), - Port: pointer.Int32Ptr(ServicePort), - }, - CABundle: cert.CABundle(), - }, - Rules: []admissionregistration.RuleWithOperations{{ - Operations: []admissionregistration.OperationType{ - admissionregistration.Create, - admissionregistration.Update, - }, - Rule: admissionregistration.Rule{ - APIGroups: []string{"picchu.medium.engineering"}, - APIVersions: []string{"v1alpha1"}, - Resources: []string{"revisions"}, - Scope: scopeTypePtr(admissionregistration.AllScopes), - }, - }}, - FailurePolicy: failurePolicyTypePtr(admissionregistration.Fail), - TimeoutSeconds: pointer.Int32Ptr(1), - AdmissionReviewVersions: []string{"v1beta1"}, - SideEffects: &noSideEffect, - }}, - } - vWebhooks := validator.DeepCopy().Webhooks - log.Info("Creating validation webhook", "webhook", validator) - controllerutil.CreateOrUpdate(ctx, cli, validator, func() error { - validator.Webhooks = vWebhooks - return nil - }) - - mutator := &admissionregistration.MutatingWebhookConfiguration{ - ObjectMeta: meta.ObjectMeta{ - Name: WebhookConfigurationName, - }, - Webhooks: []admissionregistration.MutatingWebhook{{ - Name: MutationWebhookName, - ClientConfig: admissionregistration.WebhookClientConfig{ - Service: &admissionregistration.ServiceReference{ - Namespace: namespace, - Name: ServiceName, - Path: pointer.StringPtr("/mutate-revisions"), - Port: pointer.Int32Ptr(ServicePort), - }, - CABundle: cert.CABundle(), - }, - Rules: []admissionregistration.RuleWithOperations{{ - Operations: []admissionregistration.OperationType{ - admissionregistration.Create, - admissionregistration.Update, - }, - Rule: admissionregistration.Rule{ - APIGroups: []string{"picchu.medium.engineering"}, - APIVersions: []string{"v1alpha1"}, - Resources: []string{"revisions"}, - Scope: scopeTypePtr(admissionregistration.AllScopes), - }, - }}, - FailurePolicy: failurePolicyTypePtr(admissionregistration.Fail), - TimeoutSeconds: pointer.Int32Ptr(1), - AdmissionReviewVersions: []string{"v1beta1"}, - SideEffects: &noSideEffect, - }}, - } - mWebhooks := mutator.DeepCopy().Webhooks - log.Info("Creating mutating webhook", "webhook", mutator) - panicOnError(controllerutil.CreateOrUpdate(ctx, cli, mutator, func() error { - mutator.Webhooks = mWebhooks - return nil - })) -} - -func failurePolicyTypePtr(f admissionregistration.FailurePolicyType) *admissionregistration.FailurePolicyType { - return &f -} - -func scopeTypePtr(s admissionregistration.ScopeType) *admissionregistration.ScopeType { - return &s -} - -func panicOnError(vargs ...interface{}) { - switch v := vargs[len(vargs)-1].(type) { - case error: - if v != nil { - panic(v) - } - } -} diff --git a/pkg/plan/README.md b/plan/README.md similarity index 100% rename from pkg/plan/README.md rename to plan/README.md diff --git a/pkg/plan/applier.go b/plan/applier.go similarity index 93% rename from pkg/plan/applier.go rename to plan/applier.go index 16316aa7..d555ae56 100644 --- a/pkg/plan/applier.go +++ b/plan/applier.go @@ -2,9 +2,10 @@ package plan import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" "reflect" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "github.com/go-logr/logr" "golang.org/x/sync/errgroup" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/plan/common.go b/plan/common.go similarity index 97% rename from pkg/plan/common.go rename to plan/common.go index e296c392..d421dfe6 100644 --- a/pkg/plan/common.go +++ b/plan/common.go @@ -5,13 +5,13 @@ import ( "errors" "fmt" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/controller/utils" + picchu "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/controllers/utils" - slov1alpha1 "github.com/Medium/service-level-operator/pkg/apis/monitoring/v1alpha1" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/go-logr/logr" wpav1 "github.com/practo/k8s-worker-pod-autoscaler/pkg/apis/workerpodautoscaler/v1" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + slov1alpha1 "github.com/slok/sloth/pkg/kubernetes/api/sloth/v1" istiov1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" appsv1 "k8s.io/api/apps/v1" autoscaling "k8s.io/api/autoscaling/v2beta2" @@ -257,9 +257,9 @@ func CreateOrUpdate( if err != nil { return err } - case *slov1alpha1.ServiceLevel: + case *slov1alpha1.PrometheusServiceLevel: typed := orig.DeepCopy() - sl := &slov1alpha1.ServiceLevel{ + sl := &slov1alpha1.PrometheusServiceLevel{ ObjectMeta: metav1.ObjectMeta{ Name: typed.Name, Namespace: typed.Namespace, diff --git a/pkg/plan/common_test.go b/plan/common_test.go similarity index 95% rename from pkg/plan/common_test.go rename to plan/common_test.go index 2dd618bc..16efe099 100644 --- a/pkg/plan/common_test.go +++ b/plan/common_test.go @@ -2,17 +2,18 @@ package plan import ( "context" + "testing" + "time" + test2 "go.medium.engineering/kubernetes/pkg/test" coreAsserts "go.medium.engineering/kubernetes/pkg/test/core/v1" - picchu "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - picchuScheme "go.medium.engineering/picchu/pkg/client/scheme" - "go.medium.engineering/picchu/pkg/test" + picchu "go.medium.engineering/picchu/api/v1alpha1" + picchuScheme "go.medium.engineering/picchu/client/scheme" + "go.medium.engineering/picchu/test" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "testing" - "time" ) var ( diff --git a/pkg/plan/composite.go b/plan/composite.go similarity index 91% rename from pkg/plan/composite.go rename to plan/composite.go index c5aa423b..0f9de833 100644 --- a/pkg/plan/composite.go +++ b/plan/composite.go @@ -4,7 +4,7 @@ import ( "context" "reflect" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/pkg/plan/composite_test.go b/plan/composite_test.go similarity index 85% rename from pkg/plan/composite_test.go rename to plan/composite_test.go index 14dda4ff..ccea14a1 100644 --- a/pkg/plan/composite_test.go +++ b/plan/composite_test.go @@ -2,13 +2,14 @@ package plan_test import ( "context" - picchuv1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" - "go.medium.engineering/picchu/pkg/plan" "testing" - "go.medium.engineering/picchu/pkg/mocks" - planmocks "go.medium.engineering/picchu/pkg/plan/mocks" - "go.medium.engineering/picchu/pkg/test" + picchuv1alpha1 "go.medium.engineering/picchu/api/v1alpha1" + "go.medium.engineering/picchu/plan" + + "go.medium.engineering/picchu/mocks" + planmocks "go.medium.engineering/picchu/plan/mocks" + "go.medium.engineering/picchu/test" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/pkg/plan/mocks/plan_mock.go b/plan/mocks/plan_mock.go similarity index 91% rename from pkg/plan/mocks/plan_mock.go rename to plan/mocks/plan_mock.go index 23d88b23..c622a56b 100644 --- a/pkg/plan/mocks/plan_mock.go +++ b/plan/mocks/plan_mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: go.medium.engineering/picchu/pkg/plan (interfaces: Plan) +// Source: go.medium.engineering/picchu/plan (interfaces: Plan) // Package mocks is a generated GoMock package. package mocks @@ -8,7 +8,7 @@ import ( context "context" logr "github.com/go-logr/logr" gomock "github.com/golang/mock/gomock" - v1alpha1 "go.medium.engineering/picchu/pkg/apis/picchu/v1alpha1" + v1alpha1 "go.medium.engineering/picchu/api/v1alpha1" reflect "reflect" client "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/pkg/plan/test/common.go b/plan/test/common.go similarity index 93% rename from pkg/plan/test/common.go rename to plan/test/common.go index d02d00f6..2f7425a4 100644 --- a/pkg/plan/test/common.go +++ b/plan/test/common.go @@ -3,12 +3,13 @@ package plan import ( "bytes" "fmt" - "github.com/stretchr/testify/assert" "reflect" "testing" - "go.medium.engineering/picchu/pkg/controller/utils" - "go.medium.engineering/picchu/pkg/mocks" + "github.com/stretchr/testify/assert" + + "go.medium.engineering/picchu/controllers/utils" + "go.medium.engineering/picchu/mocks" "github.com/andreyvit/diff" "github.com/golang/mock/gomock" @@ -20,7 +21,7 @@ import ( ) var ( - NotFoundError = &errors.StatusError{metav1.Status{ + NotFoundError = &errors.StatusError{ErrStatus: metav1.Status{ Reason: metav1.StatusReasonNotFound, }} yamlSerializer runtime.Serializer diff --git a/pkg/prometheus/api.go b/prometheus/api.go similarity index 99% rename from pkg/prometheus/api.go rename to prometheus/api.go index bb58ce46..e7aa1016 100644 --- a/pkg/prometheus/api.go +++ b/prometheus/api.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "sync" "text/template" "time" diff --git a/pkg/prometheus/api_test.go b/prometheus/api_test.go similarity index 98% rename from pkg/prometheus/api_test.go rename to prometheus/api_test.go index 97513674..8a616d3e 100644 --- a/pkg/prometheus/api_test.go +++ b/prometheus/api_test.go @@ -10,7 +10,7 @@ import ( "github.com/golang/mock/gomock" "github.com/prometheus/common/model" "github.com/stretchr/testify/assert" - "go.medium.engineering/picchu/pkg/prometheus/mocks" + "go.medium.engineering/picchu/prometheus/mocks" ) func TestPrometheusCache(t *testing.T) { diff --git a/pkg/prometheus/mocks/mock_promapi.go b/prometheus/mocks/mock_promapi.go similarity index 95% rename from pkg/prometheus/mocks/mock_promapi.go rename to prometheus/mocks/mock_promapi.go index 27700177..e50bd278 100644 --- a/pkg/prometheus/mocks/mock_promapi.go +++ b/prometheus/mocks/mock_promapi.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: go.medium.engineering/picchu/pkg/prometheus (interfaces: PromAPI) +// Source: go.medium.engineering/picchu/prometheus (interfaces: PromAPI) // Package mocks is a generated GoMock package. package mocks diff --git a/pkg/prometheus/parse.go b/prometheus/parse.go similarity index 91% rename from pkg/prometheus/parse.go rename to prometheus/parse.go index 906e6d10..149e99a2 100644 --- a/pkg/prometheus/parse.go +++ b/prometheus/parse.go @@ -2,7 +2,8 @@ package prometheus import ( "errors" - promql "github.com/prometheus/prometheus/promql" + + promql "github.com/prometheus/prometheus/promql/parser" ) // MetricNames returns a map (set of keys) of unique metric names included in PromQL query string @@ -53,8 +54,8 @@ func metricNames(m map[string]bool, node promql.Node) error { m[n.Name] = true case *promql.MatrixSelector: - // metricNames(m, n.VectorSelector) - m[n.Name] = true + metricNames(m, n.VectorSelector) + //m[n.Name] = true case *promql.NumberLiteral, *promql.StringLiteral: // nothing to do diff --git a/pkg/prometheus/parse_test.go b/prometheus/parse_test.go similarity index 100% rename from pkg/prometheus/parse_test.go rename to prometheus/parse_test.go diff --git a/pkg/sentry/client.go b/sentry/client.go similarity index 100% rename from pkg/sentry/client.go rename to sentry/client.go diff --git a/pkg/sentry/error.go b/sentry/error.go similarity index 100% rename from pkg/sentry/error.go rename to sentry/error.go diff --git a/pkg/sentry/release.go b/sentry/release.go similarity index 100% rename from pkg/sentry/release.go rename to sentry/release.go diff --git a/pkg/test/monitoring/v1/zz_generated.matcher.go b/test/monitoring/v1/zz_generated.matcher.go similarity index 98% rename from pkg/test/monitoring/v1/zz_generated.matcher.go rename to test/monitoring/v1/zz_generated.matcher.go index 153be787..363f1a17 100644 --- a/pkg/test/monitoring/v1/zz_generated.matcher.go +++ b/test/monitoring/v1/zz_generated.matcher.go @@ -3,7 +3,7 @@ package v1 import ( testing "testing" - v1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" assert "github.com/stretchr/testify/assert" test "go.medium.engineering/kubernetes/pkg/test" runtime "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/test/test.go b/test/test.go similarity index 100% rename from pkg/test/test.go rename to test/test.go diff --git a/version/version.go b/version/version.go deleted file mode 100644 index a600c68f..00000000 --- a/version/version.go +++ /dev/null @@ -1,14 +0,0 @@ -package version - -// force tools into vendor dir -import ( - _ "github.com/golang/mock/mockgen" - _ "go.medium.engineering/kubernetes/cmd/matcher-gen" - _ "k8s.io/code-generator/cmd/client-gen" - _ "k8s.io/code-generator/cmd/defaulter-gen" - _ "k8s.io/kube-openapi/cmd/openapi-gen" -) - -var ( - Version = "0.0.1" -)