├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .vscode └── launch.json ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── cmd └── echoperator │ └── main.go ├── go.mod ├── go.sum ├── hack ├── boilerplate.go.txt ├── hack.go └── hack.sh ├── internal ├── config │ └── config.go └── runner │ └── runner.go ├── manifests ├── crds │ ├── echo.yml │ └── scheduledecho.yml └── examples │ ├── hello-world-scheduled.yml │ └── hello-world.yml └── pkg ├── controller ├── controller.go ├── event.go ├── resource.go └── worker.go └── echo ├── echo.go └── v1alpha1 ├── apis ├── clientset │ └── versioned │ │ ├── clientset.go │ │ ├── doc.go │ │ ├── fake │ │ ├── clientset_generated.go │ │ ├── doc.go │ │ └── register.go │ │ ├── scheme │ │ ├── doc.go │ │ └── register.go │ │ └── typed │ │ └── echo │ │ └── v1alpha1 │ │ ├── doc.go │ │ ├── echo.go │ │ ├── echo_client.go │ │ ├── fake │ │ ├── doc.go │ │ ├── fake_echo.go │ │ ├── fake_echo_client.go │ │ └── fake_scheduledecho.go │ │ ├── generated_expansion.go │ │ └── scheduledecho.go ├── informers │ └── externalversions │ │ ├── echo │ │ ├── interface.go │ │ └── v1alpha1 │ │ │ ├── echo.go │ │ │ ├── interface.go │ │ │ └── scheduledecho.go │ │ ├── factory.go │ │ ├── generic.go │ │ └── internalinterfaces │ │ └── factory_interfaces.go └── listers │ └── echo │ └── v1alpha1 │ ├── echo.go │ ├── expansion_generated.go │ └── scheduledecho.go ├── doc.go ├── register.go ├── types.go └── zz_generated.deepcopy.go /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "**" 7 | push: 8 | branches: 9 | - "**" 10 | 11 | jobs: 12 | lint: 13 | name: Lint 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Setup Go 17 | uses: actions/setup-go@v3 18 | with: 19 | go-version: 1.18 20 | 21 | - name: Checkout code 22 | uses: actions/checkout@v3 23 | 24 | - name: GolangCI Lint 25 | uses: golangci/golangci-lint-action@v3 26 | with: 27 | version: v1.46.2 28 | 29 | build: 30 | name: Build 31 | runs-on: ubuntu-latest 32 | steps: 33 | - name: Setup Go 34 | uses: actions/setup-go@v3 35 | with: 36 | go-version: 1.18 37 | 38 | - name: Checkout code 39 | uses: actions/checkout@v2 40 | 41 | - name: Build 42 | run: make build 43 | 44 | test: 45 | name: Test 46 | runs-on: ubuntu-latest 47 | steps: 48 | - name: Setup Go 49 | uses: actions/setup-go@v3 50 | with: 51 | go-version: 1.18 52 | 53 | - name: Checkout code 54 | uses: actions/checkout@v2 55 | 56 | - name: Test 57 | run: make cover 58 | 59 | - name: Coverage 60 | uses: actions/upload-artifact@v2 61 | with: 62 | name: cover 63 | path: ./cover.html 64 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Fetch tags 18 | run: git fetch --force --tags 19 | 20 | - name: Setup QEMU 21 | uses: docker/setup-qemu-action@v2 22 | 23 | - name: Setup Docker Buildx 24 | uses: docker/setup-buildx-action@v2 25 | id: buildx 26 | 27 | - name: Login to container Registry 28 | uses: docker/login-action@v2 29 | with: 30 | username: ${{ github.repository_owner }} 31 | password: ${{ secrets.GITHUB_TOKEN }} 32 | registry: ghcr.io 33 | 34 | - name: Prepare 35 | id: prep 36 | run: | 37 | VERSION=sha-${GITHUB_SHA::8} 38 | if [[ $GITHUB_REF == refs/tags/* ]]; then 39 | VERSION=${GITHUB_REF/refs\/tags\//} 40 | fi 41 | echo ::set-output name=BUILD_DATE::$(date -u +'%Y-%m-%dT%H:%M:%SZ') 42 | echo ::set-output name=VERSION::${VERSION} 43 | 44 | - name: Publish multi-arch Docker image 45 | uses: docker/build-push-action@v4 46 | with: 47 | push: true 48 | builder: ${{ steps.buildx.outputs.name }} 49 | context: . 50 | file: ./Dockerfile 51 | platforms: linux/arm64,linux/amd64 52 | tags: | 53 | ghcr.io/${{ github.repository_owner }}/echoperator:${{ steps.prep.outputs.VERSION }} 54 | ghcr.io/${{ github.repository_owner }}/echoperator:latest 55 | labels: | 56 | org.opencontainers.image.title=${{ github.event.repository.name }} 57 | org.opencontainers.image.description=${{ github.event.repository.description }} 58 | org.opencontainers.image.source=${{ github.event.repository.html_url }} 59 | org.opencontainers.image.url=${{ github.event.repository.html_url }} 60 | org.opencontainers.image.revision=${{ github.sha }} 61 | org.opencontainers.image.version=${{ steps.prep.outputs.VERSION }} 62 | org.opencontainers.image.created=${{ steps.prep.outputs.BUILD_DATE }} 63 | 64 | - name: GoReleaser 65 | uses: goreleaser/goreleaser-action@v3 66 | with: 67 | version: latest 68 | args: release 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | bin/ 8 | 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | vendor/ 17 | 18 | # Env vars 19 | .env 20 | 21 | # Cover 22 | cover.* 23 | 24 | # Debugger 25 | __debug_bin -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | dupl: 3 | threshold: 100 4 | gocyclo: 5 | min-complexity: 15 6 | lll: 7 | line-length: 140 8 | misspell: 9 | locale: US 10 | 11 | linters: 12 | disable-all: true 13 | enable: 14 | - deadcode 15 | - dupl 16 | - errcheck 17 | - gocyclo 18 | - gofmt 19 | - goimports 20 | - gosimple 21 | - govet 22 | - ineffassign 23 | - lll 24 | - misspell 25 | - nestif 26 | - staticcheck 27 | - typecheck 28 | - unused 29 | - varcheck 30 | # not compatible with go 1.18 yet 31 | # - bodyclose 32 | # - noctx 33 | # - structcheck 34 | 35 | run: 36 | timeout: 5m 37 | go: "1.18" 38 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | project_name: echoperator 2 | builds: 3 | - main: ./cmd/echoperator 4 | binary: echoperator 5 | goos: 6 | - linux 7 | goarch: 8 | - arm64 9 | - amd64 10 | env: 11 | - CGO_ENABLED=0 12 | archives: 13 | - name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug", 9 | "type": "go", 10 | "request": "launch", 11 | "mode": "auto", 12 | "program": "${workspaceFolder}/cmd", 13 | "envFile": "${workspaceFolder}/.env" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.18.3-alpine3.16 AS builder 2 | 3 | RUN apk update && \ 4 | apk add --no-cache --update make bash git ca-certificates && \ 5 | update-ca-certificates 6 | 7 | WORKDIR /go/src/echoperator 8 | 9 | COPY . . 10 | 11 | RUN make build 12 | 13 | FROM alpine:3.16.0 14 | 15 | COPY --from=builder /go/src/echoperator/bin/echoperator /echoperator 16 | 17 | CMD [ "/echoperator" ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Martín Montes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ROOT := $(shell git rev-parse --show-toplevel) 2 | OS := $(shell uname -s | awk '{print tolower($$0)}') 3 | ARCH := amd64 4 | PROJECT := echoperator 5 | VERSION := $(shell git describe --abbrev=0 --tags) 6 | LD_FLAGS := -X main.version=$(VERSION) -s -w 7 | SOURCE_FILES ?= ./internal/... ./pkg/... ./cmd/... 8 | 9 | export CGO_ENABLED := 0 10 | export GO111MODULE := on 11 | export GOBIN := $(shell pwd)/bin 12 | export KUBECONFIG ?= $(HOME)/.kube/config 13 | 14 | .PHONY: all 15 | all: help 16 | 17 | .PHONY: help 18 | help: ### Show targets documentation 19 | ifeq ($(OS), linux) 20 | @grep -P '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \ 21 | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' 22 | else 23 | @awk -F ':.*###' '$$0 ~ FS {printf "%15s%s\n", $$1 ":", $$2}' \ 24 | $(MAKEFILE_LIST) | grep -v '@awk' | sort 25 | endif 26 | 27 | KIND := $(GOBIN)/kind 28 | KIND_VERSION := v0.14.0 29 | kind: 30 | $(call go-install,sigs.k8s.io/kind@$(KIND_VERSION)) 31 | 32 | GOLANGCI_LINT := $(GOBIN)/golangci-lint 33 | GOLANGCI_LINT_VERSION := v1.46.2 34 | golangci-lint: 35 | $(call go-install,github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)) 36 | 37 | GORELEASER := $(GOBIN)/goreleaser 38 | GORELEASER_VERSION := v1.9.2 39 | goreleaser: 40 | $(call go-install,github.com/goreleaser/goreleaser@$(GORELEASER_VERSION)) 41 | 42 | MOCKERY := $(GOBIN)/mockery 43 | MOCKERY_VERSION := v2.12.3 44 | mockery: 45 | $(call go-install,github.com/vektra/mockery/v2@$(MOCKERY_VERSION)) 46 | 47 | .PHONY: generate 48 | generate: vendor ### Generate code 49 | @bash ./hack/hack.sh 50 | 51 | .PHONY: install-crds 52 | install-crds: ## Install CRDs 53 | @kubectl apply -f manifests/crds 54 | 55 | .PHONY: cluster 56 | cluster: kind ### Create a KIND cluster 57 | $(KIND) create cluster --name $(PROJECT) 58 | 59 | clean: ### Clean build files 60 | @rm -rf ./bin 61 | @go clean 62 | 63 | .PHONY: build 64 | build: clean ### Build binary 65 | @go build -tags netgo -a -v -ldflags "${LD_FLAGS}" -o ./bin/echoperator ./cmd/echoperator/*.go 66 | @chmod +x ./bin/* 67 | 68 | .PHONY: run 69 | run: lint install-crds ### Quick run 70 | @CGO_ENABLED=1 go run -race cmd/echoperator/*.go 71 | 72 | .PHONY: deps 73 | deps: ### Optimize dependencies 74 | @go mod tidy 75 | 76 | .PHONY: vendor 77 | vendor: ### Vendor dependencies 78 | @go mod vendor 79 | 80 | .PHONY: lint 81 | lint: golangci-lint ### Lint 82 | $(GOLANGCI_LINT) run 83 | 84 | .PHONY: release 85 | release: goreleaser ### Dry-run release 86 | $(GORELEASER) release --snapshot --rm-dist 87 | 88 | .PHONY: test-clean 89 | test-clean: ### Clean test cache 90 | @go clean -testcache ./... 91 | 92 | .PHONY: test 93 | test: ### Run tests 94 | @go test -v -coverprofile=cover.out -timeout 10s ./... 95 | 96 | .PHONY: cover 97 | cover: test ### Run tests and generate coverage 98 | @go tool cover -html=cover.out -o=cover.html 99 | 100 | .PHONY: mocks 101 | mocks: mockery ### Generate mocks 102 | $(MOCKERY) --all --dir internal --output internal/mocks 103 | 104 | # go-get-tool will 'go get' any package $2 and install it to $1. 105 | PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) 106 | define go-install 107 | @[ -f $(1) ] || { \ 108 | go install $(1) ; \ 109 | } 110 | endef 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🤖 echoperator 2 | 3 | [![CI](https://github.com/mmontes11/echoperator/actions/workflows/ci.yml/badge.svg)](https://github.com/mmontes11/echoperator/actions/workflows/ci.yml) 4 | [![Release](https://github.com/mmontes11/echoperator/actions/workflows/release.yml/badge.svg)](https://github.com/mmontes11/echoperator/actions/workflows/release.yml) 5 | [![Go Report Card](https://goreportcard.com/badge/github.com/mmontes11/echoperator)](https://goreportcard.com/report/github.com/mmontes11/echoperator) 6 | [![Go Reference](https://pkg.go.dev/badge/github.com/mmontes11/echoperator.svg)](https://pkg.go.dev/github.com/mmontes11/echoperator) 7 | [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/echoperator)](https://artifacthub.io/packages/helm/mmontes/echoperator) 8 | [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT) 9 | 10 | Simple Kubernetes operator built from scratch with [client-go](https://github.com/kubernetes/client-go). 11 | 12 | [Kubernetes operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) implementation using the [client-go](https://github.com/kubernetes/client-go) library. Altough there are a bunch of frameworks for doing this ([kubebuilder](https://book.kubebuilder.io/), [operator framework](https://operatorframework.io/) ...), this example operator uses the tools provided by [client-go](https://github.com/kubernetes/client-go) for simplicity and flexibility reasons. 13 | 14 | [Medium article](https://betterprogramming.pub/building-a-highly-available-kubernetes-operator-using-golang-fe4a44c395c2) that explains how to build this operator step by step. 15 | 16 | ### Features 17 | 18 | - Simple example to understand how a Kubernetes operator works. 19 | - Manages [Echo CRDs](https://github.com/mmontes11/charts/blob/main/charts/echoperator/crds/echo.yml) for executing an `echo` inside a pod. 20 | - Manages [ScheduledEcho CRDs](https://github.com/mmontes11/charts/blob/main/charts/echoperator/crds/scheduledecho.yml) for scheduling the execution of an `echo` inside a pod. 21 | - High Availability operator using Kubernetes [lease](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#lease-v1-coordination-k8s-io) objects. 22 | - Prometheus metrics. 23 | - [Helm chart](https://github.com/mmontes11/charts/tree/main/charts/echoperator). 24 | 25 | 26 | ### Versioning 27 | 28 | |Echo|ScheduledEcho|Job|CronJob|Lease|Kubernetes| 29 | |----|-------------|---|-------|-----|----------| 30 | |v1alpha1|v1alpha1|v1|v1|v1|v1.21.x| 31 | 32 | ### Installation 33 | 34 | ```bash 35 | helm repo add mmontes https://mmontes11.github.io/charts 36 | helm install echoperator mmontes/echoperator 37 | ``` 38 | 39 | ### Custom Resource Definitions (CRDs) 40 | 41 | The helm chart installs automatically the [Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) needed for this operator to work. However, if you wanted to install them manually, you can find them in the [helm chart repo](https://github.com/mmontes11/charts/tree/main/charts/echoperator/crds). 42 | 43 | ### Example use cases 44 | 45 | ###### Hello world 46 | 47 | - Client creates a [hello world Echo CRD](./manifests/examples/hello-world.yml). 48 | - Operator receives a `Echo` added event. 49 | - Operator reads the `message` property from the `Echo` and creates a `Job` resource. 50 | - The `Job` resource creates a `Pod` that performs a `echo` command with the `message` property. 51 | 52 | ###### Scheduled hello world 53 | 54 | - Client creates a [hello world ScheduledEcho CRD](./manifests/examples/hello-world-scheduled.yml). 55 | - Operator receives a `ScheduledEcho` added event. 56 | - Operator reads the `message` and `schedule` property from the `ScheduledEcho` and creates a `CronJob`. 57 | - The `CronJob` schedules a `Job` creation using the `schedule` property. 58 | - When scheduled, the `Job` resource creates a `Pod` that performs a `echo` command with the `message` property. 59 | -------------------------------------------------------------------------------- /cmd/echoperator/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | 10 | "github.com/gotway/gotway/pkg/log" 11 | "github.com/gotway/gotway/pkg/metrics" 12 | 13 | "github.com/mmontes11/echoperator/internal/config" 14 | "github.com/mmontes11/echoperator/internal/runner" 15 | "github.com/mmontes11/echoperator/pkg/controller" 16 | echov1alpha1clientset "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 17 | 18 | "k8s.io/client-go/kubernetes" 19 | "k8s.io/client-go/rest" 20 | "k8s.io/client-go/tools/clientcmd" 21 | ) 22 | 23 | func main() { 24 | config, err := config.GetConfig() 25 | if err != nil { 26 | panic(fmt.Errorf("error getting config %v", err)) 27 | } 28 | logger := getLogger(config) 29 | logger.Debugf("config %v", config) 30 | 31 | var restConfig *rest.Config 32 | var errKubeConfig error 33 | if config.KubeConfig != "" { 34 | restConfig, errKubeConfig = clientcmd.BuildConfigFromFlags("", config.KubeConfig) 35 | } else { 36 | restConfig, errKubeConfig = rest.InClusterConfig() 37 | } 38 | if errKubeConfig != nil { 39 | logger.Fatal("error getting kubernetes config ", err) 40 | } 41 | 42 | kubeClientSet, err := kubernetes.NewForConfig(restConfig) 43 | if err != nil { 44 | logger.Fatal("error getting kubernetes client ", err) 45 | } 46 | echov1alpha1ClientSet, err := echov1alpha1clientset.NewForConfig(restConfig) 47 | if err != nil { 48 | logger.Fatal("error creating echo client ", err) 49 | } 50 | 51 | ctrl := controller.New( 52 | kubeClientSet, 53 | echov1alpha1ClientSet, 54 | config.Namespace, 55 | logger.WithField("type", "controller"), 56 | ) 57 | 58 | ctx, cancel := signal.NotifyContext(context.Background(), []os.Signal{ 59 | os.Interrupt, 60 | syscall.SIGINT, 61 | syscall.SIGTERM, 62 | syscall.SIGKILL, 63 | syscall.SIGHUP, 64 | syscall.SIGQUIT, 65 | }...) 66 | defer cancel() 67 | 68 | if config.Metrics.Enabled { 69 | m := metrics.New( 70 | metrics.Options{ 71 | Path: config.Metrics.Path, 72 | Port: config.Metrics.Port, 73 | }, 74 | logger.WithField("type", "metrics"), 75 | ) 76 | go m.Start() 77 | defer m.Stop() 78 | } 79 | 80 | r := runner.NewRunner( 81 | ctrl, 82 | kubeClientSet, 83 | config, 84 | logger.WithField("type", "runner"), 85 | ) 86 | r.Start(ctx) 87 | } 88 | 89 | func getLogger(config config.Config) log.Logger { 90 | logger := log.NewLogger(log.Fields{ 91 | "service": "echoperator", 92 | }, config.Env, config.LogLevel, os.Stdout) 93 | if config.HA.Enabled { 94 | return logger.WithField("node", config.HA.NodeId) 95 | } 96 | return logger 97 | } 98 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mmontes11/echoperator 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gotway/gotway v0.0.11 7 | k8s.io/api v0.21.2 8 | k8s.io/apimachinery v0.21.2 9 | k8s.io/client-go v0.21.2 10 | k8s.io/code-generator v0.21.2 11 | ) 12 | 13 | require ( 14 | github.com/PuerkitoBio/purell v1.1.1 // indirect 15 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 16 | github.com/beorn7/perks v1.0.1 // indirect 17 | github.com/cespare/xxhash/v2 v2.1.1 // indirect 18 | github.com/davecgh/go-spew v1.1.1 // indirect 19 | github.com/emicklei/go-restful v2.9.5+incompatible // indirect 20 | github.com/evanphx/json-patch v4.9.0+incompatible // indirect 21 | github.com/go-logr/logr v0.4.0 // indirect 22 | github.com/go-openapi/jsonpointer v0.19.3 // indirect 23 | github.com/go-openapi/jsonreference v0.19.3 // indirect 24 | github.com/go-openapi/spec v0.19.5 // indirect 25 | github.com/go-openapi/swag v0.19.5 // indirect 26 | github.com/gogo/protobuf v1.3.2 // indirect 27 | github.com/golang/protobuf v1.4.3 // indirect 28 | github.com/google/go-cmp v0.5.6 // indirect 29 | github.com/google/gofuzz v1.1.0 // indirect 30 | github.com/googleapis/gnostic v0.4.1 // indirect 31 | github.com/hashicorp/golang-lru v0.5.1 // indirect 32 | github.com/imdario/mergo v0.3.5 // indirect 33 | github.com/json-iterator/go v1.1.11 // indirect 34 | github.com/mailru/easyjson v0.7.0 // indirect 35 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect 36 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 37 | github.com/modern-go/reflect2 v1.0.1 // indirect 38 | github.com/pkg/errors v0.9.1 // indirect 39 | github.com/prometheus/client_golang v1.11.0 // indirect 40 | github.com/prometheus/client_model v0.2.0 // indirect 41 | github.com/prometheus/common v0.26.0 // indirect 42 | github.com/prometheus/procfs v0.6.0 // indirect 43 | github.com/sirupsen/logrus v1.8.1 // indirect 44 | github.com/spf13/pflag v1.0.5 // indirect 45 | golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 // indirect 46 | golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 // indirect 47 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect 48 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect 49 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect 50 | golang.org/x/text v0.3.4 // indirect 51 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect 52 | golang.org/x/tools v0.1.0 // indirect 53 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 54 | google.golang.org/appengine v1.6.5 // indirect 55 | google.golang.org/protobuf v1.26.0-rc.1 // indirect 56 | gopkg.in/inf.v0 v0.9.1 // indirect 57 | gopkg.in/yaml.v2 v2.4.0 // indirect 58 | k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 // indirect 59 | k8s.io/klog/v2 v2.8.0 // indirect 60 | k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 // indirect 61 | k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect 62 | sigs.k8s.io/structured-merge-diff/v4 v4.1.0 // indirect 63 | sigs.k8s.io/yaml v1.2.0 // indirect 64 | ) 65 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 13 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 14 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 15 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 16 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 17 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 18 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 19 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 20 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 21 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 22 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 23 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 24 | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= 25 | github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= 26 | github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= 27 | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= 28 | github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= 29 | github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= 30 | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 31 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 32 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 33 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 34 | github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= 35 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 36 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= 37 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 38 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 39 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 40 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 41 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 42 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 43 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 44 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 45 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 46 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 47 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 48 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 49 | github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= 50 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 51 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 52 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 53 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 54 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 55 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 56 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 57 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 58 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 59 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 60 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 61 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 62 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 63 | github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= 64 | github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 65 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 66 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 67 | github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= 68 | github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 69 | github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 70 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 71 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= 72 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 73 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 74 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 75 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 76 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 77 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 78 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 79 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 80 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 81 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 82 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 83 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 84 | github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= 85 | github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 86 | github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= 87 | github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= 88 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 89 | github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= 90 | github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= 91 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= 92 | github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= 93 | github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= 94 | github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= 95 | github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 96 | github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= 97 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 98 | github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= 99 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 100 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 101 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 102 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 103 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 104 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 105 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 106 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= 107 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 108 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 109 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 110 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 111 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 112 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 113 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 114 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 115 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 116 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 117 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 118 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 119 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 120 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 121 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 122 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 123 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 124 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 125 | github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= 126 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 127 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 128 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 129 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 130 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 131 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 132 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 133 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 134 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 135 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 136 | github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 137 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 138 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 139 | github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= 140 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 141 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 142 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 143 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 144 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 145 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 146 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 147 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 148 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 149 | github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= 150 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 151 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 152 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 153 | github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= 154 | github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 155 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 156 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 157 | github.com/gotway/gotway v0.0.11 h1:T0nk2d4muOQNlDkT0XRUYcVUmWk2n1wRbbCURtey/+g= 158 | github.com/gotway/gotway v0.0.11/go.mod h1:1bTrDVleeFV9Oe7o1/UTIzAL0SGyhUIp5vACd7xZ/IY= 159 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 160 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 161 | github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= 162 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 163 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 164 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 165 | github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= 166 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 167 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 168 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 169 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 170 | github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= 171 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 172 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 173 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 174 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 175 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 176 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 177 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 178 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 179 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 180 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 181 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 182 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 183 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 184 | github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= 185 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 186 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 187 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 188 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 189 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 190 | github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= 191 | github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= 192 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 193 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 194 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 195 | github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= 196 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 197 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 198 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 199 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 200 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 201 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 202 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 203 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 204 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 205 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= 206 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 207 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 208 | github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= 209 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 210 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 211 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 212 | github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 213 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 214 | github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= 215 | github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= 216 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 217 | github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 218 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 219 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 220 | github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= 221 | github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= 222 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 223 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 224 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 225 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 226 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 227 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 228 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 229 | github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= 230 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 231 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 232 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 233 | github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= 234 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 235 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 236 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 237 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 238 | github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= 239 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 240 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 241 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 242 | github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= 243 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= 244 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 245 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 246 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= 247 | github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= 248 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 249 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 250 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 251 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 252 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 253 | github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= 254 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 255 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 256 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 257 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 258 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 259 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 260 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 261 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 262 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 263 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 264 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 265 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 266 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 267 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 268 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 269 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 270 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 271 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 272 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 273 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 274 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 275 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 276 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 277 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 278 | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 279 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 280 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 281 | golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 282 | golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 283 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 284 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 285 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 286 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 287 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 288 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 289 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 290 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 291 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 292 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 293 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 294 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 295 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 296 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 297 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 298 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 299 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 300 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 301 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 302 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 303 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 304 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 305 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 306 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 307 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 308 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 309 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 310 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 311 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 312 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 313 | golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= 314 | golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 315 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 316 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 317 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 318 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 319 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 320 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 321 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 322 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 323 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 324 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 325 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 326 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 327 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 328 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 329 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 330 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 331 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 332 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 333 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 334 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 335 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 336 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 337 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 338 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 339 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 340 | golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 341 | golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM= 342 | golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 343 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 344 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 345 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 346 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 347 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= 348 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 349 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 350 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 351 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 352 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 353 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 354 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 355 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 356 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 357 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 358 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 359 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 360 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 361 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 362 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 363 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 364 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 365 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 366 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 367 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 368 | golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 369 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 370 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 371 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 372 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 373 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 374 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 375 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 376 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 377 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 378 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 379 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 380 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 381 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 382 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 383 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 384 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 385 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 386 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 387 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 388 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 389 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 390 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 391 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 392 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 393 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 394 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= 395 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 396 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 397 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 398 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= 399 | golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 400 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 401 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 402 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 403 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 404 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 405 | golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= 406 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 407 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 408 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 409 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 410 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= 411 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 412 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 413 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 414 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 415 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 416 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 417 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 418 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 419 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 420 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 421 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 422 | golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 423 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 424 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 425 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 426 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 427 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 428 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 429 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 430 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 431 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 432 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 433 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 434 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 435 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 436 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 437 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 438 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 439 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 440 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 441 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 442 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 443 | golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 444 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 445 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 446 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 447 | golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= 448 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 449 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 450 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 451 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 452 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 453 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 454 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 455 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 456 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 457 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 458 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 459 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 460 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 461 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 462 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 463 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 464 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 465 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 466 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 467 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 468 | google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= 469 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 470 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 471 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 472 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 473 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 474 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 475 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 476 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 477 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 478 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 479 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 480 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 481 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 482 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 483 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 484 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 485 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 486 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 487 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 488 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 489 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 490 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 491 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 492 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 493 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 494 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 495 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 496 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 497 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 498 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 499 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 500 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 501 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 502 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 503 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 504 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 505 | google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= 506 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 507 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 508 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 509 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 510 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 511 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= 512 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 513 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 514 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 515 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 516 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 517 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 518 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 519 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 520 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 521 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 522 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 523 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 524 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 525 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 526 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 527 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 528 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 529 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 530 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 531 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 532 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 533 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 534 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 535 | k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y= 536 | k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= 537 | k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= 538 | k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= 539 | k8s.io/client-go v0.21.2 h1:Q1j4L/iMN4pTw6Y4DWppBoUxgKO8LbffEMVEV00MUp0= 540 | k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= 541 | k8s.io/code-generator v0.21.2 h1:EyHysEtLHTsNMoace0b3Yec9feD0qkV+5RZRoeSh+sc= 542 | k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= 543 | k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= 544 | k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw= 545 | k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 546 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 547 | k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= 548 | k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= 549 | k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= 550 | k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= 551 | k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= 552 | k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= 553 | k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 554 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 555 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 556 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 557 | sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 558 | sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= 559 | sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 560 | sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= 561 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= 562 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | -------------------------------------------------------------------------------- /hack/hack.go: -------------------------------------------------------------------------------- 1 | //go:build hack 2 | // +build hack 3 | 4 | /* 5 | MIT License 6 | 7 | Copyright (c) 2021 Martín Montes 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | package hack 29 | 30 | import _ "k8s.io/code-generator" 31 | -------------------------------------------------------------------------------- /hack/hack.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2021 Martín Montes 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | set -o errexit 26 | set -o nounset 27 | set -o pipefail 28 | 29 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 30 | HACK_PKG=${HACK_PKG:-$( 31 | cd "${SCRIPT_ROOT}" 32 | ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator 33 | )} 34 | GO_PKG="github.com/mmontes11/echoperator/pkg" 35 | 36 | bash "${HACK_PKG}"/generate-groups.sh "all" \ 37 | ${GO_PKG}/echo/v1alpha1/apis \ 38 | ${GO_PKG} \ 39 | echo:v1alpha1 \ 40 | --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt 41 | -------------------------------------------------------------------------------- /internal/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | 8 | "github.com/gotway/gotway/pkg/env" 9 | ) 10 | 11 | type HA struct { 12 | Enabled bool 13 | NodeId string 14 | LeaseLockName string 15 | LeaseDuration time.Duration 16 | RenewDeadline time.Duration 17 | RetryPeriod time.Duration 18 | } 19 | 20 | func (c HA) String() string { 21 | return fmt.Sprintf( 22 | "HA{Enabled='%v'NodeId='%s'LeaseLockName='%s'LeaseDuration='%v'RenewDeadline='%v'RetryPeriod='%v'}", 23 | c.Enabled, 24 | c.NodeId, 25 | c.LeaseLockName, 26 | c.LeaseDuration, 27 | c.RenewDeadline, 28 | c.RetryPeriod, 29 | ) 30 | } 31 | 32 | type Metrics struct { 33 | Enabled bool 34 | Path string 35 | Port string 36 | } 37 | 38 | func (m Metrics) String() string { 39 | return fmt.Sprintf( 40 | "Metrics{Enabled='%v'Path='%s'Port='%s'}", 41 | m.Enabled, 42 | m.Path, 43 | m.Port, 44 | ) 45 | } 46 | 47 | type Config struct { 48 | KubeConfig string 49 | Namespace string 50 | NumWorkers int 51 | HA HA 52 | Metrics Metrics 53 | Env string 54 | LogLevel string 55 | } 56 | 57 | func (c Config) String() string { 58 | return fmt.Sprintf( 59 | "Config{KubeConfig='%s'Namespace='%s'NumWorkers='%d'HA='%v'Metrics='%v'Env='%s'LogLevel='%s'}", 60 | c.KubeConfig, 61 | c.Namespace, 62 | c.NumWorkers, 63 | c.HA, 64 | c.Metrics, 65 | c.Env, 66 | c.LogLevel, 67 | ) 68 | } 69 | 70 | func GetConfig() (Config, error) { 71 | ha := env.GetBool("HA_ENABLED", false) 72 | 73 | var nodeId string 74 | if ha { 75 | nodeId = env.Get("HA_NODE_ID", "") 76 | if nodeId == "" { 77 | hostname, err := os.Hostname() 78 | if err != nil { 79 | return Config{}, fmt.Errorf("error getting node id %v", err) 80 | } 81 | nodeId = hostname 82 | } 83 | } 84 | 85 | return Config{ 86 | KubeConfig: env.Get("KUBECONFIG", ""), 87 | Namespace: env.Get("NAMESPACE", "default"), 88 | NumWorkers: env.GetInt("NUM_WORKERS", 4), 89 | HA: HA{ 90 | Enabled: ha, 91 | NodeId: nodeId, 92 | LeaseLockName: env.Get("HA_LEASE_LOCK_NAME", "echoperator"), 93 | LeaseDuration: env.GetDuration("HA_LEASE_DURATION_SECONDS", 15) * time.Second, 94 | RenewDeadline: env.GetDuration("HA_RENEW_DEADLINE_SECONDS", 10) * time.Second, 95 | RetryPeriod: env.GetDuration("HA_RETRY_PERIOD_SECONDS", 2) * time.Second, 96 | }, 97 | Metrics: Metrics{ 98 | Enabled: env.GetBool("METRICS_ENABLED", true), 99 | Path: env.Get("METRICS_PATH", "/metrics"), 100 | Port: env.Get("METRICS_PORT", "2112"), 101 | }, 102 | Env: env.Get("ENV", "local"), 103 | LogLevel: env.Get("LOG_LEVEL", "debug"), 104 | }, nil 105 | } 106 | -------------------------------------------------------------------------------- /internal/runner/runner.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/gotway/gotway/pkg/log" 7 | "github.com/mmontes11/echoperator/internal/config" 8 | "github.com/mmontes11/echoperator/pkg/controller" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/client-go/kubernetes" 11 | "k8s.io/client-go/tools/leaderelection" 12 | "k8s.io/client-go/tools/leaderelection/resourcelock" 13 | ) 14 | 15 | type Runner struct { 16 | ctrl *controller.Controller 17 | clientset *kubernetes.Clientset 18 | config config.Config 19 | logger log.Logger 20 | } 21 | 22 | func (r *Runner) Start(ctx context.Context) { 23 | if r.config.HA.Enabled { 24 | r.logger.Info("starting HA controller") 25 | r.runHA(ctx) 26 | } else { 27 | r.logger.Info("starting standalone controller") 28 | r.runSingleNode(ctx) 29 | } 30 | } 31 | 32 | func (r *Runner) runSingleNode(ctx context.Context) { 33 | if err := r.ctrl.Run(ctx, r.config.NumWorkers); err != nil { 34 | r.logger.Fatal("error running controller ", err) 35 | } 36 | } 37 | 38 | func (r *Runner) runHA(ctx context.Context) { 39 | if r.config.HA == (config.HA{}) || !r.config.HA.Enabled { 40 | r.logger.Fatal("HA config not set or not enabled") 41 | } 42 | 43 | lock := &resourcelock.LeaseLock{ 44 | LeaseMeta: metav1.ObjectMeta{ 45 | Name: r.config.HA.LeaseLockName, 46 | Namespace: r.config.Namespace, 47 | }, 48 | Client: r.clientset.CoordinationV1(), 49 | LockConfig: resourcelock.ResourceLockConfig{ 50 | Identity: r.config.HA.NodeId, 51 | }, 52 | } 53 | leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ 54 | Lock: lock, 55 | ReleaseOnCancel: true, 56 | LeaseDuration: r.config.HA.LeaseDuration, 57 | RenewDeadline: r.config.HA.RenewDeadline, 58 | RetryPeriod: r.config.HA.RetryPeriod, 59 | Callbacks: leaderelection.LeaderCallbacks{ 60 | OnStartedLeading: func(ctx context.Context) { 61 | r.logger.Info("start leading") 62 | r.runSingleNode(ctx) 63 | }, 64 | OnStoppedLeading: func() { 65 | r.logger.Info("stopped leading") 66 | }, 67 | OnNewLeader: func(identity string) { 68 | if identity == r.config.HA.NodeId { 69 | r.logger.Info("obtained leadership") 70 | return 71 | } 72 | r.logger.Infof("leader elected: '%s'", identity) 73 | }, 74 | }, 75 | }) 76 | } 77 | 78 | func NewRunner( 79 | ctrl *controller.Controller, 80 | clientset *kubernetes.Clientset, 81 | config config.Config, 82 | logger log.Logger, 83 | ) *Runner { 84 | return &Runner{ 85 | ctrl: ctrl, 86 | clientset: clientset, 87 | config: config, 88 | logger: logger, 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /manifests/crds/echo.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: echos.mmontes.io 5 | spec: 6 | group: mmontes.io 7 | names: 8 | kind: Echo 9 | listKind: EchoList 10 | plural: echos 11 | singular: echo 12 | shortNames: 13 | - ec 14 | scope: Namespaced 15 | versions: 16 | - name: v1alpha1 17 | served: true 18 | storage: true 19 | schema: 20 | openAPIV3Schema: 21 | type: object 22 | properties: 23 | spec: 24 | type: object 25 | properties: 26 | message: 27 | type: string 28 | required: 29 | - message 30 | -------------------------------------------------------------------------------- /manifests/crds/scheduledecho.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: scheduledechos.mmontes.io 5 | spec: 6 | group: mmontes.io 7 | names: 8 | kind: ScheduledEcho 9 | listKind: ScheduledEchoList 10 | plural: scheduledechos 11 | singular: scheduledecho 12 | shortNames: 13 | - sec 14 | scope: Namespaced 15 | versions: 16 | - name: v1alpha1 17 | served: true 18 | storage: true 19 | schema: 20 | openAPIV3Schema: 21 | type: object 22 | properties: 23 | spec: 24 | type: object 25 | properties: 26 | message: 27 | type: string 28 | schedule: 29 | type: string 30 | required: 31 | - message 32 | - schedule 33 | -------------------------------------------------------------------------------- /manifests/examples/hello-world-scheduled.yml: -------------------------------------------------------------------------------- 1 | apiVersion: mmontes.io/v1alpha1 2 | kind: ScheduledEcho 3 | metadata: 4 | name: hello-world-scheduled 5 | namespace: default 6 | spec: 7 | message: "Hola, 世界!" 8 | schedule: "*/1 * * * *" 9 | -------------------------------------------------------------------------------- /manifests/examples/hello-world.yml: -------------------------------------------------------------------------------- 1 | apiVersion: mmontes.io/v1alpha1 2 | kind: Echo 3 | metadata: 4 | name: hello-world 5 | namespace: default 6 | spec: 7 | message: "Hola, 世界!" 8 | -------------------------------------------------------------------------------- /pkg/controller/controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "time" 7 | 8 | "github.com/gotway/gotway/pkg/log" 9 | 10 | echov1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 11 | echov1alpha1clientset "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 12 | echoinformers "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions" 13 | 14 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 15 | "k8s.io/apimachinery/pkg/util/wait" 16 | kubeinformers "k8s.io/client-go/informers" 17 | "k8s.io/client-go/kubernetes" 18 | "k8s.io/client-go/tools/cache" 19 | "k8s.io/client-go/util/workqueue" 20 | ) 21 | 22 | type Controller struct { 23 | kubeClientSet kubernetes.Interface 24 | 25 | echoInformer cache.SharedIndexInformer 26 | jobInformer cache.SharedIndexInformer 27 | scheduledEchoInformer cache.SharedIndexInformer 28 | cronjobInformer cache.SharedIndexInformer 29 | 30 | queue workqueue.RateLimitingInterface 31 | 32 | namespace string 33 | 34 | logger log.Logger 35 | } 36 | 37 | func (c *Controller) Run(ctx context.Context, numWorkers int) error { 38 | defer utilruntime.HandleCrash() 39 | defer c.queue.ShutDown() 40 | 41 | c.logger.Info("starting controller") 42 | 43 | c.logger.Info("starting informers") 44 | for _, i := range []cache.SharedIndexInformer{ 45 | c.echoInformer, 46 | c.scheduledEchoInformer, 47 | c.jobInformer, 48 | c.cronjobInformer, 49 | } { 50 | go i.Run(ctx.Done()) 51 | } 52 | 53 | c.logger.Info("waiting for informer caches to sync") 54 | if !cache.WaitForCacheSync(ctx.Done(), []cache.InformerSynced{ 55 | c.echoInformer.HasSynced, 56 | c.scheduledEchoInformer.HasSynced, 57 | c.jobInformer.HasSynced, 58 | c.cronjobInformer.HasSynced, 59 | }...) { 60 | err := errors.New("failed to wait for informers caches to sync") 61 | utilruntime.HandleError(err) 62 | return err 63 | } 64 | 65 | c.logger.Infof("starting %d workers", numWorkers) 66 | for i := 0; i < numWorkers; i++ { 67 | go wait.Until(func() { 68 | c.runWorker(ctx) 69 | }, time.Second, ctx.Done()) 70 | } 71 | c.logger.Info("controller ready") 72 | 73 | <-ctx.Done() 74 | c.logger.Info("stopping controller") 75 | 76 | return nil 77 | } 78 | 79 | func (c *Controller) addEcho(obj interface{}) { 80 | c.logger.Debug("adding echo") 81 | echo, ok := obj.(*echov1alpha1.Echo) 82 | if !ok { 83 | c.logger.Errorf("unexpected object %v", obj) 84 | return 85 | } 86 | c.queue.Add(event{ 87 | eventType: addEcho, 88 | newObj: echo.DeepCopy(), 89 | }) 90 | } 91 | 92 | func (c *Controller) addScheduledEcho(obj interface{}) { 93 | c.logger.Debug("adding scheduled echo") 94 | scheduledEcho, ok := obj.(*echov1alpha1.ScheduledEcho) 95 | if !ok { 96 | c.logger.Errorf("unexpected object %v", obj) 97 | return 98 | } 99 | c.queue.Add(event{ 100 | eventType: addScheduledEcho, 101 | newObj: scheduledEcho.DeepCopy(), 102 | }) 103 | } 104 | 105 | func (c *Controller) updateScheduledEcho(oldObj, newObj interface{}) { 106 | c.logger.Debug("updating scheduled echo") 107 | oldScheduledEcho, ok := oldObj.(*echov1alpha1.ScheduledEcho) 108 | if !ok { 109 | c.logger.Errorf("unexpected new object %v", newObj) 110 | return 111 | } 112 | scheduledEcho, ok := newObj.(*echov1alpha1.ScheduledEcho) 113 | if !ok { 114 | c.logger.Errorf("unexpected new object %v", newObj) 115 | return 116 | } 117 | c.queue.Add(event{ 118 | eventType: updateScheduledEcho, 119 | oldObj: oldScheduledEcho.DeepCopy(), 120 | newObj: scheduledEcho.DeepCopy(), 121 | }) 122 | } 123 | 124 | func New( 125 | kubeClientSet kubernetes.Interface, 126 | echoClientSet echov1alpha1clientset.Interface, 127 | namespace string, 128 | logger log.Logger, 129 | ) *Controller { 130 | 131 | echoInformerFactory := echoinformers.NewSharedInformerFactory( 132 | echoClientSet, 133 | 10*time.Second, 134 | ) 135 | echoInformer := echoInformerFactory.Mmontes().V1alpha1().Echos().Informer() 136 | scheduledechoInformer := echoInformerFactory.Mmontes().V1alpha1().ScheduledEchos().Informer() 137 | 138 | kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClientSet, 10*time.Second) 139 | jobInformer := kubeInformerFactory.Batch().V1().Jobs().Informer() 140 | cronjobInformer := kubeInformerFactory.Batch().V1().CronJobs().Informer() 141 | 142 | queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) 143 | 144 | ctrl := &Controller{ 145 | kubeClientSet: kubeClientSet, 146 | 147 | echoInformer: echoInformer, 148 | jobInformer: jobInformer, 149 | scheduledEchoInformer: scheduledechoInformer, 150 | cronjobInformer: cronjobInformer, 151 | 152 | queue: queue, 153 | 154 | namespace: namespace, 155 | 156 | logger: logger, 157 | } 158 | 159 | echoInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ 160 | AddFunc: ctrl.addEcho, 161 | }) 162 | scheduledechoInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ 163 | AddFunc: ctrl.addScheduledEcho, 164 | UpdateFunc: ctrl.updateScheduledEcho, 165 | }) 166 | 167 | return ctrl 168 | } 169 | -------------------------------------------------------------------------------- /pkg/controller/event.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | type eventType string 4 | 5 | const ( 6 | addEcho eventType = "addEcho" 7 | addScheduledEcho eventType = "addScheduledEcho" 8 | updateScheduledEcho eventType = "updateScheduledEcho" 9 | ) 10 | 11 | type event struct { 12 | eventType eventType 13 | oldObj, newObj interface{} 14 | } 15 | -------------------------------------------------------------------------------- /pkg/controller/resource.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | echo "github.com/mmontes11/echoperator/pkg/echo" 5 | echov1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 6 | batchv1 "k8s.io/api/batch/v1" 7 | corev1 "k8s.io/api/core/v1" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | ) 10 | 11 | func createJob(newEcho *echov1alpha1.Echo, namespace string) *batchv1.Job { 12 | return &batchv1.Job{ 13 | ObjectMeta: metav1.ObjectMeta{ 14 | Name: newEcho.ObjectMeta.Name, 15 | Namespace: namespace, 16 | Labels: make(map[string]string), 17 | OwnerReferences: []metav1.OwnerReference{ 18 | *metav1.NewControllerRef( 19 | newEcho, 20 | echov1alpha1.SchemeGroupVersion.WithKind(echo.EchoKind), 21 | ), 22 | }, 23 | }, 24 | Spec: createJobSpec(newEcho.Name, namespace, newEcho.Spec.Message), 25 | } 26 | } 27 | 28 | func createCronJob( 29 | newScheduledEcho *echov1alpha1.ScheduledEcho, 30 | namespace string, 31 | ) *batchv1.CronJob { 32 | return &batchv1.CronJob{ 33 | ObjectMeta: metav1.ObjectMeta{ 34 | Name: newScheduledEcho.ObjectMeta.Name, 35 | Namespace: namespace, 36 | Labels: make(map[string]string), 37 | OwnerReferences: []metav1.OwnerReference{ 38 | *metav1.NewControllerRef( 39 | newScheduledEcho, 40 | echov1alpha1.SchemeGroupVersion.WithKind(echo.ScheduledEchoKind), 41 | ), 42 | }, 43 | }, 44 | Spec: batchv1.CronJobSpec{ 45 | Schedule: newScheduledEcho.Spec.Schedule, 46 | ConcurrencyPolicy: batchv1.ForbidConcurrent, 47 | JobTemplate: batchv1.JobTemplateSpec{ 48 | ObjectMeta: metav1.ObjectMeta{ 49 | GenerateName: newScheduledEcho.Name + "-", 50 | Namespace: namespace, 51 | Labels: make(map[string]string), 52 | }, 53 | Spec: createJobSpec( 54 | newScheduledEcho.Name, 55 | namespace, 56 | newScheduledEcho.Spec.Message, 57 | ), 58 | }, 59 | }, 60 | } 61 | } 62 | 63 | func createJobSpec(name, namespace, msg string) batchv1.JobSpec { 64 | return batchv1.JobSpec{ 65 | Template: corev1.PodTemplateSpec{ 66 | ObjectMeta: metav1.ObjectMeta{ 67 | GenerateName: name + "-", 68 | Namespace: namespace, 69 | Labels: make(map[string]string), 70 | }, 71 | Spec: corev1.PodSpec{ 72 | Containers: []corev1.Container{ 73 | { 74 | Name: name, 75 | Image: "busybox:1.33.1", 76 | Command: []string{"echo", msg}, 77 | ImagePullPolicy: "IfNotPresent", 78 | }, 79 | }, 80 | RestartPolicy: corev1.RestartPolicyNever, 81 | }, 82 | }, 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /pkg/controller/worker.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | echov1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 8 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 9 | "k8s.io/client-go/tools/cache" 10 | 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | ) 13 | 14 | const maxRetries = 3 15 | 16 | func (c *Controller) runWorker(ctx context.Context) { 17 | for c.processNextItem(ctx) { 18 | } 19 | } 20 | 21 | func (c *Controller) processNextItem(ctx context.Context) bool { 22 | obj, shutdown := c.queue.Get() 23 | if shutdown { 24 | return false 25 | } 26 | defer c.queue.Done(obj) 27 | 28 | err := c.processEvent(ctx, obj) 29 | if err == nil { 30 | c.logger.Debug("processed item") 31 | c.queue.Forget(obj) 32 | } else if c.queue.NumRequeues(obj) < maxRetries { 33 | c.logger.Errorf("error processing event: %v, retrying", err) 34 | c.queue.AddRateLimited(obj) 35 | } else { 36 | c.logger.Errorf("error processing event: %v, max retries reached", err) 37 | c.queue.Forget(obj) 38 | utilruntime.HandleError(err) 39 | } 40 | 41 | return true 42 | } 43 | 44 | func (c *Controller) processEvent(ctx context.Context, obj interface{}) error { 45 | event, ok := obj.(event) 46 | if !ok { 47 | c.logger.Error("unexpected event ", obj) 48 | return nil 49 | } 50 | switch event.eventType { 51 | case addEcho: 52 | return c.processAddEcho(ctx, event.newObj.(*echov1alpha1.Echo)) 53 | case addScheduledEcho: 54 | return c.processAddScheduledEcho(ctx, event.newObj.(*echov1alpha1.ScheduledEcho)) 55 | case updateScheduledEcho: 56 | return c.processUpdateScheduledEcho( 57 | ctx, 58 | event.oldObj.(*echov1alpha1.ScheduledEcho), 59 | event.newObj.(*echov1alpha1.ScheduledEcho), 60 | ) 61 | } 62 | return nil 63 | } 64 | 65 | func (c *Controller) processAddEcho(ctx context.Context, echo *echov1alpha1.Echo) error { 66 | job := createJob(echo, c.namespace) 67 | exists, err := resourceExists(job, c.jobInformer.GetIndexer()) 68 | if err != nil { 69 | return fmt.Errorf("error checking job existence %v", err) 70 | } 71 | if exists { 72 | c.logger.Debug("job already exists, skipping") 73 | return nil 74 | } 75 | 76 | _, err = c.kubeClientSet.BatchV1(). 77 | Jobs(c.namespace). 78 | Create(ctx, job, metav1.CreateOptions{}) 79 | return err 80 | } 81 | 82 | func (c *Controller) processAddScheduledEcho( 83 | ctx context.Context, 84 | scheduledEcho *echov1alpha1.ScheduledEcho, 85 | ) error { 86 | cronjob := createCronJob(scheduledEcho, c.namespace) 87 | exists, err := resourceExists(cronjob, c.cronjobInformer.GetIndexer()) 88 | if err != nil { 89 | return fmt.Errorf("error checking cronjobjob existence %v", err) 90 | } 91 | if exists { 92 | c.logger.Debug("cronjob already exists, skipping") 93 | return nil 94 | } 95 | 96 | _, err = c.kubeClientSet.BatchV1(). 97 | CronJobs(c.namespace). 98 | Create(ctx, cronjob, metav1.CreateOptions{}) 99 | return err 100 | } 101 | 102 | func (c *Controller) processUpdateScheduledEcho( 103 | ctx context.Context, 104 | oldScheduledEcho, newScheduledEcho *echov1alpha1.ScheduledEcho, 105 | ) error { 106 | if !oldScheduledEcho.HasChanged(newScheduledEcho) { 107 | c.logger.Debug("scheduled echo has not changed, skipping") 108 | return nil 109 | } 110 | cronjob := createCronJob(newScheduledEcho, c.namespace) 111 | 112 | _, err := c.kubeClientSet.BatchV1(). 113 | CronJobs(c.namespace). 114 | Update(ctx, cronjob, metav1.UpdateOptions{}) 115 | return err 116 | } 117 | 118 | func resourceExists(obj interface{}, indexer cache.Indexer) (bool, error) { 119 | key, err := cache.MetaNamespaceKeyFunc(obj) 120 | if err != nil { 121 | return false, fmt.Errorf("error getting key %v", err) 122 | } 123 | _, exists, err := indexer.GetByKey(key) 124 | return exists, err 125 | } 126 | -------------------------------------------------------------------------------- /pkg/echo/echo.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | package echo 26 | 27 | const ( 28 | GroupName = "mmontes.io" 29 | 30 | V1alpha1 = "v1alpha1" 31 | 32 | EchoKind string = "Echo" 33 | ScheduledEchoKind string = "ScheduledEcho" 34 | ) 35 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/clientset.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package versioned 28 | 29 | import ( 30 | "fmt" 31 | 32 | mmontesv1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1" 33 | discovery "k8s.io/client-go/discovery" 34 | rest "k8s.io/client-go/rest" 35 | flowcontrol "k8s.io/client-go/util/flowcontrol" 36 | ) 37 | 38 | type Interface interface { 39 | Discovery() discovery.DiscoveryInterface 40 | MmontesV1alpha1() mmontesv1alpha1.MmontesV1alpha1Interface 41 | } 42 | 43 | // Clientset contains the clients for groups. Each group has exactly one 44 | // version included in a Clientset. 45 | type Clientset struct { 46 | *discovery.DiscoveryClient 47 | mmontesV1alpha1 *mmontesv1alpha1.MmontesV1alpha1Client 48 | } 49 | 50 | // MmontesV1alpha1 retrieves the MmontesV1alpha1Client 51 | func (c *Clientset) MmontesV1alpha1() mmontesv1alpha1.MmontesV1alpha1Interface { 52 | return c.mmontesV1alpha1 53 | } 54 | 55 | // Discovery retrieves the DiscoveryClient 56 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 57 | if c == nil { 58 | return nil 59 | } 60 | return c.DiscoveryClient 61 | } 62 | 63 | // NewForConfig creates a new Clientset for the given config. 64 | // If config's RateLimiter is not set and QPS and Burst are acceptable, 65 | // NewForConfig will generate a rate-limiter in configShallowCopy. 66 | func NewForConfig(c *rest.Config) (*Clientset, error) { 67 | configShallowCopy := *c 68 | if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { 69 | if configShallowCopy.Burst <= 0 { 70 | return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") 71 | } 72 | configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) 73 | } 74 | var cs Clientset 75 | var err error 76 | cs.mmontesV1alpha1, err = mmontesv1alpha1.NewForConfig(&configShallowCopy) 77 | if err != nil { 78 | return nil, err 79 | } 80 | 81 | cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return &cs, nil 86 | } 87 | 88 | // NewForConfigOrDie creates a new Clientset for the given config and 89 | // panics if there is an error in the config. 90 | func NewForConfigOrDie(c *rest.Config) *Clientset { 91 | var cs Clientset 92 | cs.mmontesV1alpha1 = mmontesv1alpha1.NewForConfigOrDie(c) 93 | 94 | cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) 95 | return &cs 96 | } 97 | 98 | // New creates a new Clientset for the given RESTClient. 99 | func New(c rest.Interface) *Clientset { 100 | var cs Clientset 101 | cs.mmontesV1alpha1 = mmontesv1alpha1.New(c) 102 | 103 | cs.DiscoveryClient = discovery.NewDiscoveryClient(c) 104 | return &cs 105 | } 106 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | // This package has the automatically generated clientset. 28 | package versioned 29 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/fake/clientset_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package fake 28 | 29 | import ( 30 | clientset "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 31 | mmontesv1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1" 32 | fakemmontesv1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/fake" 33 | "k8s.io/apimachinery/pkg/runtime" 34 | "k8s.io/apimachinery/pkg/watch" 35 | "k8s.io/client-go/discovery" 36 | fakediscovery "k8s.io/client-go/discovery/fake" 37 | "k8s.io/client-go/testing" 38 | ) 39 | 40 | // NewSimpleClientset returns a clientset that will respond with the provided objects. 41 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, 42 | // without applying any validations and/or defaults. It shouldn't be considered a replacement 43 | // for a real clientset and is mostly useful in simple unit tests. 44 | func NewSimpleClientset(objects ...runtime.Object) *Clientset { 45 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) 46 | for _, obj := range objects { 47 | if err := o.Add(obj); err != nil { 48 | panic(err) 49 | } 50 | } 51 | 52 | cs := &Clientset{tracker: o} 53 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} 54 | cs.AddReactor("*", "*", testing.ObjectReaction(o)) 55 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { 56 | gvr := action.GetResource() 57 | ns := action.GetNamespace() 58 | watch, err := o.Watch(gvr, ns) 59 | if err != nil { 60 | return false, nil, err 61 | } 62 | return true, watch, nil 63 | }) 64 | 65 | return cs 66 | } 67 | 68 | // Clientset implements clientset.Interface. Meant to be embedded into a 69 | // struct to get a default implementation. This makes faking out just the method 70 | // you want to test easier. 71 | type Clientset struct { 72 | testing.Fake 73 | discovery *fakediscovery.FakeDiscovery 74 | tracker testing.ObjectTracker 75 | } 76 | 77 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 78 | return c.discovery 79 | } 80 | 81 | func (c *Clientset) Tracker() testing.ObjectTracker { 82 | return c.tracker 83 | } 84 | 85 | var _ clientset.Interface = &Clientset{} 86 | 87 | // MmontesV1alpha1 retrieves the MmontesV1alpha1Client 88 | func (c *Clientset) MmontesV1alpha1() mmontesv1alpha1.MmontesV1alpha1Interface { 89 | return &fakemmontesv1alpha1.FakeMmontesV1alpha1{Fake: &c.Fake} 90 | } 91 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | // This package has the automatically generated fake clientset. 28 | package fake 29 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package fake 28 | 29 | import ( 30 | mmontesv1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 31 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 | runtime "k8s.io/apimachinery/pkg/runtime" 33 | schema "k8s.io/apimachinery/pkg/runtime/schema" 34 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 35 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 36 | ) 37 | 38 | var scheme = runtime.NewScheme() 39 | var codecs = serializer.NewCodecFactory(scheme) 40 | 41 | var localSchemeBuilder = runtime.SchemeBuilder{ 42 | mmontesv1alpha1.AddToScheme, 43 | } 44 | 45 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 46 | // of clientsets, like in: 47 | // 48 | // import ( 49 | // "k8s.io/client-go/kubernetes" 50 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 51 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 52 | // ) 53 | // 54 | // kclientset, _ := kubernetes.NewForConfig(c) 55 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 56 | // 57 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 58 | // correctly. 59 | var AddToScheme = localSchemeBuilder.AddToScheme 60 | 61 | func init() { 62 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 63 | utilruntime.Must(AddToScheme(scheme)) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | // This package contains the scheme of the automatically generated clientset. 28 | package scheme 29 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package scheme 28 | 29 | import ( 30 | mmontesv1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 31 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 | runtime "k8s.io/apimachinery/pkg/runtime" 33 | schema "k8s.io/apimachinery/pkg/runtime/schema" 34 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 35 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 36 | ) 37 | 38 | var Scheme = runtime.NewScheme() 39 | var Codecs = serializer.NewCodecFactory(Scheme) 40 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 41 | var localSchemeBuilder = runtime.SchemeBuilder{ 42 | mmontesv1alpha1.AddToScheme, 43 | } 44 | 45 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 46 | // of clientsets, like in: 47 | // 48 | // import ( 49 | // "k8s.io/client-go/kubernetes" 50 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 51 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 52 | // ) 53 | // 54 | // kclientset, _ := kubernetes.NewForConfig(c) 55 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 56 | // 57 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 58 | // correctly. 59 | var AddToScheme = localSchemeBuilder.AddToScheme 60 | 61 | func init() { 62 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 63 | utilruntime.Must(AddToScheme(Scheme)) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | // This package has the automatically generated typed clients. 28 | package v1alpha1 29 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/echo.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | "context" 31 | "time" 32 | 33 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 34 | scheme "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/scheme" 35 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 36 | types "k8s.io/apimachinery/pkg/types" 37 | watch "k8s.io/apimachinery/pkg/watch" 38 | rest "k8s.io/client-go/rest" 39 | ) 40 | 41 | // EchosGetter has a method to return a EchoInterface. 42 | // A group's client should implement this interface. 43 | type EchosGetter interface { 44 | Echos(namespace string) EchoInterface 45 | } 46 | 47 | // EchoInterface has methods to work with Echo resources. 48 | type EchoInterface interface { 49 | Create(ctx context.Context, echo *v1alpha1.Echo, opts v1.CreateOptions) (*v1alpha1.Echo, error) 50 | Update(ctx context.Context, echo *v1alpha1.Echo, opts v1.UpdateOptions) (*v1alpha1.Echo, error) 51 | Delete(ctx context.Context, name string, opts v1.DeleteOptions) error 52 | DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error 53 | Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.Echo, error) 54 | List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.EchoList, error) 55 | Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) 56 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Echo, err error) 57 | EchoExpansion 58 | } 59 | 60 | // echos implements EchoInterface 61 | type echos struct { 62 | client rest.Interface 63 | ns string 64 | } 65 | 66 | // newEchos returns a Echos 67 | func newEchos(c *MmontesV1alpha1Client, namespace string) *echos { 68 | return &echos{ 69 | client: c.RESTClient(), 70 | ns: namespace, 71 | } 72 | } 73 | 74 | // Get takes name of the echo, and returns the corresponding echo object, and an error if there is any. 75 | func (c *echos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Echo, err error) { 76 | result = &v1alpha1.Echo{} 77 | err = c.client.Get(). 78 | Namespace(c.ns). 79 | Resource("echos"). 80 | Name(name). 81 | VersionedParams(&options, scheme.ParameterCodec). 82 | Do(ctx). 83 | Into(result) 84 | return 85 | } 86 | 87 | // List takes label and field selectors, and returns the list of Echos that match those selectors. 88 | func (c *echos) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.EchoList, err error) { 89 | var timeout time.Duration 90 | if opts.TimeoutSeconds != nil { 91 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 92 | } 93 | result = &v1alpha1.EchoList{} 94 | err = c.client.Get(). 95 | Namespace(c.ns). 96 | Resource("echos"). 97 | VersionedParams(&opts, scheme.ParameterCodec). 98 | Timeout(timeout). 99 | Do(ctx). 100 | Into(result) 101 | return 102 | } 103 | 104 | // Watch returns a watch.Interface that watches the requested echos. 105 | func (c *echos) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 106 | var timeout time.Duration 107 | if opts.TimeoutSeconds != nil { 108 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 109 | } 110 | opts.Watch = true 111 | return c.client.Get(). 112 | Namespace(c.ns). 113 | Resource("echos"). 114 | VersionedParams(&opts, scheme.ParameterCodec). 115 | Timeout(timeout). 116 | Watch(ctx) 117 | } 118 | 119 | // Create takes the representation of a echo and creates it. Returns the server's representation of the echo, and an error, if there is any. 120 | func (c *echos) Create(ctx context.Context, echo *v1alpha1.Echo, opts v1.CreateOptions) (result *v1alpha1.Echo, err error) { 121 | result = &v1alpha1.Echo{} 122 | err = c.client.Post(). 123 | Namespace(c.ns). 124 | Resource("echos"). 125 | VersionedParams(&opts, scheme.ParameterCodec). 126 | Body(echo). 127 | Do(ctx). 128 | Into(result) 129 | return 130 | } 131 | 132 | // Update takes the representation of a echo and updates it. Returns the server's representation of the echo, and an error, if there is any. 133 | func (c *echos) Update(ctx context.Context, echo *v1alpha1.Echo, opts v1.UpdateOptions) (result *v1alpha1.Echo, err error) { 134 | result = &v1alpha1.Echo{} 135 | err = c.client.Put(). 136 | Namespace(c.ns). 137 | Resource("echos"). 138 | Name(echo.Name). 139 | VersionedParams(&opts, scheme.ParameterCodec). 140 | Body(echo). 141 | Do(ctx). 142 | Into(result) 143 | return 144 | } 145 | 146 | // Delete takes name of the echo and deletes it. Returns an error if one occurs. 147 | func (c *echos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 148 | return c.client.Delete(). 149 | Namespace(c.ns). 150 | Resource("echos"). 151 | Name(name). 152 | Body(&opts). 153 | Do(ctx). 154 | Error() 155 | } 156 | 157 | // DeleteCollection deletes a collection of objects. 158 | func (c *echos) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 159 | var timeout time.Duration 160 | if listOpts.TimeoutSeconds != nil { 161 | timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second 162 | } 163 | return c.client.Delete(). 164 | Namespace(c.ns). 165 | Resource("echos"). 166 | VersionedParams(&listOpts, scheme.ParameterCodec). 167 | Timeout(timeout). 168 | Body(&opts). 169 | Do(ctx). 170 | Error() 171 | } 172 | 173 | // Patch applies the patch and returns the patched echo. 174 | func (c *echos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Echo, err error) { 175 | result = &v1alpha1.Echo{} 176 | err = c.client.Patch(pt). 177 | Namespace(c.ns). 178 | Resource("echos"). 179 | Name(name). 180 | SubResource(subresources...). 181 | VersionedParams(&opts, scheme.ParameterCodec). 182 | Body(data). 183 | Do(ctx). 184 | Into(result) 185 | return 186 | } 187 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/echo_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 31 | "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/scheme" 32 | rest "k8s.io/client-go/rest" 33 | ) 34 | 35 | type MmontesV1alpha1Interface interface { 36 | RESTClient() rest.Interface 37 | EchosGetter 38 | ScheduledEchosGetter 39 | } 40 | 41 | // MmontesV1alpha1Client is used to interact with features provided by the mmontes.io group. 42 | type MmontesV1alpha1Client struct { 43 | restClient rest.Interface 44 | } 45 | 46 | func (c *MmontesV1alpha1Client) Echos(namespace string) EchoInterface { 47 | return newEchos(c, namespace) 48 | } 49 | 50 | func (c *MmontesV1alpha1Client) ScheduledEchos(namespace string) ScheduledEchoInterface { 51 | return newScheduledEchos(c, namespace) 52 | } 53 | 54 | // NewForConfig creates a new MmontesV1alpha1Client for the given config. 55 | func NewForConfig(c *rest.Config) (*MmontesV1alpha1Client, error) { 56 | config := *c 57 | if err := setConfigDefaults(&config); err != nil { 58 | return nil, err 59 | } 60 | client, err := rest.RESTClientFor(&config) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return &MmontesV1alpha1Client{client}, nil 65 | } 66 | 67 | // NewForConfigOrDie creates a new MmontesV1alpha1Client for the given config and 68 | // panics if there is an error in the config. 69 | func NewForConfigOrDie(c *rest.Config) *MmontesV1alpha1Client { 70 | client, err := NewForConfig(c) 71 | if err != nil { 72 | panic(err) 73 | } 74 | return client 75 | } 76 | 77 | // New creates a new MmontesV1alpha1Client for the given RESTClient. 78 | func New(c rest.Interface) *MmontesV1alpha1Client { 79 | return &MmontesV1alpha1Client{c} 80 | } 81 | 82 | func setConfigDefaults(config *rest.Config) error { 83 | gv := v1alpha1.SchemeGroupVersion 84 | config.GroupVersion = &gv 85 | config.APIPath = "/apis" 86 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() 87 | 88 | if config.UserAgent == "" { 89 | config.UserAgent = rest.DefaultKubernetesUserAgent() 90 | } 91 | 92 | return nil 93 | } 94 | 95 | // RESTClient returns a RESTClient that is used to communicate 96 | // with API server by this client implementation. 97 | func (c *MmontesV1alpha1Client) RESTClient() rest.Interface { 98 | if c == nil { 99 | return nil 100 | } 101 | return c.restClient 102 | } 103 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | // Package fake has the automatically generated clients. 28 | package fake 29 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/fake/fake_echo.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package fake 28 | 29 | import ( 30 | "context" 31 | 32 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 33 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 34 | labels "k8s.io/apimachinery/pkg/labels" 35 | schema "k8s.io/apimachinery/pkg/runtime/schema" 36 | types "k8s.io/apimachinery/pkg/types" 37 | watch "k8s.io/apimachinery/pkg/watch" 38 | testing "k8s.io/client-go/testing" 39 | ) 40 | 41 | // FakeEchos implements EchoInterface 42 | type FakeEchos struct { 43 | Fake *FakeMmontesV1alpha1 44 | ns string 45 | } 46 | 47 | var echosResource = schema.GroupVersionResource{Group: "mmontes.io", Version: "v1alpha1", Resource: "echos"} 48 | 49 | var echosKind = schema.GroupVersionKind{Group: "mmontes.io", Version: "v1alpha1", Kind: "Echo"} 50 | 51 | // Get takes name of the echo, and returns the corresponding echo object, and an error if there is any. 52 | func (c *FakeEchos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Echo, err error) { 53 | obj, err := c.Fake. 54 | Invokes(testing.NewGetAction(echosResource, c.ns, name), &v1alpha1.Echo{}) 55 | 56 | if obj == nil { 57 | return nil, err 58 | } 59 | return obj.(*v1alpha1.Echo), err 60 | } 61 | 62 | // List takes label and field selectors, and returns the list of Echos that match those selectors. 63 | func (c *FakeEchos) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.EchoList, err error) { 64 | obj, err := c.Fake. 65 | Invokes(testing.NewListAction(echosResource, echosKind, c.ns, opts), &v1alpha1.EchoList{}) 66 | 67 | if obj == nil { 68 | return nil, err 69 | } 70 | 71 | label, _, _ := testing.ExtractFromListOptions(opts) 72 | if label == nil { 73 | label = labels.Everything() 74 | } 75 | list := &v1alpha1.EchoList{ListMeta: obj.(*v1alpha1.EchoList).ListMeta} 76 | for _, item := range obj.(*v1alpha1.EchoList).Items { 77 | if label.Matches(labels.Set(item.Labels)) { 78 | list.Items = append(list.Items, item) 79 | } 80 | } 81 | return list, err 82 | } 83 | 84 | // Watch returns a watch.Interface that watches the requested echos. 85 | func (c *FakeEchos) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 86 | return c.Fake. 87 | InvokesWatch(testing.NewWatchAction(echosResource, c.ns, opts)) 88 | 89 | } 90 | 91 | // Create takes the representation of a echo and creates it. Returns the server's representation of the echo, and an error, if there is any. 92 | func (c *FakeEchos) Create(ctx context.Context, echo *v1alpha1.Echo, opts v1.CreateOptions) (result *v1alpha1.Echo, err error) { 93 | obj, err := c.Fake. 94 | Invokes(testing.NewCreateAction(echosResource, c.ns, echo), &v1alpha1.Echo{}) 95 | 96 | if obj == nil { 97 | return nil, err 98 | } 99 | return obj.(*v1alpha1.Echo), err 100 | } 101 | 102 | // Update takes the representation of a echo and updates it. Returns the server's representation of the echo, and an error, if there is any. 103 | func (c *FakeEchos) Update(ctx context.Context, echo *v1alpha1.Echo, opts v1.UpdateOptions) (result *v1alpha1.Echo, err error) { 104 | obj, err := c.Fake. 105 | Invokes(testing.NewUpdateAction(echosResource, c.ns, echo), &v1alpha1.Echo{}) 106 | 107 | if obj == nil { 108 | return nil, err 109 | } 110 | return obj.(*v1alpha1.Echo), err 111 | } 112 | 113 | // Delete takes name of the echo and deletes it. Returns an error if one occurs. 114 | func (c *FakeEchos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 115 | _, err := c.Fake. 116 | Invokes(testing.NewDeleteAction(echosResource, c.ns, name), &v1alpha1.Echo{}) 117 | 118 | return err 119 | } 120 | 121 | // DeleteCollection deletes a collection of objects. 122 | func (c *FakeEchos) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 123 | action := testing.NewDeleteCollectionAction(echosResource, c.ns, listOpts) 124 | 125 | _, err := c.Fake.Invokes(action, &v1alpha1.EchoList{}) 126 | return err 127 | } 128 | 129 | // Patch applies the patch and returns the patched echo. 130 | func (c *FakeEchos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Echo, err error) { 131 | obj, err := c.Fake. 132 | Invokes(testing.NewPatchSubresourceAction(echosResource, c.ns, name, pt, data, subresources...), &v1alpha1.Echo{}) 133 | 134 | if obj == nil { 135 | return nil, err 136 | } 137 | return obj.(*v1alpha1.Echo), err 138 | } 139 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/fake/fake_echo_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package fake 28 | 29 | import ( 30 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1" 31 | rest "k8s.io/client-go/rest" 32 | testing "k8s.io/client-go/testing" 33 | ) 34 | 35 | type FakeMmontesV1alpha1 struct { 36 | *testing.Fake 37 | } 38 | 39 | func (c *FakeMmontesV1alpha1) Echos(namespace string) v1alpha1.EchoInterface { 40 | return &FakeEchos{c, namespace} 41 | } 42 | 43 | func (c *FakeMmontesV1alpha1) ScheduledEchos(namespace string) v1alpha1.ScheduledEchoInterface { 44 | return &FakeScheduledEchos{c, namespace} 45 | } 46 | 47 | // RESTClient returns a RESTClient that is used to communicate 48 | // with API server by this client implementation. 49 | func (c *FakeMmontesV1alpha1) RESTClient() rest.Interface { 50 | var ret *rest.RESTClient 51 | return ret 52 | } 53 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/fake/fake_scheduledecho.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package fake 28 | 29 | import ( 30 | "context" 31 | 32 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 33 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 34 | labels "k8s.io/apimachinery/pkg/labels" 35 | schema "k8s.io/apimachinery/pkg/runtime/schema" 36 | types "k8s.io/apimachinery/pkg/types" 37 | watch "k8s.io/apimachinery/pkg/watch" 38 | testing "k8s.io/client-go/testing" 39 | ) 40 | 41 | // FakeScheduledEchos implements ScheduledEchoInterface 42 | type FakeScheduledEchos struct { 43 | Fake *FakeMmontesV1alpha1 44 | ns string 45 | } 46 | 47 | var scheduledechosResource = schema.GroupVersionResource{Group: "mmontes.io", Version: "v1alpha1", Resource: "scheduledechos"} 48 | 49 | var scheduledechosKind = schema.GroupVersionKind{Group: "mmontes.io", Version: "v1alpha1", Kind: "ScheduledEcho"} 50 | 51 | // Get takes name of the scheduledEcho, and returns the corresponding scheduledEcho object, and an error if there is any. 52 | func (c *FakeScheduledEchos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ScheduledEcho, err error) { 53 | obj, err := c.Fake. 54 | Invokes(testing.NewGetAction(scheduledechosResource, c.ns, name), &v1alpha1.ScheduledEcho{}) 55 | 56 | if obj == nil { 57 | return nil, err 58 | } 59 | return obj.(*v1alpha1.ScheduledEcho), err 60 | } 61 | 62 | // List takes label and field selectors, and returns the list of ScheduledEchos that match those selectors. 63 | func (c *FakeScheduledEchos) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ScheduledEchoList, err error) { 64 | obj, err := c.Fake. 65 | Invokes(testing.NewListAction(scheduledechosResource, scheduledechosKind, c.ns, opts), &v1alpha1.ScheduledEchoList{}) 66 | 67 | if obj == nil { 68 | return nil, err 69 | } 70 | 71 | label, _, _ := testing.ExtractFromListOptions(opts) 72 | if label == nil { 73 | label = labels.Everything() 74 | } 75 | list := &v1alpha1.ScheduledEchoList{ListMeta: obj.(*v1alpha1.ScheduledEchoList).ListMeta} 76 | for _, item := range obj.(*v1alpha1.ScheduledEchoList).Items { 77 | if label.Matches(labels.Set(item.Labels)) { 78 | list.Items = append(list.Items, item) 79 | } 80 | } 81 | return list, err 82 | } 83 | 84 | // Watch returns a watch.Interface that watches the requested scheduledEchos. 85 | func (c *FakeScheduledEchos) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 86 | return c.Fake. 87 | InvokesWatch(testing.NewWatchAction(scheduledechosResource, c.ns, opts)) 88 | 89 | } 90 | 91 | // Create takes the representation of a scheduledEcho and creates it. Returns the server's representation of the scheduledEcho, and an error, if there is any. 92 | func (c *FakeScheduledEchos) Create(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.CreateOptions) (result *v1alpha1.ScheduledEcho, err error) { 93 | obj, err := c.Fake. 94 | Invokes(testing.NewCreateAction(scheduledechosResource, c.ns, scheduledEcho), &v1alpha1.ScheduledEcho{}) 95 | 96 | if obj == nil { 97 | return nil, err 98 | } 99 | return obj.(*v1alpha1.ScheduledEcho), err 100 | } 101 | 102 | // Update takes the representation of a scheduledEcho and updates it. Returns the server's representation of the scheduledEcho, and an error, if there is any. 103 | func (c *FakeScheduledEchos) Update(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.UpdateOptions) (result *v1alpha1.ScheduledEcho, err error) { 104 | obj, err := c.Fake. 105 | Invokes(testing.NewUpdateAction(scheduledechosResource, c.ns, scheduledEcho), &v1alpha1.ScheduledEcho{}) 106 | 107 | if obj == nil { 108 | return nil, err 109 | } 110 | return obj.(*v1alpha1.ScheduledEcho), err 111 | } 112 | 113 | // Delete takes name of the scheduledEcho and deletes it. Returns an error if one occurs. 114 | func (c *FakeScheduledEchos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 115 | _, err := c.Fake. 116 | Invokes(testing.NewDeleteAction(scheduledechosResource, c.ns, name), &v1alpha1.ScheduledEcho{}) 117 | 118 | return err 119 | } 120 | 121 | // DeleteCollection deletes a collection of objects. 122 | func (c *FakeScheduledEchos) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 123 | action := testing.NewDeleteCollectionAction(scheduledechosResource, c.ns, listOpts) 124 | 125 | _, err := c.Fake.Invokes(action, &v1alpha1.ScheduledEchoList{}) 126 | return err 127 | } 128 | 129 | // Patch applies the patch and returns the patched scheduledEcho. 130 | func (c *FakeScheduledEchos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ScheduledEcho, err error) { 131 | obj, err := c.Fake. 132 | Invokes(testing.NewPatchSubresourceAction(scheduledechosResource, c.ns, name, pt, data, subresources...), &v1alpha1.ScheduledEcho{}) 133 | 134 | if obj == nil { 135 | return nil, err 136 | } 137 | return obj.(*v1alpha1.ScheduledEcho), err 138 | } 139 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | type EchoExpansion interface{} 30 | 31 | type ScheduledEchoExpansion interface{} 32 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/clientset/versioned/typed/echo/v1alpha1/scheduledecho.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by client-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | "context" 31 | "time" 32 | 33 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 34 | scheme "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned/scheme" 35 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 36 | types "k8s.io/apimachinery/pkg/types" 37 | watch "k8s.io/apimachinery/pkg/watch" 38 | rest "k8s.io/client-go/rest" 39 | ) 40 | 41 | // ScheduledEchosGetter has a method to return a ScheduledEchoInterface. 42 | // A group's client should implement this interface. 43 | type ScheduledEchosGetter interface { 44 | ScheduledEchos(namespace string) ScheduledEchoInterface 45 | } 46 | 47 | // ScheduledEchoInterface has methods to work with ScheduledEcho resources. 48 | type ScheduledEchoInterface interface { 49 | Create(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.CreateOptions) (*v1alpha1.ScheduledEcho, error) 50 | Update(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.UpdateOptions) (*v1alpha1.ScheduledEcho, error) 51 | Delete(ctx context.Context, name string, opts v1.DeleteOptions) error 52 | DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error 53 | Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ScheduledEcho, error) 54 | List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ScheduledEchoList, error) 55 | Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) 56 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ScheduledEcho, err error) 57 | ScheduledEchoExpansion 58 | } 59 | 60 | // scheduledEchos implements ScheduledEchoInterface 61 | type scheduledEchos struct { 62 | client rest.Interface 63 | ns string 64 | } 65 | 66 | // newScheduledEchos returns a ScheduledEchos 67 | func newScheduledEchos(c *MmontesV1alpha1Client, namespace string) *scheduledEchos { 68 | return &scheduledEchos{ 69 | client: c.RESTClient(), 70 | ns: namespace, 71 | } 72 | } 73 | 74 | // Get takes name of the scheduledEcho, and returns the corresponding scheduledEcho object, and an error if there is any. 75 | func (c *scheduledEchos) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ScheduledEcho, err error) { 76 | result = &v1alpha1.ScheduledEcho{} 77 | err = c.client.Get(). 78 | Namespace(c.ns). 79 | Resource("scheduledechos"). 80 | Name(name). 81 | VersionedParams(&options, scheme.ParameterCodec). 82 | Do(ctx). 83 | Into(result) 84 | return 85 | } 86 | 87 | // List takes label and field selectors, and returns the list of ScheduledEchos that match those selectors. 88 | func (c *scheduledEchos) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ScheduledEchoList, err error) { 89 | var timeout time.Duration 90 | if opts.TimeoutSeconds != nil { 91 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 92 | } 93 | result = &v1alpha1.ScheduledEchoList{} 94 | err = c.client.Get(). 95 | Namespace(c.ns). 96 | Resource("scheduledechos"). 97 | VersionedParams(&opts, scheme.ParameterCodec). 98 | Timeout(timeout). 99 | Do(ctx). 100 | Into(result) 101 | return 102 | } 103 | 104 | // Watch returns a watch.Interface that watches the requested scheduledEchos. 105 | func (c *scheduledEchos) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { 106 | var timeout time.Duration 107 | if opts.TimeoutSeconds != nil { 108 | timeout = time.Duration(*opts.TimeoutSeconds) * time.Second 109 | } 110 | opts.Watch = true 111 | return c.client.Get(). 112 | Namespace(c.ns). 113 | Resource("scheduledechos"). 114 | VersionedParams(&opts, scheme.ParameterCodec). 115 | Timeout(timeout). 116 | Watch(ctx) 117 | } 118 | 119 | // Create takes the representation of a scheduledEcho and creates it. Returns the server's representation of the scheduledEcho, and an error, if there is any. 120 | func (c *scheduledEchos) Create(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.CreateOptions) (result *v1alpha1.ScheduledEcho, err error) { 121 | result = &v1alpha1.ScheduledEcho{} 122 | err = c.client.Post(). 123 | Namespace(c.ns). 124 | Resource("scheduledechos"). 125 | VersionedParams(&opts, scheme.ParameterCodec). 126 | Body(scheduledEcho). 127 | Do(ctx). 128 | Into(result) 129 | return 130 | } 131 | 132 | // Update takes the representation of a scheduledEcho and updates it. Returns the server's representation of the scheduledEcho, and an error, if there is any. 133 | func (c *scheduledEchos) Update(ctx context.Context, scheduledEcho *v1alpha1.ScheduledEcho, opts v1.UpdateOptions) (result *v1alpha1.ScheduledEcho, err error) { 134 | result = &v1alpha1.ScheduledEcho{} 135 | err = c.client.Put(). 136 | Namespace(c.ns). 137 | Resource("scheduledechos"). 138 | Name(scheduledEcho.Name). 139 | VersionedParams(&opts, scheme.ParameterCodec). 140 | Body(scheduledEcho). 141 | Do(ctx). 142 | Into(result) 143 | return 144 | } 145 | 146 | // Delete takes name of the scheduledEcho and deletes it. Returns an error if one occurs. 147 | func (c *scheduledEchos) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { 148 | return c.client.Delete(). 149 | Namespace(c.ns). 150 | Resource("scheduledechos"). 151 | Name(name). 152 | Body(&opts). 153 | Do(ctx). 154 | Error() 155 | } 156 | 157 | // DeleteCollection deletes a collection of objects. 158 | func (c *scheduledEchos) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { 159 | var timeout time.Duration 160 | if listOpts.TimeoutSeconds != nil { 161 | timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second 162 | } 163 | return c.client.Delete(). 164 | Namespace(c.ns). 165 | Resource("scheduledechos"). 166 | VersionedParams(&listOpts, scheme.ParameterCodec). 167 | Timeout(timeout). 168 | Body(&opts). 169 | Do(ctx). 170 | Error() 171 | } 172 | 173 | // Patch applies the patch and returns the patched scheduledEcho. 174 | func (c *scheduledEchos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ScheduledEcho, err error) { 175 | result = &v1alpha1.ScheduledEcho{} 176 | err = c.client.Patch(pt). 177 | Namespace(c.ns). 178 | Resource("scheduledechos"). 179 | Name(name). 180 | SubResource(subresources...). 181 | VersionedParams(&opts, scheme.ParameterCodec). 182 | Body(data). 183 | Do(ctx). 184 | Into(result) 185 | return 186 | } 187 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/echo/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package echo 28 | 29 | import ( 30 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/echo/v1alpha1" 31 | internalinterfaces "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces" 32 | ) 33 | 34 | // Interface provides access to each of this group's versions. 35 | type Interface interface { 36 | // V1alpha1 provides access to shared informers for resources in V1alpha1. 37 | V1alpha1() v1alpha1.Interface 38 | } 39 | 40 | type group struct { 41 | factory internalinterfaces.SharedInformerFactory 42 | namespace string 43 | tweakListOptions internalinterfaces.TweakListOptionsFunc 44 | } 45 | 46 | // New returns a new Interface. 47 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 48 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 49 | } 50 | 51 | // V1alpha1 returns a new v1alpha1.Interface. 52 | func (g *group) V1alpha1() v1alpha1.Interface { 53 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/echo/v1alpha1/echo.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | "context" 31 | time "time" 32 | 33 | echov1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 34 | versioned "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 35 | internalinterfaces "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces" 36 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/listers/echo/v1alpha1" 37 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 38 | runtime "k8s.io/apimachinery/pkg/runtime" 39 | watch "k8s.io/apimachinery/pkg/watch" 40 | cache "k8s.io/client-go/tools/cache" 41 | ) 42 | 43 | // EchoInformer provides access to a shared informer and lister for 44 | // Echos. 45 | type EchoInformer interface { 46 | Informer() cache.SharedIndexInformer 47 | Lister() v1alpha1.EchoLister 48 | } 49 | 50 | type echoInformer struct { 51 | factory internalinterfaces.SharedInformerFactory 52 | tweakListOptions internalinterfaces.TweakListOptionsFunc 53 | namespace string 54 | } 55 | 56 | // NewEchoInformer constructs a new informer for Echo type. 57 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 58 | // one. This reduces memory footprint and number of connections to the server. 59 | func NewEchoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { 60 | return NewFilteredEchoInformer(client, namespace, resyncPeriod, indexers, nil) 61 | } 62 | 63 | // NewFilteredEchoInformer constructs a new informer for Echo type. 64 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 65 | // one. This reduces memory footprint and number of connections to the server. 66 | func NewFilteredEchoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { 67 | return cache.NewSharedIndexInformer( 68 | &cache.ListWatch{ 69 | ListFunc: func(options v1.ListOptions) (runtime.Object, error) { 70 | if tweakListOptions != nil { 71 | tweakListOptions(&options) 72 | } 73 | return client.MmontesV1alpha1().Echos(namespace).List(context.TODO(), options) 74 | }, 75 | WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { 76 | if tweakListOptions != nil { 77 | tweakListOptions(&options) 78 | } 79 | return client.MmontesV1alpha1().Echos(namespace).Watch(context.TODO(), options) 80 | }, 81 | }, 82 | &echov1alpha1.Echo{}, 83 | resyncPeriod, 84 | indexers, 85 | ) 86 | } 87 | 88 | func (f *echoInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { 89 | return NewFilteredEchoInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) 90 | } 91 | 92 | func (f *echoInformer) Informer() cache.SharedIndexInformer { 93 | return f.factory.InformerFor(&echov1alpha1.Echo{}, f.defaultInformer) 94 | } 95 | 96 | func (f *echoInformer) Lister() v1alpha1.EchoLister { 97 | return v1alpha1.NewEchoLister(f.Informer().GetIndexer()) 98 | } 99 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/echo/v1alpha1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | internalinterfaces "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces" 31 | ) 32 | 33 | // Interface provides access to all the informers in this group version. 34 | type Interface interface { 35 | // Echos returns a EchoInformer. 36 | Echos() EchoInformer 37 | // ScheduledEchos returns a ScheduledEchoInformer. 38 | ScheduledEchos() ScheduledEchoInformer 39 | } 40 | 41 | type version struct { 42 | factory internalinterfaces.SharedInformerFactory 43 | namespace string 44 | tweakListOptions internalinterfaces.TweakListOptionsFunc 45 | } 46 | 47 | // New returns a new Interface. 48 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 49 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 50 | } 51 | 52 | // Echos returns a EchoInformer. 53 | func (v *version) Echos() EchoInformer { 54 | return &echoInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 55 | } 56 | 57 | // ScheduledEchos returns a ScheduledEchoInformer. 58 | func (v *version) ScheduledEchos() ScheduledEchoInformer { 59 | return &scheduledEchoInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 60 | } 61 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/echo/v1alpha1/scheduledecho.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | "context" 31 | time "time" 32 | 33 | echov1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 34 | versioned "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 35 | internalinterfaces "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces" 36 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/listers/echo/v1alpha1" 37 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 38 | runtime "k8s.io/apimachinery/pkg/runtime" 39 | watch "k8s.io/apimachinery/pkg/watch" 40 | cache "k8s.io/client-go/tools/cache" 41 | ) 42 | 43 | // ScheduledEchoInformer provides access to a shared informer and lister for 44 | // ScheduledEchos. 45 | type ScheduledEchoInformer interface { 46 | Informer() cache.SharedIndexInformer 47 | Lister() v1alpha1.ScheduledEchoLister 48 | } 49 | 50 | type scheduledEchoInformer struct { 51 | factory internalinterfaces.SharedInformerFactory 52 | tweakListOptions internalinterfaces.TweakListOptionsFunc 53 | namespace string 54 | } 55 | 56 | // NewScheduledEchoInformer constructs a new informer for ScheduledEcho type. 57 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 58 | // one. This reduces memory footprint and number of connections to the server. 59 | func NewScheduledEchoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { 60 | return NewFilteredScheduledEchoInformer(client, namespace, resyncPeriod, indexers, nil) 61 | } 62 | 63 | // NewFilteredScheduledEchoInformer constructs a new informer for ScheduledEcho type. 64 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 65 | // one. This reduces memory footprint and number of connections to the server. 66 | func NewFilteredScheduledEchoInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { 67 | return cache.NewSharedIndexInformer( 68 | &cache.ListWatch{ 69 | ListFunc: func(options v1.ListOptions) (runtime.Object, error) { 70 | if tweakListOptions != nil { 71 | tweakListOptions(&options) 72 | } 73 | return client.MmontesV1alpha1().ScheduledEchos(namespace).List(context.TODO(), options) 74 | }, 75 | WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { 76 | if tweakListOptions != nil { 77 | tweakListOptions(&options) 78 | } 79 | return client.MmontesV1alpha1().ScheduledEchos(namespace).Watch(context.TODO(), options) 80 | }, 81 | }, 82 | &echov1alpha1.ScheduledEcho{}, 83 | resyncPeriod, 84 | indexers, 85 | ) 86 | } 87 | 88 | func (f *scheduledEchoInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { 89 | return NewFilteredScheduledEchoInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) 90 | } 91 | 92 | func (f *scheduledEchoInformer) Informer() cache.SharedIndexInformer { 93 | return f.factory.InformerFor(&echov1alpha1.ScheduledEcho{}, f.defaultInformer) 94 | } 95 | 96 | func (f *scheduledEchoInformer) Lister() v1alpha1.ScheduledEchoLister { 97 | return v1alpha1.NewScheduledEchoLister(f.Informer().GetIndexer()) 98 | } 99 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package externalversions 28 | 29 | import ( 30 | reflect "reflect" 31 | sync "sync" 32 | time "time" 33 | 34 | versioned "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 35 | echo "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/echo" 36 | internalinterfaces "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces" 37 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 38 | runtime "k8s.io/apimachinery/pkg/runtime" 39 | schema "k8s.io/apimachinery/pkg/runtime/schema" 40 | cache "k8s.io/client-go/tools/cache" 41 | ) 42 | 43 | // SharedInformerOption defines the functional option type for SharedInformerFactory. 44 | type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory 45 | 46 | type sharedInformerFactory struct { 47 | client versioned.Interface 48 | namespace string 49 | tweakListOptions internalinterfaces.TweakListOptionsFunc 50 | lock sync.Mutex 51 | defaultResync time.Duration 52 | customResync map[reflect.Type]time.Duration 53 | 54 | informers map[reflect.Type]cache.SharedIndexInformer 55 | // startedInformers is used for tracking which informers have been started. 56 | // This allows Start() to be called multiple times safely. 57 | startedInformers map[reflect.Type]bool 58 | } 59 | 60 | // WithCustomResyncConfig sets a custom resync period for the specified informer types. 61 | func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { 62 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 63 | for k, v := range resyncConfig { 64 | factory.customResync[reflect.TypeOf(k)] = v 65 | } 66 | return factory 67 | } 68 | } 69 | 70 | // WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. 71 | func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { 72 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 73 | factory.tweakListOptions = tweakListOptions 74 | return factory 75 | } 76 | } 77 | 78 | // WithNamespace limits the SharedInformerFactory to the specified namespace. 79 | func WithNamespace(namespace string) SharedInformerOption { 80 | return func(factory *sharedInformerFactory) *sharedInformerFactory { 81 | factory.namespace = namespace 82 | return factory 83 | } 84 | } 85 | 86 | // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. 87 | func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { 88 | return NewSharedInformerFactoryWithOptions(client, defaultResync) 89 | } 90 | 91 | // NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. 92 | // Listers obtained via this SharedInformerFactory will be subject to the same filters 93 | // as specified here. 94 | // Deprecated: Please use NewSharedInformerFactoryWithOptions instead 95 | func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { 96 | return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) 97 | } 98 | 99 | // NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. 100 | func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { 101 | factory := &sharedInformerFactory{ 102 | client: client, 103 | namespace: v1.NamespaceAll, 104 | defaultResync: defaultResync, 105 | informers: make(map[reflect.Type]cache.SharedIndexInformer), 106 | startedInformers: make(map[reflect.Type]bool), 107 | customResync: make(map[reflect.Type]time.Duration), 108 | } 109 | 110 | // Apply all options 111 | for _, opt := range options { 112 | factory = opt(factory) 113 | } 114 | 115 | return factory 116 | } 117 | 118 | // Start initializes all requested informers. 119 | func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { 120 | f.lock.Lock() 121 | defer f.lock.Unlock() 122 | 123 | for informerType, informer := range f.informers { 124 | if !f.startedInformers[informerType] { 125 | go informer.Run(stopCh) 126 | f.startedInformers[informerType] = true 127 | } 128 | } 129 | } 130 | 131 | // WaitForCacheSync waits for all started informers' cache were synced. 132 | func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { 133 | informers := func() map[reflect.Type]cache.SharedIndexInformer { 134 | f.lock.Lock() 135 | defer f.lock.Unlock() 136 | 137 | informers := map[reflect.Type]cache.SharedIndexInformer{} 138 | for informerType, informer := range f.informers { 139 | if f.startedInformers[informerType] { 140 | informers[informerType] = informer 141 | } 142 | } 143 | return informers 144 | }() 145 | 146 | res := map[reflect.Type]bool{} 147 | for informType, informer := range informers { 148 | res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) 149 | } 150 | return res 151 | } 152 | 153 | // InternalInformerFor returns the SharedIndexInformer for obj using an internal 154 | // client. 155 | func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { 156 | f.lock.Lock() 157 | defer f.lock.Unlock() 158 | 159 | informerType := reflect.TypeOf(obj) 160 | informer, exists := f.informers[informerType] 161 | if exists { 162 | return informer 163 | } 164 | 165 | resyncPeriod, exists := f.customResync[informerType] 166 | if !exists { 167 | resyncPeriod = f.defaultResync 168 | } 169 | 170 | informer = newFunc(f.client, resyncPeriod) 171 | f.informers[informerType] = informer 172 | 173 | return informer 174 | } 175 | 176 | // SharedInformerFactory provides shared informers for resources in all known 177 | // API group versions. 178 | type SharedInformerFactory interface { 179 | internalinterfaces.SharedInformerFactory 180 | ForResource(resource schema.GroupVersionResource) (GenericInformer, error) 181 | WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool 182 | 183 | Mmontes() echo.Interface 184 | } 185 | 186 | func (f *sharedInformerFactory) Mmontes() echo.Interface { 187 | return echo.New(f, f.namespace, f.tweakListOptions) 188 | } 189 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package externalversions 28 | 29 | import ( 30 | "fmt" 31 | 32 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 33 | schema "k8s.io/apimachinery/pkg/runtime/schema" 34 | cache "k8s.io/client-go/tools/cache" 35 | ) 36 | 37 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 38 | // sharedInformers based on type 39 | type GenericInformer interface { 40 | Informer() cache.SharedIndexInformer 41 | Lister() cache.GenericLister 42 | } 43 | 44 | type genericInformer struct { 45 | informer cache.SharedIndexInformer 46 | resource schema.GroupResource 47 | } 48 | 49 | // Informer returns the SharedIndexInformer. 50 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 51 | return f.informer 52 | } 53 | 54 | // Lister returns the GenericLister. 55 | func (f *genericInformer) Lister() cache.GenericLister { 56 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 57 | } 58 | 59 | // ForResource gives generic access to a shared informer of the matching type 60 | // TODO extend this to unknown resources with a client pool 61 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 62 | switch resource { 63 | // Group=mmontes.io, Version=v1alpha1 64 | case v1alpha1.SchemeGroupVersion.WithResource("echos"): 65 | return &genericInformer{resource: resource.GroupResource(), informer: f.Mmontes().V1alpha1().Echos().Informer()}, nil 66 | case v1alpha1.SchemeGroupVersion.WithResource("scheduledechos"): 67 | return &genericInformer{resource: resource.GroupResource(), informer: f.Mmontes().V1alpha1().ScheduledEchos().Informer()}, nil 68 | 69 | } 70 | 71 | return nil, fmt.Errorf("no informer found for %v", resource) 72 | } 73 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by informer-gen. DO NOT EDIT. 26 | 27 | package internalinterfaces 28 | 29 | import ( 30 | time "time" 31 | 32 | versioned "github.com/mmontes11/echoperator/pkg/echo/v1alpha1/apis/clientset/versioned" 33 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 34 | runtime "k8s.io/apimachinery/pkg/runtime" 35 | cache "k8s.io/client-go/tools/cache" 36 | ) 37 | 38 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 39 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 40 | 41 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 42 | type SharedInformerFactory interface { 43 | Start(stopCh <-chan struct{}) 44 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 45 | } 46 | 47 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 48 | type TweakListOptionsFunc func(*v1.ListOptions) 49 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/listers/echo/v1alpha1/echo.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by lister-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 31 | "k8s.io/apimachinery/pkg/api/errors" 32 | "k8s.io/apimachinery/pkg/labels" 33 | "k8s.io/client-go/tools/cache" 34 | ) 35 | 36 | // EchoLister helps list Echos. 37 | // All objects returned here must be treated as read-only. 38 | type EchoLister interface { 39 | // List lists all Echos in the indexer. 40 | // Objects returned here must be treated as read-only. 41 | List(selector labels.Selector) (ret []*v1alpha1.Echo, err error) 42 | // Echos returns an object that can list and get Echos. 43 | Echos(namespace string) EchoNamespaceLister 44 | EchoListerExpansion 45 | } 46 | 47 | // echoLister implements the EchoLister interface. 48 | type echoLister struct { 49 | indexer cache.Indexer 50 | } 51 | 52 | // NewEchoLister returns a new EchoLister. 53 | func NewEchoLister(indexer cache.Indexer) EchoLister { 54 | return &echoLister{indexer: indexer} 55 | } 56 | 57 | // List lists all Echos in the indexer. 58 | func (s *echoLister) List(selector labels.Selector) (ret []*v1alpha1.Echo, err error) { 59 | err = cache.ListAll(s.indexer, selector, func(m interface{}) { 60 | ret = append(ret, m.(*v1alpha1.Echo)) 61 | }) 62 | return ret, err 63 | } 64 | 65 | // Echos returns an object that can list and get Echos. 66 | func (s *echoLister) Echos(namespace string) EchoNamespaceLister { 67 | return echoNamespaceLister{indexer: s.indexer, namespace: namespace} 68 | } 69 | 70 | // EchoNamespaceLister helps list and get Echos. 71 | // All objects returned here must be treated as read-only. 72 | type EchoNamespaceLister interface { 73 | // List lists all Echos in the indexer for a given namespace. 74 | // Objects returned here must be treated as read-only. 75 | List(selector labels.Selector) (ret []*v1alpha1.Echo, err error) 76 | // Get retrieves the Echo from the indexer for a given namespace and name. 77 | // Objects returned here must be treated as read-only. 78 | Get(name string) (*v1alpha1.Echo, error) 79 | EchoNamespaceListerExpansion 80 | } 81 | 82 | // echoNamespaceLister implements the EchoNamespaceLister 83 | // interface. 84 | type echoNamespaceLister struct { 85 | indexer cache.Indexer 86 | namespace string 87 | } 88 | 89 | // List lists all Echos in the indexer for a given namespace. 90 | func (s echoNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Echo, err error) { 91 | err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { 92 | ret = append(ret, m.(*v1alpha1.Echo)) 93 | }) 94 | return ret, err 95 | } 96 | 97 | // Get retrieves the Echo from the indexer for a given namespace and name. 98 | func (s echoNamespaceLister) Get(name string) (*v1alpha1.Echo, error) { 99 | obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) 100 | if err != nil { 101 | return nil, err 102 | } 103 | if !exists { 104 | return nil, errors.NewNotFound(v1alpha1.Resource("echo"), name) 105 | } 106 | return obj.(*v1alpha1.Echo), nil 107 | } 108 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/listers/echo/v1alpha1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by lister-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | // EchoListerExpansion allows custom methods to be added to 30 | // EchoLister. 31 | type EchoListerExpansion interface{} 32 | 33 | // EchoNamespaceListerExpansion allows custom methods to be added to 34 | // EchoNamespaceLister. 35 | type EchoNamespaceListerExpansion interface{} 36 | 37 | // ScheduledEchoListerExpansion allows custom methods to be added to 38 | // ScheduledEchoLister. 39 | type ScheduledEchoListerExpansion interface{} 40 | 41 | // ScheduledEchoNamespaceListerExpansion allows custom methods to be added to 42 | // ScheduledEchoNamespaceLister. 43 | type ScheduledEchoNamespaceListerExpansion interface{} 44 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/apis/listers/echo/v1alpha1/scheduledecho.go: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2021 Martín Montes 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | // Code generated by lister-gen. DO NOT EDIT. 26 | 27 | package v1alpha1 28 | 29 | import ( 30 | v1alpha1 "github.com/mmontes11/echoperator/pkg/echo/v1alpha1" 31 | "k8s.io/apimachinery/pkg/api/errors" 32 | "k8s.io/apimachinery/pkg/labels" 33 | "k8s.io/client-go/tools/cache" 34 | ) 35 | 36 | // ScheduledEchoLister helps list ScheduledEchos. 37 | // All objects returned here must be treated as read-only. 38 | type ScheduledEchoLister interface { 39 | // List lists all ScheduledEchos in the indexer. 40 | // Objects returned here must be treated as read-only. 41 | List(selector labels.Selector) (ret []*v1alpha1.ScheduledEcho, err error) 42 | // ScheduledEchos returns an object that can list and get ScheduledEchos. 43 | ScheduledEchos(namespace string) ScheduledEchoNamespaceLister 44 | ScheduledEchoListerExpansion 45 | } 46 | 47 | // scheduledEchoLister implements the ScheduledEchoLister interface. 48 | type scheduledEchoLister struct { 49 | indexer cache.Indexer 50 | } 51 | 52 | // NewScheduledEchoLister returns a new ScheduledEchoLister. 53 | func NewScheduledEchoLister(indexer cache.Indexer) ScheduledEchoLister { 54 | return &scheduledEchoLister{indexer: indexer} 55 | } 56 | 57 | // List lists all ScheduledEchos in the indexer. 58 | func (s *scheduledEchoLister) List(selector labels.Selector) (ret []*v1alpha1.ScheduledEcho, err error) { 59 | err = cache.ListAll(s.indexer, selector, func(m interface{}) { 60 | ret = append(ret, m.(*v1alpha1.ScheduledEcho)) 61 | }) 62 | return ret, err 63 | } 64 | 65 | // ScheduledEchos returns an object that can list and get ScheduledEchos. 66 | func (s *scheduledEchoLister) ScheduledEchos(namespace string) ScheduledEchoNamespaceLister { 67 | return scheduledEchoNamespaceLister{indexer: s.indexer, namespace: namespace} 68 | } 69 | 70 | // ScheduledEchoNamespaceLister helps list and get ScheduledEchos. 71 | // All objects returned here must be treated as read-only. 72 | type ScheduledEchoNamespaceLister interface { 73 | // List lists all ScheduledEchos in the indexer for a given namespace. 74 | // Objects returned here must be treated as read-only. 75 | List(selector labels.Selector) (ret []*v1alpha1.ScheduledEcho, err error) 76 | // Get retrieves the ScheduledEcho from the indexer for a given namespace and name. 77 | // Objects returned here must be treated as read-only. 78 | Get(name string) (*v1alpha1.ScheduledEcho, error) 79 | ScheduledEchoNamespaceListerExpansion 80 | } 81 | 82 | // scheduledEchoNamespaceLister implements the ScheduledEchoNamespaceLister 83 | // interface. 84 | type scheduledEchoNamespaceLister struct { 85 | indexer cache.Indexer 86 | namespace string 87 | } 88 | 89 | // List lists all ScheduledEchos in the indexer for a given namespace. 90 | func (s scheduledEchoNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ScheduledEcho, err error) { 91 | err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { 92 | ret = append(ret, m.(*v1alpha1.ScheduledEcho)) 93 | }) 94 | return ret, err 95 | } 96 | 97 | // Get retrieves the ScheduledEcho from the indexer for a given namespace and name. 98 | func (s scheduledEchoNamespaceLister) Get(name string) (*v1alpha1.ScheduledEcho, error) { 99 | obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) 100 | if err != nil { 101 | return nil, err 102 | } 103 | if !exists { 104 | return nil, errors.NewNotFound(v1alpha1.Resource("scheduledecho"), name) 105 | } 106 | return obj.(*v1alpha1.ScheduledEcho), nil 107 | } 108 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // +k8s:deepcopy-gen=package,register 2 | // +k8s:defaulter-gen=TypeMeta 3 | // +k8s:openapi-gen=true 4 | 5 | // +groupName=mmontes.io 6 | package v1alpha1 7 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/register.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | "github.com/mmontes11/echoperator/pkg/echo" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | 7 | "k8s.io/apimachinery/pkg/runtime" 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | ) 10 | 11 | var ( 12 | SchemeGroupVersion = schema.GroupVersion{ 13 | Group: echo.GroupName, 14 | Version: echo.V1alpha1, 15 | } 16 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 17 | AddToScheme = SchemeBuilder.AddToScheme 18 | ) 19 | 20 | func Resource(resource string) schema.GroupResource { 21 | return SchemeGroupVersion.WithResource(resource).GroupResource() 22 | } 23 | 24 | func addKnownTypes(scheme *runtime.Scheme) error { 25 | scheme.AddKnownTypes(SchemeGroupVersion, 26 | &Echo{}, 27 | &EchoList{}, 28 | &ScheduledEcho{}, 29 | &ScheduledEchoList{}, 30 | ) 31 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/types.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 4 | 5 | // +genclient 6 | // +genclient:noStatus 7 | // +k8s:deepcopy-gen=true 8 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 9 | type Echo struct { 10 | metav1.TypeMeta `json:",inline"` 11 | metav1.ObjectMeta `json:"metadata"` 12 | Spec EchoSpec `json:"spec"` 13 | } 14 | 15 | type EchoSpec struct { 16 | Message string `json:"message"` 17 | } 18 | 19 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 20 | type EchoList struct { 21 | metav1.TypeMeta `json:",inline"` 22 | metav1.ListMeta `json:"metadata"` 23 | Items []Echo `json:"items"` 24 | } 25 | 26 | // +genclient 27 | // +genclient:noStatus 28 | // +k8s:deepcopy-gen=true 29 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 30 | type ScheduledEcho struct { 31 | metav1.TypeMeta `json:",inline"` 32 | metav1.ObjectMeta `json:"metadata"` 33 | Spec ScheduledEchoSpec `json:"spec"` 34 | } 35 | 36 | func (e *ScheduledEcho) HasChanged(other *ScheduledEcho) bool { 37 | return e.Spec.Message != other.Spec.Message || e.Spec.Schedule != other.Spec.Schedule 38 | } 39 | 40 | type ScheduledEchoSpec struct { 41 | Message string `json:"message"` 42 | Schedule string `json:"schedule"` 43 | } 44 | 45 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 46 | type ScheduledEchoList struct { 47 | metav1.TypeMeta `json:",inline"` 48 | metav1.ListMeta `json:"metadata"` 49 | Items []ScheduledEcho `json:"items"` 50 | } 51 | -------------------------------------------------------------------------------- /pkg/echo/v1alpha1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | MIT License 6 | 7 | Copyright (c) 2021 Martín Montes 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | // Code generated by deepcopy-gen. DO NOT EDIT. 29 | 30 | package v1alpha1 31 | 32 | import ( 33 | runtime "k8s.io/apimachinery/pkg/runtime" 34 | ) 35 | 36 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 37 | func (in *Echo) DeepCopyInto(out *Echo) { 38 | *out = *in 39 | out.TypeMeta = in.TypeMeta 40 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 41 | out.Spec = in.Spec 42 | return 43 | } 44 | 45 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Echo. 46 | func (in *Echo) DeepCopy() *Echo { 47 | if in == nil { 48 | return nil 49 | } 50 | out := new(Echo) 51 | in.DeepCopyInto(out) 52 | return out 53 | } 54 | 55 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 56 | func (in *Echo) DeepCopyObject() runtime.Object { 57 | if c := in.DeepCopy(); c != nil { 58 | return c 59 | } 60 | return nil 61 | } 62 | 63 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 64 | func (in *EchoList) DeepCopyInto(out *EchoList) { 65 | *out = *in 66 | out.TypeMeta = in.TypeMeta 67 | in.ListMeta.DeepCopyInto(&out.ListMeta) 68 | if in.Items != nil { 69 | in, out := &in.Items, &out.Items 70 | *out = make([]Echo, len(*in)) 71 | for i := range *in { 72 | (*in)[i].DeepCopyInto(&(*out)[i]) 73 | } 74 | } 75 | return 76 | } 77 | 78 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EchoList. 79 | func (in *EchoList) DeepCopy() *EchoList { 80 | if in == nil { 81 | return nil 82 | } 83 | out := new(EchoList) 84 | in.DeepCopyInto(out) 85 | return out 86 | } 87 | 88 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 89 | func (in *EchoList) DeepCopyObject() runtime.Object { 90 | if c := in.DeepCopy(); c != nil { 91 | return c 92 | } 93 | return nil 94 | } 95 | 96 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 97 | func (in *EchoSpec) DeepCopyInto(out *EchoSpec) { 98 | *out = *in 99 | return 100 | } 101 | 102 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EchoSpec. 103 | func (in *EchoSpec) DeepCopy() *EchoSpec { 104 | if in == nil { 105 | return nil 106 | } 107 | out := new(EchoSpec) 108 | in.DeepCopyInto(out) 109 | return out 110 | } 111 | 112 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 113 | func (in *ScheduledEcho) DeepCopyInto(out *ScheduledEcho) { 114 | *out = *in 115 | out.TypeMeta = in.TypeMeta 116 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 117 | out.Spec = in.Spec 118 | return 119 | } 120 | 121 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScheduledEcho. 122 | func (in *ScheduledEcho) DeepCopy() *ScheduledEcho { 123 | if in == nil { 124 | return nil 125 | } 126 | out := new(ScheduledEcho) 127 | in.DeepCopyInto(out) 128 | return out 129 | } 130 | 131 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 132 | func (in *ScheduledEcho) DeepCopyObject() runtime.Object { 133 | if c := in.DeepCopy(); c != nil { 134 | return c 135 | } 136 | return nil 137 | } 138 | 139 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 140 | func (in *ScheduledEchoList) DeepCopyInto(out *ScheduledEchoList) { 141 | *out = *in 142 | out.TypeMeta = in.TypeMeta 143 | in.ListMeta.DeepCopyInto(&out.ListMeta) 144 | if in.Items != nil { 145 | in, out := &in.Items, &out.Items 146 | *out = make([]ScheduledEcho, len(*in)) 147 | for i := range *in { 148 | (*in)[i].DeepCopyInto(&(*out)[i]) 149 | } 150 | } 151 | return 152 | } 153 | 154 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScheduledEchoList. 155 | func (in *ScheduledEchoList) DeepCopy() *ScheduledEchoList { 156 | if in == nil { 157 | return nil 158 | } 159 | out := new(ScheduledEchoList) 160 | in.DeepCopyInto(out) 161 | return out 162 | } 163 | 164 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 165 | func (in *ScheduledEchoList) DeepCopyObject() runtime.Object { 166 | if c := in.DeepCopy(); c != nil { 167 | return c 168 | } 169 | return nil 170 | } 171 | 172 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 173 | func (in *ScheduledEchoSpec) DeepCopyInto(out *ScheduledEchoSpec) { 174 | *out = *in 175 | return 176 | } 177 | 178 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScheduledEchoSpec. 179 | func (in *ScheduledEchoSpec) DeepCopy() *ScheduledEchoSpec { 180 | if in == nil { 181 | return nil 182 | } 183 | out := new(ScheduledEchoSpec) 184 | in.DeepCopyInto(out) 185 | return out 186 | } 187 | --------------------------------------------------------------------------------