From 342eedf4a41ee2c7dada1d0372a8033de80d5e0c Mon Sep 17 00:00:00 2001 From: Marc Campbell Date: Fri, 5 Jul 2019 22:38:40 +0000 Subject: [PATCH] First commit, scaffolding --- .gitignore | 24 + Dockerfile | 17 + Makefile | 73 +++ PROJECT | 3 + cmd/manager/main.go | 84 +++ ...ubleshoot.replicated.com_analyzerjobs.yaml | 404 +++++++++++++ ...troubleshoot.replicated.com_analyzers.yaml | 404 +++++++++++++ ...bleshoot.replicated.com_collectorjobs.yaml | 404 +++++++++++++ ...roubleshoot.replicated.com_collectors.yaml | 404 +++++++++++++ ...bleshoot.replicated.com_preflightjobs.yaml | 404 +++++++++++++ ...roubleshoot.replicated.com_preflights.yaml | 404 +++++++++++++ .../crds/troubleshoot_v1beta1_analyzer.yaml | 39 ++ .../troubleshoot_v1beta1_analyzerjob.yaml | 39 ++ .../crds/troubleshoot_v1beta1_collector.yaml | 39 ++ .../troubleshoot_v1beta1_collectorjob.yaml | 39 ++ .../crds/troubleshoot_v1beta1_preflight.yaml | 39 ++ .../troubleshoot_v1beta1_preflightjob.yaml | 39 ++ config/default/kustomization.yaml | 49 ++ config/default/manager_auth_proxy_patch.yaml | 24 + config/default/manager_image_patch.yaml | 12 + .../manager_prometheus_metrics_patch.yaml | 19 + config/manager/manager.yaml | 83 +++ config/rbac/auth_proxy_role.yaml | 13 + config/rbac/auth_proxy_role_binding.yaml | 12 + config/rbac/auth_proxy_service.yaml | 20 + config/rbac/rbac_role.yaml | 283 +++++++++ config/rbac/rbac_role_binding.yaml | 13 + .../troubleshoot_v1beta1_analyzer.yaml | 9 + .../troubleshoot_v1beta1_analyzerjob.yaml | 9 + .../troubleshoot_v1beta1_collector.yaml | 9 + .../troubleshoot_v1beta1_collectorjob.yaml | 9 + .../troubleshoot_v1beta1_preflight.yaml | 9 + .../troubleshoot_v1beta1_preflightjob.yaml | 9 + config/webhook/manifests.yaml | 0 go.mod | 19 + go.sum | 464 +++++++++++++++ hack/boilerplate.go.txt | 15 + pkg/apis/addtoscheme_troubleshoot_v1beta1.go | 26 + pkg/apis/apis.go | 30 + pkg/apis/troubleshoot/group.go | 18 + .../troubleshoot/v1beta1/analyzer_types.go | 62 ++ .../v1beta1/analyzer_types_test.go | 58 ++ .../troubleshoot/v1beta1/analyzerjob_types.go | 62 ++ .../v1beta1/analyzerjob_types_test.go | 58 ++ .../troubleshoot/v1beta1/collector_types.go | 62 ++ .../v1beta1/collector_types_test.go | 58 ++ .../v1beta1/collectorjob_types.go | 62 ++ .../v1beta1/collectorjob_types_test.go | 58 ++ pkg/apis/troubleshoot/v1beta1/doc.go | 23 + .../troubleshoot/v1beta1/preflight_types.go | 62 ++ .../v1beta1/preflight_types_test.go | 58 ++ .../v1beta1/preflightjob_types.go | 62 ++ .../v1beta1/preflightjob_types_test.go | 58 ++ pkg/apis/troubleshoot/v1beta1/register.go | 46 ++ .../v1beta1/v1beta1_suite_test.go | 55 ++ .../v1beta1/zz_generated.deepcopy.go | 543 ++++++++++++++++++ pkg/client/troubleshootclientset/clientset.go | 97 ++++ pkg/client/troubleshootclientset/doc.go | 19 + .../fake/clientset_generated.go | 81 +++ pkg/client/troubleshootclientset/fake/doc.go | 19 + .../troubleshootclientset/fake/register.go | 55 ++ .../troubleshootclientset/scheme/doc.go | 19 + .../troubleshootclientset/scheme/register.go | 55 ++ .../typed/troubleshoot/v1beta1/analyzer.go | 190 ++++++ .../typed/troubleshoot/v1beta1/analyzerjob.go | 190 ++++++ .../typed/troubleshoot/v1beta1/collector.go | 190 ++++++ .../troubleshoot/v1beta1/collectorjob.go | 190 ++++++ .../typed/troubleshoot/v1beta1/doc.go | 19 + .../typed/troubleshoot/v1beta1/fake/doc.go | 19 + .../v1beta1/fake/fake_analyzer.go | 139 +++++ .../v1beta1/fake/fake_analyzerjob.go | 139 +++++ .../v1beta1/fake/fake_collector.go | 139 +++++ .../v1beta1/fake/fake_collectorjob.go | 139 +++++ .../v1beta1/fake/fake_preflight.go | 139 +++++ .../v1beta1/fake/fake_preflightjob.go | 139 +++++ .../v1beta1/fake/fake_troubleshoot_client.go | 59 ++ .../v1beta1/generated_expansion.go | 30 + .../typed/troubleshoot/v1beta1/preflight.go | 190 ++++++ .../troubleshoot/v1beta1/preflightjob.go | 190 ++++++ .../v1beta1/troubleshoot_client.go | 114 ++++ pkg/controller/add_analyzer.go | 26 + pkg/controller/add_analyzerjob.go | 26 + pkg/controller/add_collector.go | 26 + pkg/controller/add_collectorjob.go | 26 + pkg/controller/add_preflight.go | 26 + pkg/controller/add_preflightjob.go | 26 + .../analyzer/analyzer_controller.go | 167 ++++++ .../analyzer_controller_suite_test.go | 75 +++ .../analyzer/analyzer_controller_test.go | 88 +++ .../analyzerjob/analyzerjob_controller.go | 167 ++++++ .../analyzerjob_controller_suite_test.go | 75 +++ .../analyzerjob_controller_test.go | 88 +++ .../collector/collector_controller.go | 167 ++++++ .../collector_controller_suite_test.go | 75 +++ .../collector/collector_controller_test.go | 88 +++ .../collectorjob/collectorjob_controller.go | 167 ++++++ .../collectorjob_controller_suite_test.go | 75 +++ .../collectorjob_controller_test.go | 88 +++ pkg/controller/controller.go | 34 ++ .../preflight/preflight_controller.go | 167 ++++++ .../preflight_controller_suite_test.go | 75 +++ .../preflight/preflight_controller_test.go | 88 +++ .../preflightjob/preflightjob_controller.go | 167 ++++++ .../preflightjob_controller_suite_test.go | 75 +++ .../preflightjob_controller_test.go | 88 +++ pkg/webhook/webhook.go | 37 ++ 106 files changed, 10167 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 PROJECT create mode 100644 cmd/manager/main.go create mode 100644 config/crd/troubleshoot.replicated.com_analyzerjobs.yaml create mode 100644 config/crd/troubleshoot.replicated.com_analyzers.yaml create mode 100644 config/crd/troubleshoot.replicated.com_collectorjobs.yaml create mode 100644 config/crd/troubleshoot.replicated.com_collectors.yaml create mode 100644 config/crd/troubleshoot.replicated.com_preflightjobs.yaml create mode 100644 config/crd/troubleshoot.replicated.com_preflights.yaml create mode 100644 config/crds/troubleshoot_v1beta1_analyzer.yaml create mode 100644 config/crds/troubleshoot_v1beta1_analyzerjob.yaml create mode 100644 config/crds/troubleshoot_v1beta1_collector.yaml create mode 100644 config/crds/troubleshoot_v1beta1_collectorjob.yaml create mode 100644 config/crds/troubleshoot_v1beta1_preflight.yaml create mode 100644 config/crds/troubleshoot_v1beta1_preflightjob.yaml create mode 100644 config/default/kustomization.yaml create mode 100644 config/default/manager_auth_proxy_patch.yaml create mode 100644 config/default/manager_image_patch.yaml create mode 100644 config/default/manager_prometheus_metrics_patch.yaml create mode 100644 config/manager/manager.yaml create mode 100644 config/rbac/auth_proxy_role.yaml create mode 100644 config/rbac/auth_proxy_role_binding.yaml create mode 100644 config/rbac/auth_proxy_service.yaml create mode 100644 config/rbac/rbac_role.yaml create mode 100644 config/rbac/rbac_role_binding.yaml create mode 100644 config/samples/troubleshoot_v1beta1_analyzer.yaml create mode 100644 config/samples/troubleshoot_v1beta1_analyzerjob.yaml create mode 100644 config/samples/troubleshoot_v1beta1_collector.yaml create mode 100644 config/samples/troubleshoot_v1beta1_collectorjob.yaml create mode 100644 config/samples/troubleshoot_v1beta1_preflight.yaml create mode 100644 config/samples/troubleshoot_v1beta1_preflightjob.yaml create mode 100644 config/webhook/manifests.yaml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 hack/boilerplate.go.txt create mode 100644 pkg/apis/addtoscheme_troubleshoot_v1beta1.go create mode 100644 pkg/apis/apis.go create mode 100644 pkg/apis/troubleshoot/group.go create mode 100644 pkg/apis/troubleshoot/v1beta1/analyzer_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/analyzer_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/analyzerjob_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/analyzerjob_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/collector_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/collector_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/collectorjob_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/collectorjob_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/doc.go create mode 100644 pkg/apis/troubleshoot/v1beta1/preflight_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/preflight_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/preflightjob_types.go create mode 100644 pkg/apis/troubleshoot/v1beta1/preflightjob_types_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/register.go create mode 100644 pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go create mode 100644 pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go create mode 100644 pkg/client/troubleshootclientset/clientset.go create mode 100644 pkg/client/troubleshootclientset/doc.go create mode 100644 pkg/client/troubleshootclientset/fake/clientset_generated.go create mode 100644 pkg/client/troubleshootclientset/fake/doc.go create mode 100644 pkg/client/troubleshootclientset/fake/register.go create mode 100644 pkg/client/troubleshootclientset/scheme/doc.go create mode 100644 pkg/client/troubleshootclientset/scheme/register.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzer.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzerjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collector.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collectorjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/doc.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/doc.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzerjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collectorjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflightjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_troubleshoot_client.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/generated_expansion.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflight.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflightjob.go create mode 100644 pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go create mode 100644 pkg/controller/add_analyzer.go create mode 100644 pkg/controller/add_analyzerjob.go create mode 100644 pkg/controller/add_collector.go create mode 100644 pkg/controller/add_collectorjob.go create mode 100644 pkg/controller/add_preflight.go create mode 100644 pkg/controller/add_preflightjob.go create mode 100644 pkg/controller/analyzer/analyzer_controller.go create mode 100644 pkg/controller/analyzer/analyzer_controller_suite_test.go create mode 100644 pkg/controller/analyzer/analyzer_controller_test.go create mode 100644 pkg/controller/analyzerjob/analyzerjob_controller.go create mode 100644 pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go create mode 100644 pkg/controller/analyzerjob/analyzerjob_controller_test.go create mode 100644 pkg/controller/collector/collector_controller.go create mode 100644 pkg/controller/collector/collector_controller_suite_test.go create mode 100644 pkg/controller/collector/collector_controller_test.go create mode 100644 pkg/controller/collectorjob/collectorjob_controller.go create mode 100644 pkg/controller/collectorjob/collectorjob_controller_suite_test.go create mode 100644 pkg/controller/collectorjob/collectorjob_controller_test.go create mode 100644 pkg/controller/controller.go create mode 100644 pkg/controller/preflight/preflight_controller.go create mode 100644 pkg/controller/preflight/preflight_controller_suite_test.go create mode 100644 pkg/controller/preflight/preflight_controller_test.go create mode 100644 pkg/controller/preflightjob/preflightjob_controller.go create mode 100644 pkg/controller/preflightjob/preflightjob_controller_suite_test.go create mode 100644 pkg/controller/preflightjob/preflightjob_controller_test.go create mode 100644 pkg/webhook/webhook.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d97ffc51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Kubernetes Generated files - skip generated files, except for vendored files + +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1158735f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# Build the manager binary +FROM golang:1.10.3 as builder + +# Copy in the go src +WORKDIR /go/src/github.com/replicatedhq/troubleshoot +COPY pkg/ pkg/ +COPY cmd/ cmd/ +COPY vendor/ vendor/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager github.com/replicatedhq/troubleshoot/cmd/manager + +# Copy the controller-manager into a thin image +FROM ubuntu:latest +WORKDIR / +COPY --from=builder /go/src/github.com/replicatedhq/troubleshoot/manager . +ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..dcfb84b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,73 @@ + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest + +all: test manager + +# Run tests +test: generate fmt vet manifests + go test ./pkg/... ./cmd/... -coverprofile cover.out + +# Build manager binary +manager: generate fmt vet + go build -o bin/manager github.com/replicatedhq/troubleshoot/cmd/manager + +# Run against the configured Kubernetes cluster in ~/.kube/config +run: generate fmt vet + go run ./cmd/manager/main.go + +# Install CRDs into a cluster +install: manifests + kubectl apply -f config/crds + +# Deploy controller in the configured Kubernetes cluster in ~/.kube/config +deploy: manifests + kubectl apply -f config/crds + kustomize build config/default | kubectl apply -f - + +# Generate manifests e.g. CRD, RBAC etc. +manifests: controller-gen + controller-gen paths=./pkg/apis/... + +# Run go fmt against code +fmt: + go fmt ./pkg/... ./cmd/... + +# Run go vet against code +vet: + go vet ./pkg/... ./cmd/... + + +.PHONY: generate +generate: controller-gen client-gen + controller-gen object:headerFile=./hack/boilerplate.go.txt paths=./api/... + client-gen go run ../../vendor/k8s.io/code-generator/cmd/client-gen/main.go --output-package=github.com/replicatedhq/troubleshoot/pkg/client --clientset-name troubleshootclientset --input-base github.com/replicatedhq/troubleshoot/pkg/apis --input troubleshoot/v1beta1 -h ./hack/boilerplate.go.txt + +# Build the docker image +docker-build: test + docker build . -t ${IMG} + @echo "updating kustomize image patch file for manager resource" + sed -i'' -e 's@image: .*@image: '"${IMG}"'@' ./config/default/manager_image_patch.yaml + +# Push the docker image +docker-push: + docker push ${IMG} + +# find or download controller-gen +# download controller-gen if necessary +controller-gen: +ifeq (, $(shell which controller-gen)) + go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.0-beta.2 +CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen +else +CONTROLLER_GEN=$(shell which controller-gen) +endif + +# find or download client-gen +client-gen: +ifeq (, $(shell which client-gen)) + go get k8s.io/code-generator/cmd/client-gen@kubernetes-1.13.5 +CLIENT_GEN=$(shell go env GOPATH)/bin/client-gen +else +CLIENT_GEN=$(shell which client-gen) +endif diff --git a/PROJECT b/PROJECT new file mode 100644 index 00000000..1269aa39 --- /dev/null +++ b/PROJECT @@ -0,0 +1,3 @@ +version: "1" +domain: replicated.com +repo: github.com/replicatedhq/troubleshoot diff --git a/cmd/manager/main.go b/cmd/manager/main.go new file mode 100644 index 00000000..63721515 --- /dev/null +++ b/cmd/manager/main.go @@ -0,0 +1,84 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "flag" + "os" + + "github.com/replicatedhq/troubleshoot/pkg/apis" + "github.com/replicatedhq/troubleshoot/pkg/controller" + "github.com/replicatedhq/troubleshoot/pkg/webhook" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/runtime/signals" +) + +func main() { + var metricsAddr string + flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + flag.Parse() + logf.SetLogger(logf.ZapLogger(false)) + log := logf.Log.WithName("entrypoint") + + // Get a config to talk to the apiserver + log.Info("setting up client for manager") + cfg, err := config.GetConfig() + if err != nil { + log.Error(err, "unable to set up client config") + os.Exit(1) + } + + // Create a new Cmd to provide shared dependencies and start components + log.Info("setting up manager") + mgr, err := manager.New(cfg, manager.Options{MetricsBindAddress: metricsAddr}) + if err != nil { + log.Error(err, "unable to set up overall controller manager") + os.Exit(1) + } + + log.Info("Registering Components.") + + // Setup Scheme for all resources + log.Info("setting up scheme") + if err := apis.AddToScheme(mgr.GetScheme()); err != nil { + log.Error(err, "unable add APIs to scheme") + os.Exit(1) + } + + // Setup all Controllers + log.Info("Setting up controller") + if err := controller.AddToManager(mgr); err != nil { + log.Error(err, "unable to register controllers to the manager") + os.Exit(1) + } + + log.Info("setting up webhooks") + if err := webhook.AddToManager(mgr); err != nil { + log.Error(err, "unable to register webhooks to the manager") + os.Exit(1) + } + + // Start the Cmd + log.Info("Starting the Cmd.") + if err := mgr.Start(signals.SetupSignalHandler()); err != nil { + log.Error(err, "unable to run the manager") + os.Exit(1) + } +} diff --git a/config/crd/troubleshoot.replicated.com_analyzerjobs.yaml b/config/crd/troubleshoot.replicated.com_analyzerjobs.yaml new file mode 100644 index 00000000..77c85c3e --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_analyzerjobs.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: analyzerjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: AnalyzerJob + plural: analyzerjobs + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: AnalyzerJob is the Schema for the analyzerjobs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/troubleshoot.replicated.com_analyzers.yaml b/config/crd/troubleshoot.replicated.com_analyzers.yaml new file mode 100644 index 00000000..abaa32fa --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_analyzers.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: analyzers.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Analyzer + plural: analyzers + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Analyzer is the Schema for the analyzers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/troubleshoot.replicated.com_collectorjobs.yaml b/config/crd/troubleshoot.replicated.com_collectorjobs.yaml new file mode 100644 index 00000000..877a87b7 --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_collectorjobs.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: collectorjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: CollectorJob + plural: collectorjobs + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: CollectorJob is the Schema for the collectorjobs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/troubleshoot.replicated.com_collectors.yaml b/config/crd/troubleshoot.replicated.com_collectors.yaml new file mode 100644 index 00000000..439df71a --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_collectors.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: collectors.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Collector + plural: collectors + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Collector is the Schema for the collectors API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/troubleshoot.replicated.com_preflightjobs.yaml b/config/crd/troubleshoot.replicated.com_preflightjobs.yaml new file mode 100644 index 00000000..e22a213f --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_preflightjobs.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: preflightjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: PreflightJob + plural: preflightjobs + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: PreflightJob is the Schema for the preflightjobs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/troubleshoot.replicated.com_preflights.yaml b/config/crd/troubleshoot.replicated.com_preflights.yaml new file mode 100644 index 00000000..8a6e65b0 --- /dev/null +++ b/config/crd/troubleshoot.replicated.com_preflights.yaml @@ -0,0 +1,404 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: preflights.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Preflight + plural: preflights + scope: "" + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Preflight is the Schema for the preflights API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and retrieve + arbitrary metadata. They are not queryable and should be preserved + when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + clusterName: + description: The name of the cluster which the object belongs to. + This is used to distinguish resources with same name and namespace + in different clusters. This field is not set anywhere right now + and apiserver is going to ignore it if set in create or update request. + type: string + creationTimestamp: + description: "CreationTimestamp is a timestamp representing the server + time when this object was created. It is not guaranteed to be set + in happens-before order across separate operations. Clients may + not set this value. It is represented in RFC3339 form and is in + UTC. \n Populated by the system. Read-only. Null for lists. More + info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + deletionGracePeriodSeconds: + description: Number of seconds allowed for this object to gracefully + terminate before it will be removed from the system. Only set when + deletionTimestamp is also set. May only be shortened. Read-only. + format: int64 + type: integer + deletionTimestamp: + description: "DeletionTimestamp is RFC 3339 date and time at which + this resource will be deleted. This field is set by the server when + a graceful deletion is requested by the user, and is not directly + settable by a client. The resource is expected to be deleted (no + longer visible from resource lists, and not reachable by name) after + the time in this field, once the finalizers list is empty. As long + as the finalizers list contains items, deletion is blocked. Once + the deletionTimestamp is set, this value may not be unset or be + set further into the future, although it may be shortened or the + resource may be deleted prior to this time. For example, a user + may request that a pod is deleted in 30 seconds. The Kubelet will + react by sending a graceful termination signal to the containers + in the pod. After that 30 seconds, the Kubelet will send a hard + termination signal (SIGKILL) to the container and after cleanup, + remove the pod from the API. In the presence of network partitions, + this object may still exist after this timestamp, until an administrator + or automated process can determine the resource is fully terminated. + If not set, graceful deletion of the object has not been requested. + \n Populated by the system when a graceful deletion is requested. + Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata" + format: date-time + type: string + finalizers: + description: Must be empty before the object is deleted from the registry. + Each entry is an identifier for the responsible component that will + remove the entry from the list. If the deletionTimestamp of the + object is non-nil, entries in this list can only be removed. + items: + type: string + type: array + generateName: + description: "GenerateName is an optional prefix, used by the server, + to generate a unique name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique + suffix. The provided value has the same validation rules as the + Name field, and may be truncated by the length of the suffix required + to make the value unique on the server. \n If this field is specified + and the generated name exists, the server will NOT return a 409 + - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the + time allotted, and the client should retry (optionally after the + time indicated in the Retry-After header). \n Applied only if Name + is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency" + type: string + generation: + description: A sequence number representing a specific generation + of the desired state. Populated by the system. Read-only. + format: int64 + type: integer + initializers: + description: "An initializer is a controller which enforces some system + invariant at object creation time. This field is a list of initializers + that have not yet acted on this object. If nil or empty, this object + has been completely initialized. Otherwise, the object is considered + uninitialized and is hidden (in list/watch and get calls) from clients + that haven't explicitly asked to observe uninitialized objects. + \n When an object is created, the system will populate this list + with the current set of initializers. Only privileged users may + set or modify this list. Once it is empty, it may not be modified + further by any user. \n DEPRECATED - initializers are an alpha field + and will be removed in v1.15." + properties: + pending: + description: Pending is a list of initializers that must execute + in order before this object is visible. When the last pending + initializer is removed, and no failing result is set, the initializers + struct will be set to nil and the object is considered as initialized + and visible to all clients. + items: + properties: + name: + description: name of the process that is responsible for + initializing this object. + type: string + required: + - name + type: object + type: array + result: + description: If result is set with the Failure field, the object + will be persisted to storage and then deleted, ensuring that + other clients can observe the deletion. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + code: + description: Suggested HTTP return code for this status, 0 + if not set. + format: int32 + type: integer + details: + description: Extended data associated with the reason. Each + reason may define its own extended details. This field is + optional and the data returned is not guaranteed to conform + to any schema except that defined by the reason type. + properties: + causes: + description: The Causes array includes more details associated + with the StatusReason failure. Not all StatusReasons + may provide detailed causes. + items: + properties: + field: + description: "The field of the resource that has + caused this error, as named by its JSON serialization. + May include dot and postfix notation for nested + attributes. Arrays are zero-indexed. Fields may + appear more than once in an array of causes due + to fields having multiple errors. Optional. \n + Examples: \"name\" - the field \"name\" on the + current resource \"items[0].name\" - the field + \"name\" on the first array entry in \"items\"" + type: string + message: + description: A human-readable description of the + cause of the error. This field may be presented + as-is to a reader. + type: string + reason: + description: A machine-readable description of the + cause of the error. If this value is empty there + is no information available. + type: string + type: object + type: array + group: + description: The group attribute of the resource associated + with the status StatusReason. + type: string + kind: + description: 'The kind attribute of the resource associated + with the status StatusReason. On some operations may + differ from the requested resource Kind. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: The name attribute of the resource associated + with the status StatusReason (when there is a single + name which can be described). + type: string + retryAfterSeconds: + description: If specified, the time in seconds before + the operation should be retried. Some errors may indicate + the client must take an alternate action - for those + errors this field may indicate how long to wait before + taking the alternate action. + format: int32 + type: integer + uid: + description: 'UID of the resource. (when there is a single + resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + type: object + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + message: + description: A human-readable description of the status of + this operation. + type: string + metadata: + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + properties: + continue: + description: continue may be set if the user set a limit + on the number of items returned, and indicates that + the server has more data available. The value is opaque + and may be used to issue another request to the endpoint + that served this list to retrieve the next set of available + objects. Continuing a consistent list may not be possible + if the server configuration has changed or more than + a few minutes have passed. The resourceVersion field + returned when using this continue value will be identical + to the value in the first response, unless you have + received this token from an error message. + type: string + resourceVersion: + description: 'String that identifies the server''s internal + version of this object that can be used by clients to + determine when objects have changed. Value must be treated + as opaque by clients and passed unmodified back to the + server. Populated by the system. Read-only. More info: + https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency' + type: string + selfLink: + description: selfLink is a URL representing this object. + Populated by the system. Read-only. + type: string + type: object + reason: + description: A machine-readable description of why this operation + is in the "Failure" status. If this value is empty there + is no information available. A Reason clarifies an HTTP + status code but does not override it. + type: string + status: + description: 'Status of the operation. One of: "Success" or + "Failure". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status' + type: string + type: object + required: + - pending + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to organize + and categorize (scope and select) objects. May match selectors of + replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels' + type: object + managedFields: + description: "ManagedFields maps workflow-id and version to the set + of fields that are managed by that workflow. This is mostly for + internal housekeeping, and users typically shouldn't need to set + or understand this field. A workflow can be the user's name, a controller's + name, or the name of a specific apply path like \"ci-cd\". The set + of fields is always in the version that the workflow used when modifying + the object. \n This field is alpha and can be changed or removed + without notice." + items: + properties: + apiVersion: + description: APIVersion defines the version of this resource + that this field set applies to. The format is "group/version" + just like the top-level APIVersion field. It is necessary + to track the version of a field set because it cannot be automatically + converted. + type: string + fields: + additionalProperties: true + description: Fields identifies a set of fields. + type: object + manager: + description: Manager is an identifier of the workflow managing + these fields. + type: string + operation: + description: Operation is the type of operation which lead to + this ManagedFieldsEntry being created. The only valid values + for this field are 'Apply' and 'Update'. + type: string + time: + description: Time is timestamp of when these fields were set. + It should always be empty if Operation is 'Apply' + format: date-time + type: string + type: object + type: array + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a client + to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + namespace: + description: "Namespace defines the space within each name must be + unique. An empty namespace is equivalent to the \"default\" namespace, + but \"default\" is the canonical representation. Not all objects + are required to be scoped to a namespace - the value of this field + for those objects will be empty. \n Must be a DNS_LABEL. Cannot + be updated. More info: http://kubernetes.io/docs/user-guide/namespaces" + type: string + ownerReferences: + description: List of objects depended by this object. If ALL objects + in the list have been deleted, this object will be garbage collected. + If this object is managed by a controller, then an entry in this + list will point to this controller, with the controller field set + to true. There cannot be more than one managing controller. + items: + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. Defaults to false. + To set this field, a user needs "delete" permission of the + owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + type: array + resourceVersion: + description: "An opaque value that represents the internal version + of this object that can be used by clients to determine when objects + have changed. May be used for optimistic concurrency, change detection, + and the watch operation on a resource or set of resources. Clients + must treat these values as opaque and passed unmodified back to + the server. They may only be valid for a particular resource or + set of resources. \n Populated by the system. Read-only. Value must + be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency" + type: string + selfLink: + description: SelfLink is a URL representing this object. Populated + by the system. Read-only. + type: string + uid: + description: "UID is the unique in time and space value for this object. + It is typically generated by the server on successful creation of + a resource and is not allowed to change on PUT operations. \n Populated + by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids" + type: string + type: object + spec: + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_analyzer.yaml b/config/crds/troubleshoot_v1beta1_analyzer.yaml new file mode 100644 index 00000000..5838b3c6 --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_analyzer.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: analyzers.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Analyzer + plural: analyzers + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_analyzerjob.yaml b/config/crds/troubleshoot_v1beta1_analyzerjob.yaml new file mode 100644 index 00000000..854319c9 --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_analyzerjob.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: analyzerjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: AnalyzerJob + plural: analyzerjobs + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_collector.yaml b/config/crds/troubleshoot_v1beta1_collector.yaml new file mode 100644 index 00000000..027cac08 --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_collector.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: collectors.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Collector + plural: collectors + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_collectorjob.yaml b/config/crds/troubleshoot_v1beta1_collectorjob.yaml new file mode 100644 index 00000000..52cc495e --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_collectorjob.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: collectorjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: CollectorJob + plural: collectorjobs + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_preflight.yaml b/config/crds/troubleshoot_v1beta1_preflight.yaml new file mode 100644 index 00000000..0733c2bd --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_preflight.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: preflights.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: Preflight + plural: preflights + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crds/troubleshoot_v1beta1_preflightjob.yaml b/config/crds/troubleshoot_v1beta1_preflightjob.yaml new file mode 100644 index 00000000..2aa989fa --- /dev/null +++ b/config/crds/troubleshoot_v1beta1_preflightjob.yaml @@ -0,0 +1,39 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + controller-tools.k8s.io: "1.0" + name: preflightjobs.troubleshoot.replicated.com +spec: + group: troubleshoot.replicated.com + names: + kind: PreflightJob + plural: preflightjobs + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + status: + type: object + version: v1beta1 +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml new file mode 100644 index 00000000..bd82b980 --- /dev/null +++ b/config/default/kustomization.yaml @@ -0,0 +1,49 @@ +# Adds namespace to all resources. +namespace: troubleshoot-system + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: troubleshoot- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +# Each entry in this list must resolve to an existing +# resource definition in YAML. These are the resource +# files that kustomize reads, modifies and emits as a +# YAML string, with resources separated by document +# markers ("---"). +resources: +- ../rbac/rbac_role.yaml +- ../rbac/rbac_role_binding.yaml +- ../manager/manager.yaml + # Comment the following 3 lines if you want to disable + # the auth proxy (https://github.com/brancz/kube-rbac-proxy) + # which protects your /metrics endpoint. +- ../rbac/auth_proxy_service.yaml +- ../rbac/auth_proxy_role.yaml +- ../rbac/auth_proxy_role_binding.yaml + +patches: +- manager_image_patch.yaml + # Protect the /metrics endpoint by putting it behind auth. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. +- manager_auth_proxy_patch.yaml + # If you want your controller-manager to expose the /metrics + # endpoint w/o any authn/z, uncomment the following line and + # comment manager_auth_proxy_patch.yaml. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. +#- manager_prometheus_metrics_patch.yaml + +vars: +- name: WEBHOOK_SECRET_NAME + objref: + kind: Secret + name: webhook-server-secret + apiVersion: v1 diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000..cbcc6d0f --- /dev/null +++ b/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,24 @@ +# This patch inject a sidecar container which is a HTTP proxy for the controller manager, +# it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https + - name: manager + args: + - "--metrics-addr=127.0.0.1:8080" diff --git a/config/default/manager_image_patch.yaml b/config/default/manager_image_patch.yaml new file mode 100644 index 00000000..fcbf39dc --- /dev/null +++ b/config/default/manager_image_patch.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + # Change the value of image field below to your controller image URL + - image: IMAGE_URL + name: manager diff --git a/config/default/manager_prometheus_metrics_patch.yaml b/config/default/manager_prometheus_metrics_patch.yaml new file mode 100644 index 00000000..96fdcdac --- /dev/null +++ b/config/default/manager_prometheus_metrics_patch.yaml @@ -0,0 +1,19 @@ +# This patch enables Prometheus scraping for the manager pod. +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: controller-manager + namespace: system +spec: + template: + metadata: + annotations: + prometheus.io/scrape: 'true' + spec: + containers: + # Expose the prometheus metrics on default port + - name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml new file mode 100644 index 00000000..b718bb4e --- /dev/null +++ b/config/manager/manager.yaml @@ -0,0 +1,83 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" + name: system +--- +apiVersion: v1 +kind: Service +metadata: + name: controller-manager-service + namespace: system + labels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" +spec: + selector: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" + ports: + - port: 443 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" +spec: + selector: + matchLabels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" + serviceName: controller-manager-service + template: + metadata: + labels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" + spec: + containers: + - command: + - /manager + image: controller:latest + imagePullPolicy: Always + name: manager + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SECRET_NAME + value: $(WEBHOOK_SECRET_NAME) + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + ports: + - containerPort: 9876 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/cert + name: cert + readOnly: true + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-secret +--- +apiVersion: v1 +kind: Secret +metadata: + name: webhook-server-secret + namespace: system diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000..618f5e41 --- /dev/null +++ b/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000..48ed1e4b --- /dev/null +++ b/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: default + namespace: system diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000..027073f9 --- /dev/null +++ b/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/port: "8443" + prometheus.io/scheme: https + prometheus.io/scrape: "true" + labels: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager + controller-tools.k8s.io: "1.0" diff --git a/config/rbac/rbac_role.yaml b/config/rbac/rbac_role.yaml new file mode 100644 index 00000000..59518489 --- /dev/null +++ b/config/rbac/rbac_role.yaml @@ -0,0 +1,283 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - analyzers + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - analyzers/status + verbs: + - get + - update + - patch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - analyzerjobs + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - analyzerjobs/status + verbs: + - get + - update + - patch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - collectors + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - collectors/status + verbs: + - get + - update + - patch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - collectorjobs + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - collectorjobs/status + verbs: + - get + - update + - patch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - preflights + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - preflights/status + verbs: + - get + - update + - patch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - update + - patch +- apiGroups: + - troubleshoot.replicated.com + resources: + - preflightjobs + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - troubleshoot.replicated.com + resources: + - preflightjobs/status + verbs: + - get + - update + - patch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - create + - update + - patch + - delete diff --git a/config/rbac/rbac_role_binding.yaml b/config/rbac/rbac_role_binding.yaml new file mode 100644 index 00000000..c1033e23 --- /dev/null +++ b/config/rbac/rbac_role_binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + creationTimestamp: null + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: default + namespace: system diff --git a/config/samples/troubleshoot_v1beta1_analyzer.yaml b/config/samples/troubleshoot_v1beta1_analyzer.yaml new file mode 100644 index 00000000..f985de7a --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_analyzer.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: Analyzer +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: analyzer-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/troubleshoot_v1beta1_analyzerjob.yaml b/config/samples/troubleshoot_v1beta1_analyzerjob.yaml new file mode 100644 index 00000000..2cd695d0 --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_analyzerjob.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: AnalyzerJob +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: analyzerjob-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/troubleshoot_v1beta1_collector.yaml b/config/samples/troubleshoot_v1beta1_collector.yaml new file mode 100644 index 00000000..bcf9699c --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_collector.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: Collector +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: collector-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/troubleshoot_v1beta1_collectorjob.yaml b/config/samples/troubleshoot_v1beta1_collectorjob.yaml new file mode 100644 index 00000000..2e09f730 --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_collectorjob.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: CollectorJob +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: collectorjob-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/troubleshoot_v1beta1_preflight.yaml b/config/samples/troubleshoot_v1beta1_preflight.yaml new file mode 100644 index 00000000..ba9a825a --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_preflight.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: Preflight +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: preflight-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/troubleshoot_v1beta1_preflightjob.yaml b/config/samples/troubleshoot_v1beta1_preflightjob.yaml new file mode 100644 index 00000000..61f005c6 --- /dev/null +++ b/config/samples/troubleshoot_v1beta1_preflightjob.yaml @@ -0,0 +1,9 @@ +apiVersion: troubleshoot.replicated.com/v1beta1 +kind: PreflightJob +metadata: + labels: + controller-tools.k8s.io: "1.0" + name: preflightjob-sample +spec: + # Add fields here + foo: bar diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 00000000..e69de29b diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..49d4df70 --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module github.com/replicatedhq/troubleshoot + +go 1.12 + +require ( + github.com/onsi/gomega v1.5.0 + github.com/spf13/cobra v0.0.3 + github.com/spf13/viper v1.4.0 + github.com/stretchr/testify v1.3.0 + github.com/xo/dburl v0.0.0-20190203050942-98997a05b24f + golang.org/x/net v0.0.0-20190522155817-f3200d17e092 + gopkg.in/yaml.v2 v2.2.2 + k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b + k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d + k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible + sigs.k8s.io/controller-runtime v0.2.0-beta.2 + sigs.k8s.io/controller-tools v0.2.0-beta.2 // indirect + +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..64a6df0d --- /dev/null +++ b/go.sum @@ -0,0 +1,464 @@ +cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.41.0 h1:NFvqUTDnSNYPX5oReekmB+D+90jrJIcVImxQ3qrBVgM= +cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 h1:Kn3rqvbUFqSepE2OqVu0Pn1CbDw9IuMlONapol0zuwk= +github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= +github.com/appscode/jsonpatch v2.0.0+incompatible h1:DEsgcSnA7ui6pICc75uxDpyN8Bx4DLFTS8aRym702nE= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/evanphx/json-patch v4.0.0+incompatible h1:xregGRMLBeuRcwiOTHRCsPPuzCQlqhxUPbqdw+zNkLc= +github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc= +github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= +github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= +github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0= +github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47 h1:UnszMmmmm5vLwWzDjTFVIkfhvWF1NdrmChl8L2NUDCw= +github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c h1:MUyE44mTvnI5A0xrxIxaMqoWFzPfQvtE2IWUollMDMs= +github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 h1:zNBQb37RGLmJybyMcs983HfUfpkw9OTFD9tbBfAViHE= +github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/petar/GoLLRB v0.0.0-20190514000832-33fb24c13b99/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= +github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/dburl v0.0.0-20190203050942-98997a05b24f/go.mod h1:g6rdekR8vgfVZrkLWfobLTm0kVez7GAN23mWtkGCJ14= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872 h1:cGjJzUd8RgBw428LXP65YXni0aiGNA4Bl+ls8SmLOm8= +golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190501045030-23463209683d/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190703212419-2214986f1668/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.0.0-20190222213804-5cb15d344471 h1:MzQGt8qWQCR+39kbYRd0uQqsvSidpYqJLFeWiJ9l4OE= +k8s.io/api v0.0.0-20190222213804-5cb15d344471/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo= +k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.0.0-20190703205437-39734b2a72fe h1:MFaHtAyhZcfBZocN91muHSqnwiF5yfXx7yGoehneNYg= +k8s.io/api v0.0.0-20190703205437-39734b2a72fe/go.mod h1:J5EZ0KSEjvyKOBy5BDHSF3zn82madLLWg7nUKaOHZKU= +k8s.io/apiextensions-apiserver v0.0.0-20190228180357-d002e88f6236 h1:JfFtjaElBIgYKCWEtYQkcNrTpW+lMO4GJy8NP6SVQmM= +k8s.io/apiextensions-apiserver v0.0.0-20190228180357-d002e88f6236/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8 h1:q1Qvjzs/iEdXF6A1a8H3AKVFDzJNcJn3nXMs6R6qFtA= +k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= +k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 h1:UYfHH+KEF88OTg+GojQUwFTNxbxwmoktLwutUzR0GPg= +k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA= +k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.0.0-20190703205208-4cfb76a8bf76 h1:vxMYBaJgczGAIpJAOBco2eHuFYIyDdNIebt60jxLauA= +k8s.io/apimachinery v0.0.0-20190703205208-4cfb76a8bf76/go.mod h1:M2fZgZL9DbLfeJaPBCDqSqNsdsmLN+V29knYJnIXlMA= +k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4 h1:aE8wOCKuoRs2aU0OP/Rz8SXiAB0FTTku3VtGhhrkSmc= +k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= +k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible h1:U5Bt+dab9K8qaUmXINrkXO135kA11/i5Kg1RUydgaMQ= +k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b h1:KH0fUlgdFZH8UMxJ/FDCYHpczfSQKefetq5NjL6BVF0= +k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= +k8s.io/code-generator v0.0.0-20190703204957-583809a49343/go.mod h1:gZ0mjdzfPz3P+cILxibAJ25xFoZ1Kf0xQrFUHy66AEs= +k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a h1:QoHVuRquf80YZ+/bovwxoMO3Q/A3nt3yTgS0/0nejuk= +k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= +k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c= +k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c h1:3KSCztE7gPitlZmWbNwue/2U0YruD65DqX3INopDAQM= +k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30 h1:TRb4wNWoBVrH9plmkp2q86FIDppkbrEXdXlxU3a3BMI= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 h1:5sW+fEHvlJI3Ngolx30CmubFulwH28DhKjGf70Xmtco= +k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 h1:VBM/0P5TWxwk+Nw6Z+lAw3DKgO76g90ETOiA6rfLV1Y= +k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a h1:2jUDc9gJja832Ftp+QbDV0tVhQHMISFn01els+2ZAcw= +k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= +modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/controller-runtime v0.1.12 h1:ovDq28E64PeY1yR+6H7DthakIC09soiDCrKvfP2tPYo= +sigs.k8s.io/controller-runtime v0.1.12/go.mod h1:HFAYoOh6XMV+jKF1UjFwrknPbowfyHEHHRdJMf2jMX8= +sigs.k8s.io/controller-runtime v0.2.0-beta.2 h1:hOWldx1qmGI9TsU+uUsq1xTgVmUV7AZo08VAYX0dwGI= +sigs.k8s.io/controller-runtime v0.2.0-beta.2/go.mod h1:TSH2R0nSz4WAlUUlNnOFcOR/VUhfwBLlmtq2X6AiQCA= +sigs.k8s.io/controller-tools v0.1.11/go.mod h1:6g08p9m9G/So3sBc1AOQifHfhxH/mb6Sc4z0LMI8XMw= +sigs.k8s.io/controller-tools v0.2.0-beta.2/go.mod h1:gC5UAnK1jbxWnDaqTi0yxKIsRsRwshzeRtTUGbM9vos= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/testing_frameworks v0.1.1 h1:cP2l8fkA3O9vekpy5Ks8mmA0NW/F7yBdXf8brkWhVrs= +sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 00000000..7f2ede7c --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/pkg/apis/addtoscheme_troubleshoot_v1beta1.go b/pkg/apis/addtoscheme_troubleshoot_v1beta1.go new file mode 100644 index 00000000..afa9a02b --- /dev/null +++ b/pkg/apis/addtoscheme_troubleshoot_v1beta1.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apis + +import ( + "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" +) + +func init() { + // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, v1beta1.SchemeBuilder.AddToScheme) +} diff --git a/pkg/apis/apis.go b/pkg/apis/apis.go new file mode 100644 index 00000000..4480b30a --- /dev/null +++ b/pkg/apis/apis.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package apis contains Kubernetes API groups. +package apis + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// AddToSchemes may be used to add all resources defined in the project to a Scheme +var AddToSchemes runtime.SchemeBuilder + +// AddToScheme adds all Resources to the Scheme +func AddToScheme(s *runtime.Scheme) error { + return AddToSchemes.AddToScheme(s) +} diff --git a/pkg/apis/troubleshoot/group.go b/pkg/apis/troubleshoot/group.go new file mode 100644 index 00000000..be0551ca --- /dev/null +++ b/pkg/apis/troubleshoot/group.go @@ -0,0 +1,18 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package troubleshoot contains troubleshoot API versions +package troubleshoot diff --git a/pkg/apis/troubleshoot/v1beta1/analyzer_types.go b/pkg/apis/troubleshoot/v1beta1/analyzer_types.go new file mode 100644 index 00000000..ca50647d --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/analyzer_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// AnalyzerSpec defines the desired state of Analyzer +type AnalyzerSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// AnalyzerStatus defines the observed state of Analyzer +type AnalyzerStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Analyzer is the Schema for the analyzers API +// +k8s:openapi-gen=true +type Analyzer struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AnalyzerSpec `json:"spec,omitempty"` + Status AnalyzerStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AnalyzerList contains a list of Analyzer +type AnalyzerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Analyzer `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Analyzer{}, &AnalyzerList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/analyzer_types_test.go b/pkg/apis/troubleshoot/v1beta1/analyzer_types_test.go new file mode 100644 index 00000000..1253b7f1 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/analyzer_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStorageAnalyzer(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &Analyzer{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &Analyzer{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/analyzerjob_types.go b/pkg/apis/troubleshoot/v1beta1/analyzerjob_types.go new file mode 100644 index 00000000..94d33c8c --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/analyzerjob_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// AnalyzerJobSpec defines the desired state of AnalyzerJob +type AnalyzerJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// AnalyzerJobStatus defines the observed state of AnalyzerJob +type AnalyzerJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AnalyzerJob is the Schema for the analyzerjobs API +// +k8s:openapi-gen=true +type AnalyzerJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AnalyzerJobSpec `json:"spec,omitempty"` + Status AnalyzerJobStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AnalyzerJobList contains a list of AnalyzerJob +type AnalyzerJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AnalyzerJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&AnalyzerJob{}, &AnalyzerJobList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/analyzerjob_types_test.go b/pkg/apis/troubleshoot/v1beta1/analyzerjob_types_test.go new file mode 100644 index 00000000..c8dab3b7 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/analyzerjob_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStorageAnalyzerJob(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &AnalyzerJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &AnalyzerJob{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/collector_types.go b/pkg/apis/troubleshoot/v1beta1/collector_types.go new file mode 100644 index 00000000..60af6022 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/collector_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// CollectorSpec defines the desired state of Collector +type CollectorSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// CollectorStatus defines the observed state of Collector +type CollectorStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Collector is the Schema for the collectors API +// +k8s:openapi-gen=true +type Collector struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CollectorSpec `json:"spec,omitempty"` + Status CollectorStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CollectorList contains a list of Collector +type CollectorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Collector `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Collector{}, &CollectorList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/collector_types_test.go b/pkg/apis/troubleshoot/v1beta1/collector_types_test.go new file mode 100644 index 00000000..74fa235e --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/collector_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStorageCollector(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &Collector{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &Collector{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/collectorjob_types.go b/pkg/apis/troubleshoot/v1beta1/collectorjob_types.go new file mode 100644 index 00000000..0473e6cb --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/collectorjob_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// CollectorJobSpec defines the desired state of CollectorJob +type CollectorJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// CollectorJobStatus defines the observed state of CollectorJob +type CollectorJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CollectorJob is the Schema for the collectorjobs API +// +k8s:openapi-gen=true +type CollectorJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CollectorJobSpec `json:"spec,omitempty"` + Status CollectorJobStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CollectorJobList contains a list of CollectorJob +type CollectorJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []CollectorJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&CollectorJob{}, &CollectorJobList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/collectorjob_types_test.go b/pkg/apis/troubleshoot/v1beta1/collectorjob_types_test.go new file mode 100644 index 00000000..a5cde22b --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/collectorjob_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStorageCollectorJob(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &CollectorJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &CollectorJob{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/doc.go b/pkg/apis/troubleshoot/v1beta1/doc.go new file mode 100644 index 00000000..92991251 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains API Schema definitions for the troubleshoot v1beta1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot +// +k8s:defaulter-gen=TypeMeta +// +groupName=troubleshoot.replicated.com +package v1beta1 diff --git a/pkg/apis/troubleshoot/v1beta1/preflight_types.go b/pkg/apis/troubleshoot/v1beta1/preflight_types.go new file mode 100644 index 00000000..b64a2f53 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/preflight_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PreflightSpec defines the desired state of Preflight +type PreflightSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// PreflightStatus defines the observed state of Preflight +type PreflightStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Preflight is the Schema for the preflights API +// +k8s:openapi-gen=true +type Preflight struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PreflightSpec `json:"spec,omitempty"` + Status PreflightStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PreflightList contains a list of Preflight +type PreflightList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Preflight `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Preflight{}, &PreflightList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/preflight_types_test.go b/pkg/apis/troubleshoot/v1beta1/preflight_types_test.go new file mode 100644 index 00000000..45bedc0f --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/preflight_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStoragePreflight(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &Preflight{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &Preflight{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/preflightjob_types.go b/pkg/apis/troubleshoot/v1beta1/preflightjob_types.go new file mode 100644 index 00000000..fad4fcf1 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/preflightjob_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PreflightJobSpec defines the desired state of PreflightJob +type PreflightJobSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// PreflightJobStatus defines the observed state of PreflightJob +type PreflightJobStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PreflightJob is the Schema for the preflightjobs API +// +k8s:openapi-gen=true +type PreflightJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PreflightJobSpec `json:"spec,omitempty"` + Status PreflightJobStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PreflightJobList contains a list of PreflightJob +type PreflightJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PreflightJob `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PreflightJob{}, &PreflightJobList{}) +} diff --git a/pkg/apis/troubleshoot/v1beta1/preflightjob_types_test.go b/pkg/apis/troubleshoot/v1beta1/preflightjob_types_test.go new file mode 100644 index 00000000..d8bf2f60 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/preflightjob_types_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "testing" + + "github.com/onsi/gomega" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestStoragePreflightJob(t *testing.T) { + key := types.NamespacedName{ + Name: "foo", + Namespace: "default", + } + created := &PreflightJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }} + g := gomega.NewGomegaWithT(t) + + // Test Create + fetched := &PreflightJob{} + g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(created)) + + // Test Updating the Labels + updated := fetched.DeepCopy() + updated.Labels = map[string]string{"hello": "world"} + g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) + + g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(fetched).To(gomega.Equal(updated)) + + // Test Delete + g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) + g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) +} diff --git a/pkg/apis/troubleshoot/v1beta1/register.go b/pkg/apis/troubleshoot/v1beta1/register.go new file mode 100644 index 00000000..c7fa41a7 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/register.go @@ -0,0 +1,46 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// NOTE: Boilerplate only. Ignore this file. + +// Package v1beta1 contains API Schema definitions for the troubleshoot v1beta1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot +// +k8s:defaulter-gen=TypeMeta +// +groupName=troubleshoot.replicated.com +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "troubleshoot.replicated.com", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme is required by pkg/client/... + AddToScheme = SchemeBuilder.AddToScheme +) + +// Resource is required by pkg/client/listers/... +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go b/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go new file mode 100644 index 00000000..e6f04157 --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go @@ -0,0 +1,55 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "log" + "os" + "path/filepath" + "testing" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +var cfg *rest.Config +var c client.Client + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")}, + } + + err := SchemeBuilder.AddToScheme(scheme.Scheme) + if err != nil { + log.Fatal(err) + } + + if cfg, err = t.Start(); err != nil { + log.Fatal(err) + } + + if c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil { + log.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} diff --git a/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000..55d155fb --- /dev/null +++ b/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,543 @@ +// +build !ignore_autogenerated + +// autogenerated by controller-gen object, do not modify manually + +package v1beta1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Analyzer) DeepCopyInto(out *Analyzer) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Analyzer. +func (in *Analyzer) DeepCopy() *Analyzer { + if in == nil { + return nil + } + out := new(Analyzer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Analyzer) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerJob) DeepCopyInto(out *AnalyzerJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerJob. +func (in *AnalyzerJob) DeepCopy() *AnalyzerJob { + if in == nil { + return nil + } + out := new(AnalyzerJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AnalyzerJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerJobList) DeepCopyInto(out *AnalyzerJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AnalyzerJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerJobList. +func (in *AnalyzerJobList) DeepCopy() *AnalyzerJobList { + if in == nil { + return nil + } + out := new(AnalyzerJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AnalyzerJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerJobSpec) DeepCopyInto(out *AnalyzerJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerJobSpec. +func (in *AnalyzerJobSpec) DeepCopy() *AnalyzerJobSpec { + if in == nil { + return nil + } + out := new(AnalyzerJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerJobStatus) DeepCopyInto(out *AnalyzerJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerJobStatus. +func (in *AnalyzerJobStatus) DeepCopy() *AnalyzerJobStatus { + if in == nil { + return nil + } + out := new(AnalyzerJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerList) DeepCopyInto(out *AnalyzerList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Analyzer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerList. +func (in *AnalyzerList) DeepCopy() *AnalyzerList { + if in == nil { + return nil + } + out := new(AnalyzerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AnalyzerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerSpec) DeepCopyInto(out *AnalyzerSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerSpec. +func (in *AnalyzerSpec) DeepCopy() *AnalyzerSpec { + if in == nil { + return nil + } + out := new(AnalyzerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyzerStatus) DeepCopyInto(out *AnalyzerStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyzerStatus. +func (in *AnalyzerStatus) DeepCopy() *AnalyzerStatus { + if in == nil { + return nil + } + out := new(AnalyzerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Collector) DeepCopyInto(out *Collector) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Collector. +func (in *Collector) DeepCopy() *Collector { + if in == nil { + return nil + } + out := new(Collector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Collector) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorJob) DeepCopyInto(out *CollectorJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorJob. +func (in *CollectorJob) DeepCopy() *CollectorJob { + if in == nil { + return nil + } + out := new(CollectorJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CollectorJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorJobList) DeepCopyInto(out *CollectorJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CollectorJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorJobList. +func (in *CollectorJobList) DeepCopy() *CollectorJobList { + if in == nil { + return nil + } + out := new(CollectorJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CollectorJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorJobSpec) DeepCopyInto(out *CollectorJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorJobSpec. +func (in *CollectorJobSpec) DeepCopy() *CollectorJobSpec { + if in == nil { + return nil + } + out := new(CollectorJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorJobStatus) DeepCopyInto(out *CollectorJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorJobStatus. +func (in *CollectorJobStatus) DeepCopy() *CollectorJobStatus { + if in == nil { + return nil + } + out := new(CollectorJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorList) DeepCopyInto(out *CollectorList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Collector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorList. +func (in *CollectorList) DeepCopy() *CollectorList { + if in == nil { + return nil + } + out := new(CollectorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CollectorList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorSpec) DeepCopyInto(out *CollectorSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorSpec. +func (in *CollectorSpec) DeepCopy() *CollectorSpec { + if in == nil { + return nil + } + out := new(CollectorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CollectorStatus) DeepCopyInto(out *CollectorStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectorStatus. +func (in *CollectorStatus) DeepCopy() *CollectorStatus { + if in == nil { + return nil + } + out := new(CollectorStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Preflight) DeepCopyInto(out *Preflight) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Preflight. +func (in *Preflight) DeepCopy() *Preflight { + if in == nil { + return nil + } + out := new(Preflight) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Preflight) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightJob) DeepCopyInto(out *PreflightJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightJob. +func (in *PreflightJob) DeepCopy() *PreflightJob { + if in == nil { + return nil + } + out := new(PreflightJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PreflightJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightJobList) DeepCopyInto(out *PreflightJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PreflightJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightJobList. +func (in *PreflightJobList) DeepCopy() *PreflightJobList { + if in == nil { + return nil + } + out := new(PreflightJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PreflightJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightJobSpec) DeepCopyInto(out *PreflightJobSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightJobSpec. +func (in *PreflightJobSpec) DeepCopy() *PreflightJobSpec { + if in == nil { + return nil + } + out := new(PreflightJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightJobStatus) DeepCopyInto(out *PreflightJobStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightJobStatus. +func (in *PreflightJobStatus) DeepCopy() *PreflightJobStatus { + if in == nil { + return nil + } + out := new(PreflightJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightList) DeepCopyInto(out *PreflightList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Preflight, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightList. +func (in *PreflightList) DeepCopy() *PreflightList { + if in == nil { + return nil + } + out := new(PreflightList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PreflightList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightSpec) DeepCopyInto(out *PreflightSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightSpec. +func (in *PreflightSpec) DeepCopy() *PreflightSpec { + if in == nil { + return nil + } + out := new(PreflightSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreflightStatus) DeepCopyInto(out *PreflightStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreflightStatus. +func (in *PreflightStatus) DeepCopy() *PreflightStatus { + if in == nil { + return nil + } + out := new(PreflightStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/client/troubleshootclientset/clientset.go b/pkg/client/troubleshootclientset/clientset.go new file mode 100644 index 00000000..3c99b6c4 --- /dev/null +++ b/pkg/client/troubleshootclientset/clientset.go @@ -0,0 +1,97 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package troubleshootclientset + +import ( + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface + // Deprecated: please explicitly pick a version if possible. + Troubleshoot() troubleshootv1beta1.TroubleshootV1beta1Interface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + troubleshootV1beta1 *troubleshootv1beta1.TroubleshootV1beta1Client +} + +// TroubleshootV1beta1 retrieves the TroubleshootV1beta1Client +func (c *Clientset) TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface { + return c.troubleshootV1beta1 +} + +// Deprecated: Troubleshoot retrieves the default version of TroubleshootClient. +// Please explicitly pick a version. +func (c *Clientset) Troubleshoot() troubleshootv1beta1.TroubleshootV1beta1Interface { + return c.troubleshootV1beta1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + var cs Clientset + var err error + cs.troubleshootV1beta1, err = troubleshootv1beta1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + var cs Clientset + cs.troubleshootV1beta1 = troubleshootv1beta1.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.troubleshootV1beta1 = troubleshootv1beta1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/pkg/client/troubleshootclientset/doc.go b/pkg/client/troubleshootclientset/doc.go new file mode 100644 index 00000000..05559a44 --- /dev/null +++ b/pkg/client/troubleshootclientset/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package troubleshootclientset diff --git a/pkg/client/troubleshootclientset/fake/clientset_generated.go b/pkg/client/troubleshootclientset/fake/clientset_generated.go new file mode 100644 index 00000000..827b2a60 --- /dev/null +++ b/pkg/client/troubleshootclientset/fake/clientset_generated.go @@ -0,0 +1,81 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + clientset "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" + faketroubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +var _ clientset.Interface = &Clientset{} + +// TroubleshootV1beta1 retrieves the TroubleshootV1beta1Client +func (c *Clientset) TroubleshootV1beta1() troubleshootv1beta1.TroubleshootV1beta1Interface { + return &faketroubleshootv1beta1.FakeTroubleshootV1beta1{Fake: &c.Fake} +} + +// Troubleshoot retrieves the TroubleshootV1beta1Client +func (c *Clientset) Troubleshoot() troubleshootv1beta1.TroubleshootV1beta1Interface { + return &faketroubleshootv1beta1.FakeTroubleshootV1beta1{Fake: &c.Fake} +} diff --git a/pkg/client/troubleshootclientset/fake/doc.go b/pkg/client/troubleshootclientset/fake/doc.go new file mode 100644 index 00000000..51266d80 --- /dev/null +++ b/pkg/client/troubleshootclientset/fake/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/pkg/client/troubleshootclientset/fake/register.go b/pkg/client/troubleshootclientset/fake/register.go new file mode 100644 index 00000000..71731ac9 --- /dev/null +++ b/pkg/client/troubleshootclientset/fake/register.go @@ -0,0 +1,55 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) +var parameterCodec = runtime.NewParameterCodec(scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + troubleshootv1beta1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/pkg/client/troubleshootclientset/scheme/doc.go b/pkg/client/troubleshootclientset/scheme/doc.go new file mode 100644 index 00000000..37f640ec --- /dev/null +++ b/pkg/client/troubleshootclientset/scheme/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/pkg/client/troubleshootclientset/scheme/register.go b/pkg/client/troubleshootclientset/scheme/register.go new file mode 100644 index 00000000..55051e56 --- /dev/null +++ b/pkg/client/troubleshootclientset/scheme/register.go @@ -0,0 +1,55 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + troubleshootv1beta1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzer.go new file mode 100644 index 00000000..2950c600 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzer.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// AnalyzersGetter has a method to return a AnalyzerInterface. +// A group's client should implement this interface. +type AnalyzersGetter interface { + Analyzers(namespace string) AnalyzerInterface +} + +// AnalyzerInterface has methods to work with Analyzer resources. +type AnalyzerInterface interface { + Create(*v1beta1.Analyzer) (*v1beta1.Analyzer, error) + Update(*v1beta1.Analyzer) (*v1beta1.Analyzer, error) + UpdateStatus(*v1beta1.Analyzer) (*v1beta1.Analyzer, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.Analyzer, error) + List(opts v1.ListOptions) (*v1beta1.AnalyzerList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Analyzer, err error) + AnalyzerExpansion +} + +// analyzers implements AnalyzerInterface +type analyzers struct { + client rest.Interface + ns string +} + +// newAnalyzers returns a Analyzers +func newAnalyzers(c *TroubleshootV1beta1Client, namespace string) *analyzers { + return &analyzers{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the analyzer, and returns the corresponding analyzer object, and an error if there is any. +func (c *analyzers) Get(name string, options v1.GetOptions) (result *v1beta1.Analyzer, err error) { + result = &v1beta1.Analyzer{} + err = c.client.Get(). + Namespace(c.ns). + Resource("analyzers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Analyzers that match those selectors. +func (c *analyzers) List(opts v1.ListOptions) (result *v1beta1.AnalyzerList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.AnalyzerList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("analyzers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested analyzers. +func (c *analyzers) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("analyzers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a analyzer and creates it. Returns the server's representation of the analyzer, and an error, if there is any. +func (c *analyzers) Create(analyzer *v1beta1.Analyzer) (result *v1beta1.Analyzer, err error) { + result = &v1beta1.Analyzer{} + err = c.client.Post(). + Namespace(c.ns). + Resource("analyzers"). + Body(analyzer). + Do(). + Into(result) + return +} + +// Update takes the representation of a analyzer and updates it. Returns the server's representation of the analyzer, and an error, if there is any. +func (c *analyzers) Update(analyzer *v1beta1.Analyzer) (result *v1beta1.Analyzer, err error) { + result = &v1beta1.Analyzer{} + err = c.client.Put(). + Namespace(c.ns). + Resource("analyzers"). + Name(analyzer.Name). + Body(analyzer). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *analyzers) UpdateStatus(analyzer *v1beta1.Analyzer) (result *v1beta1.Analyzer, err error) { + result = &v1beta1.Analyzer{} + err = c.client.Put(). + Namespace(c.ns). + Resource("analyzers"). + Name(analyzer.Name). + SubResource("status"). + Body(analyzer). + Do(). + Into(result) + return +} + +// Delete takes name of the analyzer and deletes it. Returns an error if one occurs. +func (c *analyzers) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("analyzers"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *analyzers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("analyzers"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched analyzer. +func (c *analyzers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Analyzer, err error) { + result = &v1beta1.Analyzer{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("analyzers"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzerjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzerjob.go new file mode 100644 index 00000000..10726b7b --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/analyzerjob.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// AnalyzerJobsGetter has a method to return a AnalyzerJobInterface. +// A group's client should implement this interface. +type AnalyzerJobsGetter interface { + AnalyzerJobs(namespace string) AnalyzerJobInterface +} + +// AnalyzerJobInterface has methods to work with AnalyzerJob resources. +type AnalyzerJobInterface interface { + Create(*v1beta1.AnalyzerJob) (*v1beta1.AnalyzerJob, error) + Update(*v1beta1.AnalyzerJob) (*v1beta1.AnalyzerJob, error) + UpdateStatus(*v1beta1.AnalyzerJob) (*v1beta1.AnalyzerJob, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.AnalyzerJob, error) + List(opts v1.ListOptions) (*v1beta1.AnalyzerJobList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.AnalyzerJob, err error) + AnalyzerJobExpansion +} + +// analyzerJobs implements AnalyzerJobInterface +type analyzerJobs struct { + client rest.Interface + ns string +} + +// newAnalyzerJobs returns a AnalyzerJobs +func newAnalyzerJobs(c *TroubleshootV1beta1Client, namespace string) *analyzerJobs { + return &analyzerJobs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the analyzerJob, and returns the corresponding analyzerJob object, and an error if there is any. +func (c *analyzerJobs) Get(name string, options v1.GetOptions) (result *v1beta1.AnalyzerJob, err error) { + result = &v1beta1.AnalyzerJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("analyzerjobs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of AnalyzerJobs that match those selectors. +func (c *analyzerJobs) List(opts v1.ListOptions) (result *v1beta1.AnalyzerJobList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.AnalyzerJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("analyzerjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested analyzerJobs. +func (c *analyzerJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("analyzerjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a analyzerJob and creates it. Returns the server's representation of the analyzerJob, and an error, if there is any. +func (c *analyzerJobs) Create(analyzerJob *v1beta1.AnalyzerJob) (result *v1beta1.AnalyzerJob, err error) { + result = &v1beta1.AnalyzerJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("analyzerjobs"). + Body(analyzerJob). + Do(). + Into(result) + return +} + +// Update takes the representation of a analyzerJob and updates it. Returns the server's representation of the analyzerJob, and an error, if there is any. +func (c *analyzerJobs) Update(analyzerJob *v1beta1.AnalyzerJob) (result *v1beta1.AnalyzerJob, err error) { + result = &v1beta1.AnalyzerJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("analyzerjobs"). + Name(analyzerJob.Name). + Body(analyzerJob). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *analyzerJobs) UpdateStatus(analyzerJob *v1beta1.AnalyzerJob) (result *v1beta1.AnalyzerJob, err error) { + result = &v1beta1.AnalyzerJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("analyzerjobs"). + Name(analyzerJob.Name). + SubResource("status"). + Body(analyzerJob). + Do(). + Into(result) + return +} + +// Delete takes name of the analyzerJob and deletes it. Returns an error if one occurs. +func (c *analyzerJobs) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("analyzerjobs"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *analyzerJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("analyzerjobs"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched analyzerJob. +func (c *analyzerJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.AnalyzerJob, err error) { + result = &v1beta1.AnalyzerJob{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("analyzerjobs"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collector.go new file mode 100644 index 00000000..a36ed680 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collector.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CollectorsGetter has a method to return a CollectorInterface. +// A group's client should implement this interface. +type CollectorsGetter interface { + Collectors(namespace string) CollectorInterface +} + +// CollectorInterface has methods to work with Collector resources. +type CollectorInterface interface { + Create(*v1beta1.Collector) (*v1beta1.Collector, error) + Update(*v1beta1.Collector) (*v1beta1.Collector, error) + UpdateStatus(*v1beta1.Collector) (*v1beta1.Collector, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.Collector, error) + List(opts v1.ListOptions) (*v1beta1.CollectorList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Collector, err error) + CollectorExpansion +} + +// collectors implements CollectorInterface +type collectors struct { + client rest.Interface + ns string +} + +// newCollectors returns a Collectors +func newCollectors(c *TroubleshootV1beta1Client, namespace string) *collectors { + return &collectors{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the collector, and returns the corresponding collector object, and an error if there is any. +func (c *collectors) Get(name string, options v1.GetOptions) (result *v1beta1.Collector, err error) { + result = &v1beta1.Collector{} + err = c.client.Get(). + Namespace(c.ns). + Resource("collectors"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Collectors that match those selectors. +func (c *collectors) List(opts v1.ListOptions) (result *v1beta1.CollectorList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.CollectorList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("collectors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested collectors. +func (c *collectors) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("collectors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a collector and creates it. Returns the server's representation of the collector, and an error, if there is any. +func (c *collectors) Create(collector *v1beta1.Collector) (result *v1beta1.Collector, err error) { + result = &v1beta1.Collector{} + err = c.client.Post(). + Namespace(c.ns). + Resource("collectors"). + Body(collector). + Do(). + Into(result) + return +} + +// Update takes the representation of a collector and updates it. Returns the server's representation of the collector, and an error, if there is any. +func (c *collectors) Update(collector *v1beta1.Collector) (result *v1beta1.Collector, err error) { + result = &v1beta1.Collector{} + err = c.client.Put(). + Namespace(c.ns). + Resource("collectors"). + Name(collector.Name). + Body(collector). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *collectors) UpdateStatus(collector *v1beta1.Collector) (result *v1beta1.Collector, err error) { + result = &v1beta1.Collector{} + err = c.client.Put(). + Namespace(c.ns). + Resource("collectors"). + Name(collector.Name). + SubResource("status"). + Body(collector). + Do(). + Into(result) + return +} + +// Delete takes name of the collector and deletes it. Returns an error if one occurs. +func (c *collectors) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("collectors"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *collectors) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("collectors"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched collector. +func (c *collectors) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Collector, err error) { + result = &v1beta1.Collector{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("collectors"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collectorjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collectorjob.go new file mode 100644 index 00000000..8f8b9c89 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/collectorjob.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CollectorJobsGetter has a method to return a CollectorJobInterface. +// A group's client should implement this interface. +type CollectorJobsGetter interface { + CollectorJobs(namespace string) CollectorJobInterface +} + +// CollectorJobInterface has methods to work with CollectorJob resources. +type CollectorJobInterface interface { + Create(*v1beta1.CollectorJob) (*v1beta1.CollectorJob, error) + Update(*v1beta1.CollectorJob) (*v1beta1.CollectorJob, error) + UpdateStatus(*v1beta1.CollectorJob) (*v1beta1.CollectorJob, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.CollectorJob, error) + List(opts v1.ListOptions) (*v1beta1.CollectorJobList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CollectorJob, err error) + CollectorJobExpansion +} + +// collectorJobs implements CollectorJobInterface +type collectorJobs struct { + client rest.Interface + ns string +} + +// newCollectorJobs returns a CollectorJobs +func newCollectorJobs(c *TroubleshootV1beta1Client, namespace string) *collectorJobs { + return &collectorJobs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the collectorJob, and returns the corresponding collectorJob object, and an error if there is any. +func (c *collectorJobs) Get(name string, options v1.GetOptions) (result *v1beta1.CollectorJob, err error) { + result = &v1beta1.CollectorJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("collectorjobs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CollectorJobs that match those selectors. +func (c *collectorJobs) List(opts v1.ListOptions) (result *v1beta1.CollectorJobList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.CollectorJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("collectorjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested collectorJobs. +func (c *collectorJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("collectorjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a collectorJob and creates it. Returns the server's representation of the collectorJob, and an error, if there is any. +func (c *collectorJobs) Create(collectorJob *v1beta1.CollectorJob) (result *v1beta1.CollectorJob, err error) { + result = &v1beta1.CollectorJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("collectorjobs"). + Body(collectorJob). + Do(). + Into(result) + return +} + +// Update takes the representation of a collectorJob and updates it. Returns the server's representation of the collectorJob, and an error, if there is any. +func (c *collectorJobs) Update(collectorJob *v1beta1.CollectorJob) (result *v1beta1.CollectorJob, err error) { + result = &v1beta1.CollectorJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("collectorjobs"). + Name(collectorJob.Name). + Body(collectorJob). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *collectorJobs) UpdateStatus(collectorJob *v1beta1.CollectorJob) (result *v1beta1.CollectorJob, err error) { + result = &v1beta1.CollectorJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("collectorjobs"). + Name(collectorJob.Name). + SubResource("status"). + Body(collectorJob). + Do(). + Into(result) + return +} + +// Delete takes name of the collectorJob and deletes it. Returns an error if one occurs. +func (c *collectorJobs) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("collectorjobs"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *collectorJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("collectorjobs"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched collectorJob. +func (c *collectorJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CollectorJob, err error) { + result = &v1beta1.CollectorJob{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("collectorjobs"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/doc.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/doc.go new file mode 100644 index 00000000..e189fb14 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/doc.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/doc.go new file mode 100644 index 00000000..0767328a --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go new file mode 100644 index 00000000..9d640515 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzer.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeAnalyzers implements AnalyzerInterface +type FakeAnalyzers struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var analyzersResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "analyzers"} + +var analyzersKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Analyzer"} + +// Get takes name of the analyzer, and returns the corresponding analyzer object, and an error if there is any. +func (c *FakeAnalyzers) Get(name string, options v1.GetOptions) (result *v1beta1.Analyzer, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Analyzer), err +} + +// List takes label and field selectors, and returns the list of Analyzers that match those selectors. +func (c *FakeAnalyzers) List(opts v1.ListOptions) (result *v1beta1.AnalyzerList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(analyzersResource, analyzersKind, c.ns, opts), &v1beta1.AnalyzerList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.AnalyzerList{ListMeta: obj.(*v1beta1.AnalyzerList).ListMeta} + for _, item := range obj.(*v1beta1.AnalyzerList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested analyzers. +func (c *FakeAnalyzers) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(analyzersResource, c.ns, opts)) + +} + +// Create takes the representation of a analyzer and creates it. Returns the server's representation of the analyzer, and an error, if there is any. +func (c *FakeAnalyzers) Create(analyzer *v1beta1.Analyzer) (result *v1beta1.Analyzer, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(analyzersResource, c.ns, analyzer), &v1beta1.Analyzer{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Analyzer), err +} + +// Update takes the representation of a analyzer and updates it. Returns the server's representation of the analyzer, and an error, if there is any. +func (c *FakeAnalyzers) Update(analyzer *v1beta1.Analyzer) (result *v1beta1.Analyzer, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(analyzersResource, c.ns, analyzer), &v1beta1.Analyzer{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Analyzer), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeAnalyzers) UpdateStatus(analyzer *v1beta1.Analyzer) (*v1beta1.Analyzer, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(analyzersResource, "status", c.ns, analyzer), &v1beta1.Analyzer{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Analyzer), err +} + +// Delete takes name of the analyzer and deletes it. Returns an error if one occurs. +func (c *FakeAnalyzers) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(analyzersResource, c.ns, name), &v1beta1.Analyzer{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAnalyzers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(analyzersResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.AnalyzerList{}) + return err +} + +// Patch applies the patch and returns the patched analyzer. +func (c *FakeAnalyzers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Analyzer, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(analyzersResource, c.ns, name, pt, data, subresources...), &v1beta1.Analyzer{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Analyzer), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzerjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzerjob.go new file mode 100644 index 00000000..8d7391d2 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_analyzerjob.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeAnalyzerJobs implements AnalyzerJobInterface +type FakeAnalyzerJobs struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var analyzerjobsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "analyzerjobs"} + +var analyzerjobsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "AnalyzerJob"} + +// Get takes name of the analyzerJob, and returns the corresponding analyzerJob object, and an error if there is any. +func (c *FakeAnalyzerJobs) Get(name string, options v1.GetOptions) (result *v1beta1.AnalyzerJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(analyzerjobsResource, c.ns, name), &v1beta1.AnalyzerJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.AnalyzerJob), err +} + +// List takes label and field selectors, and returns the list of AnalyzerJobs that match those selectors. +func (c *FakeAnalyzerJobs) List(opts v1.ListOptions) (result *v1beta1.AnalyzerJobList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(analyzerjobsResource, analyzerjobsKind, c.ns, opts), &v1beta1.AnalyzerJobList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.AnalyzerJobList{ListMeta: obj.(*v1beta1.AnalyzerJobList).ListMeta} + for _, item := range obj.(*v1beta1.AnalyzerJobList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested analyzerJobs. +func (c *FakeAnalyzerJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(analyzerjobsResource, c.ns, opts)) + +} + +// Create takes the representation of a analyzerJob and creates it. Returns the server's representation of the analyzerJob, and an error, if there is any. +func (c *FakeAnalyzerJobs) Create(analyzerJob *v1beta1.AnalyzerJob) (result *v1beta1.AnalyzerJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(analyzerjobsResource, c.ns, analyzerJob), &v1beta1.AnalyzerJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.AnalyzerJob), err +} + +// Update takes the representation of a analyzerJob and updates it. Returns the server's representation of the analyzerJob, and an error, if there is any. +func (c *FakeAnalyzerJobs) Update(analyzerJob *v1beta1.AnalyzerJob) (result *v1beta1.AnalyzerJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(analyzerjobsResource, c.ns, analyzerJob), &v1beta1.AnalyzerJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.AnalyzerJob), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeAnalyzerJobs) UpdateStatus(analyzerJob *v1beta1.AnalyzerJob) (*v1beta1.AnalyzerJob, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(analyzerjobsResource, "status", c.ns, analyzerJob), &v1beta1.AnalyzerJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.AnalyzerJob), err +} + +// Delete takes name of the analyzerJob and deletes it. Returns an error if one occurs. +func (c *FakeAnalyzerJobs) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(analyzerjobsResource, c.ns, name), &v1beta1.AnalyzerJob{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeAnalyzerJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(analyzerjobsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.AnalyzerJobList{}) + return err +} + +// Patch applies the patch and returns the patched analyzerJob. +func (c *FakeAnalyzerJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.AnalyzerJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(analyzerjobsResource, c.ns, name, pt, data, subresources...), &v1beta1.AnalyzerJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.AnalyzerJob), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go new file mode 100644 index 00000000..adabd949 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collector.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCollectors implements CollectorInterface +type FakeCollectors struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var collectorsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "collectors"} + +var collectorsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Collector"} + +// Get takes name of the collector, and returns the corresponding collector object, and an error if there is any. +func (c *FakeCollectors) Get(name string, options v1.GetOptions) (result *v1beta1.Collector, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(collectorsResource, c.ns, name), &v1beta1.Collector{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Collector), err +} + +// List takes label and field selectors, and returns the list of Collectors that match those selectors. +func (c *FakeCollectors) List(opts v1.ListOptions) (result *v1beta1.CollectorList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(collectorsResource, collectorsKind, c.ns, opts), &v1beta1.CollectorList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.CollectorList{ListMeta: obj.(*v1beta1.CollectorList).ListMeta} + for _, item := range obj.(*v1beta1.CollectorList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested collectors. +func (c *FakeCollectors) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(collectorsResource, c.ns, opts)) + +} + +// Create takes the representation of a collector and creates it. Returns the server's representation of the collector, and an error, if there is any. +func (c *FakeCollectors) Create(collector *v1beta1.Collector) (result *v1beta1.Collector, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(collectorsResource, c.ns, collector), &v1beta1.Collector{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Collector), err +} + +// Update takes the representation of a collector and updates it. Returns the server's representation of the collector, and an error, if there is any. +func (c *FakeCollectors) Update(collector *v1beta1.Collector) (result *v1beta1.Collector, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(collectorsResource, c.ns, collector), &v1beta1.Collector{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Collector), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeCollectors) UpdateStatus(collector *v1beta1.Collector) (*v1beta1.Collector, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(collectorsResource, "status", c.ns, collector), &v1beta1.Collector{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Collector), err +} + +// Delete takes name of the collector and deletes it. Returns an error if one occurs. +func (c *FakeCollectors) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(collectorsResource, c.ns, name), &v1beta1.Collector{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCollectors) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(collectorsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.CollectorList{}) + return err +} + +// Patch applies the patch and returns the patched collector. +func (c *FakeCollectors) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Collector, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(collectorsResource, c.ns, name, pt, data, subresources...), &v1beta1.Collector{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Collector), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collectorjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collectorjob.go new file mode 100644 index 00000000..3266242b --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_collectorjob.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCollectorJobs implements CollectorJobInterface +type FakeCollectorJobs struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var collectorjobsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "collectorjobs"} + +var collectorjobsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "CollectorJob"} + +// Get takes name of the collectorJob, and returns the corresponding collectorJob object, and an error if there is any. +func (c *FakeCollectorJobs) Get(name string, options v1.GetOptions) (result *v1beta1.CollectorJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(collectorjobsResource, c.ns, name), &v1beta1.CollectorJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.CollectorJob), err +} + +// List takes label and field selectors, and returns the list of CollectorJobs that match those selectors. +func (c *FakeCollectorJobs) List(opts v1.ListOptions) (result *v1beta1.CollectorJobList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(collectorjobsResource, collectorjobsKind, c.ns, opts), &v1beta1.CollectorJobList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.CollectorJobList{ListMeta: obj.(*v1beta1.CollectorJobList).ListMeta} + for _, item := range obj.(*v1beta1.CollectorJobList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested collectorJobs. +func (c *FakeCollectorJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(collectorjobsResource, c.ns, opts)) + +} + +// Create takes the representation of a collectorJob and creates it. Returns the server's representation of the collectorJob, and an error, if there is any. +func (c *FakeCollectorJobs) Create(collectorJob *v1beta1.CollectorJob) (result *v1beta1.CollectorJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(collectorjobsResource, c.ns, collectorJob), &v1beta1.CollectorJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.CollectorJob), err +} + +// Update takes the representation of a collectorJob and updates it. Returns the server's representation of the collectorJob, and an error, if there is any. +func (c *FakeCollectorJobs) Update(collectorJob *v1beta1.CollectorJob) (result *v1beta1.CollectorJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(collectorjobsResource, c.ns, collectorJob), &v1beta1.CollectorJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.CollectorJob), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeCollectorJobs) UpdateStatus(collectorJob *v1beta1.CollectorJob) (*v1beta1.CollectorJob, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(collectorjobsResource, "status", c.ns, collectorJob), &v1beta1.CollectorJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.CollectorJob), err +} + +// Delete takes name of the collectorJob and deletes it. Returns an error if one occurs. +func (c *FakeCollectorJobs) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(collectorjobsResource, c.ns, name), &v1beta1.CollectorJob{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCollectorJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(collectorjobsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.CollectorJobList{}) + return err +} + +// Patch applies the patch and returns the patched collectorJob. +func (c *FakeCollectorJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CollectorJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(collectorjobsResource, c.ns, name, pt, data, subresources...), &v1beta1.CollectorJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.CollectorJob), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go new file mode 100644 index 00000000..8f7147c2 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflight.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePreflights implements PreflightInterface +type FakePreflights struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var preflightsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "preflights"} + +var preflightsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "Preflight"} + +// Get takes name of the preflight, and returns the corresponding preflight object, and an error if there is any. +func (c *FakePreflights) Get(name string, options v1.GetOptions) (result *v1beta1.Preflight, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(preflightsResource, c.ns, name), &v1beta1.Preflight{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Preflight), err +} + +// List takes label and field selectors, and returns the list of Preflights that match those selectors. +func (c *FakePreflights) List(opts v1.ListOptions) (result *v1beta1.PreflightList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(preflightsResource, preflightsKind, c.ns, opts), &v1beta1.PreflightList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.PreflightList{ListMeta: obj.(*v1beta1.PreflightList).ListMeta} + for _, item := range obj.(*v1beta1.PreflightList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested preflights. +func (c *FakePreflights) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(preflightsResource, c.ns, opts)) + +} + +// Create takes the representation of a preflight and creates it. Returns the server's representation of the preflight, and an error, if there is any. +func (c *FakePreflights) Create(preflight *v1beta1.Preflight) (result *v1beta1.Preflight, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(preflightsResource, c.ns, preflight), &v1beta1.Preflight{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Preflight), err +} + +// Update takes the representation of a preflight and updates it. Returns the server's representation of the preflight, and an error, if there is any. +func (c *FakePreflights) Update(preflight *v1beta1.Preflight) (result *v1beta1.Preflight, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(preflightsResource, c.ns, preflight), &v1beta1.Preflight{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Preflight), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakePreflights) UpdateStatus(preflight *v1beta1.Preflight) (*v1beta1.Preflight, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(preflightsResource, "status", c.ns, preflight), &v1beta1.Preflight{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Preflight), err +} + +// Delete takes name of the preflight and deletes it. Returns an error if one occurs. +func (c *FakePreflights) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(preflightsResource, c.ns, name), &v1beta1.Preflight{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePreflights) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(preflightsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.PreflightList{}) + return err +} + +// Patch applies the patch and returns the patched preflight. +func (c *FakePreflights) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Preflight, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(preflightsResource, c.ns, name, pt, data, subresources...), &v1beta1.Preflight{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Preflight), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflightjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflightjob.go new file mode 100644 index 00000000..f0a8910e --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_preflightjob.go @@ -0,0 +1,139 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePreflightJobs implements PreflightJobInterface +type FakePreflightJobs struct { + Fake *FakeTroubleshootV1beta1 + ns string +} + +var preflightjobsResource = schema.GroupVersionResource{Group: "troubleshoot.replicated.com", Version: "v1beta1", Resource: "preflightjobs"} + +var preflightjobsKind = schema.GroupVersionKind{Group: "troubleshoot.replicated.com", Version: "v1beta1", Kind: "PreflightJob"} + +// Get takes name of the preflightJob, and returns the corresponding preflightJob object, and an error if there is any. +func (c *FakePreflightJobs) Get(name string, options v1.GetOptions) (result *v1beta1.PreflightJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(preflightjobsResource, c.ns, name), &v1beta1.PreflightJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.PreflightJob), err +} + +// List takes label and field selectors, and returns the list of PreflightJobs that match those selectors. +func (c *FakePreflightJobs) List(opts v1.ListOptions) (result *v1beta1.PreflightJobList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(preflightjobsResource, preflightjobsKind, c.ns, opts), &v1beta1.PreflightJobList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.PreflightJobList{ListMeta: obj.(*v1beta1.PreflightJobList).ListMeta} + for _, item := range obj.(*v1beta1.PreflightJobList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested preflightJobs. +func (c *FakePreflightJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(preflightjobsResource, c.ns, opts)) + +} + +// Create takes the representation of a preflightJob and creates it. Returns the server's representation of the preflightJob, and an error, if there is any. +func (c *FakePreflightJobs) Create(preflightJob *v1beta1.PreflightJob) (result *v1beta1.PreflightJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(preflightjobsResource, c.ns, preflightJob), &v1beta1.PreflightJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.PreflightJob), err +} + +// Update takes the representation of a preflightJob and updates it. Returns the server's representation of the preflightJob, and an error, if there is any. +func (c *FakePreflightJobs) Update(preflightJob *v1beta1.PreflightJob) (result *v1beta1.PreflightJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(preflightjobsResource, c.ns, preflightJob), &v1beta1.PreflightJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.PreflightJob), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakePreflightJobs) UpdateStatus(preflightJob *v1beta1.PreflightJob) (*v1beta1.PreflightJob, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(preflightjobsResource, "status", c.ns, preflightJob), &v1beta1.PreflightJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.PreflightJob), err +} + +// Delete takes name of the preflightJob and deletes it. Returns an error if one occurs. +func (c *FakePreflightJobs) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(preflightjobsResource, c.ns, name), &v1beta1.PreflightJob{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePreflightJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(preflightjobsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1beta1.PreflightJobList{}) + return err +} + +// Patch applies the patch and returns the patched preflightJob. +func (c *FakePreflightJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.PreflightJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(preflightjobsResource, c.ns, name, pt, data, subresources...), &v1beta1.PreflightJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.PreflightJob), err +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_troubleshoot_client.go new file mode 100644 index 00000000..2cf59a9b --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/fake/fake_troubleshoot_client.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeTroubleshootV1beta1 struct { + *testing.Fake +} + +func (c *FakeTroubleshootV1beta1) Analyzers(namespace string) v1beta1.AnalyzerInterface { + return &FakeAnalyzers{c, namespace} +} + +func (c *FakeTroubleshootV1beta1) AnalyzerJobs(namespace string) v1beta1.AnalyzerJobInterface { + return &FakeAnalyzerJobs{c, namespace} +} + +func (c *FakeTroubleshootV1beta1) Collectors(namespace string) v1beta1.CollectorInterface { + return &FakeCollectors{c, namespace} +} + +func (c *FakeTroubleshootV1beta1) CollectorJobs(namespace string) v1beta1.CollectorJobInterface { + return &FakeCollectorJobs{c, namespace} +} + +func (c *FakeTroubleshootV1beta1) Preflights(namespace string) v1beta1.PreflightInterface { + return &FakePreflights{c, namespace} +} + +func (c *FakeTroubleshootV1beta1) PreflightJobs(namespace string) v1beta1.PreflightJobInterface { + return &FakePreflightJobs{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeTroubleshootV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/generated_expansion.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/generated_expansion.go new file mode 100644 index 00000000..a9cfba8e --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/generated_expansion.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type AnalyzerExpansion interface{} + +type AnalyzerJobExpansion interface{} + +type CollectorExpansion interface{} + +type CollectorJobExpansion interface{} + +type PreflightExpansion interface{} + +type PreflightJobExpansion interface{} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflight.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflight.go new file mode 100644 index 00000000..6bc85f13 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflight.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// PreflightsGetter has a method to return a PreflightInterface. +// A group's client should implement this interface. +type PreflightsGetter interface { + Preflights(namespace string) PreflightInterface +} + +// PreflightInterface has methods to work with Preflight resources. +type PreflightInterface interface { + Create(*v1beta1.Preflight) (*v1beta1.Preflight, error) + Update(*v1beta1.Preflight) (*v1beta1.Preflight, error) + UpdateStatus(*v1beta1.Preflight) (*v1beta1.Preflight, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.Preflight, error) + List(opts v1.ListOptions) (*v1beta1.PreflightList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Preflight, err error) + PreflightExpansion +} + +// preflights implements PreflightInterface +type preflights struct { + client rest.Interface + ns string +} + +// newPreflights returns a Preflights +func newPreflights(c *TroubleshootV1beta1Client, namespace string) *preflights { + return &preflights{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the preflight, and returns the corresponding preflight object, and an error if there is any. +func (c *preflights) Get(name string, options v1.GetOptions) (result *v1beta1.Preflight, err error) { + result = &v1beta1.Preflight{} + err = c.client.Get(). + Namespace(c.ns). + Resource("preflights"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Preflights that match those selectors. +func (c *preflights) List(opts v1.ListOptions) (result *v1beta1.PreflightList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.PreflightList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("preflights"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested preflights. +func (c *preflights) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("preflights"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a preflight and creates it. Returns the server's representation of the preflight, and an error, if there is any. +func (c *preflights) Create(preflight *v1beta1.Preflight) (result *v1beta1.Preflight, err error) { + result = &v1beta1.Preflight{} + err = c.client.Post(). + Namespace(c.ns). + Resource("preflights"). + Body(preflight). + Do(). + Into(result) + return +} + +// Update takes the representation of a preflight and updates it. Returns the server's representation of the preflight, and an error, if there is any. +func (c *preflights) Update(preflight *v1beta1.Preflight) (result *v1beta1.Preflight, err error) { + result = &v1beta1.Preflight{} + err = c.client.Put(). + Namespace(c.ns). + Resource("preflights"). + Name(preflight.Name). + Body(preflight). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *preflights) UpdateStatus(preflight *v1beta1.Preflight) (result *v1beta1.Preflight, err error) { + result = &v1beta1.Preflight{} + err = c.client.Put(). + Namespace(c.ns). + Resource("preflights"). + Name(preflight.Name). + SubResource("status"). + Body(preflight). + Do(). + Into(result) + return +} + +// Delete takes name of the preflight and deletes it. Returns an error if one occurs. +func (c *preflights) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("preflights"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *preflights) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("preflights"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched preflight. +func (c *preflights) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Preflight, err error) { + result = &v1beta1.Preflight{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("preflights"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflightjob.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflightjob.go new file mode 100644 index 00000000..fa1391cd --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/preflightjob.go @@ -0,0 +1,190 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "time" + + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + scheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// PreflightJobsGetter has a method to return a PreflightJobInterface. +// A group's client should implement this interface. +type PreflightJobsGetter interface { + PreflightJobs(namespace string) PreflightJobInterface +} + +// PreflightJobInterface has methods to work with PreflightJob resources. +type PreflightJobInterface interface { + Create(*v1beta1.PreflightJob) (*v1beta1.PreflightJob, error) + Update(*v1beta1.PreflightJob) (*v1beta1.PreflightJob, error) + UpdateStatus(*v1beta1.PreflightJob) (*v1beta1.PreflightJob, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1beta1.PreflightJob, error) + List(opts v1.ListOptions) (*v1beta1.PreflightJobList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.PreflightJob, err error) + PreflightJobExpansion +} + +// preflightJobs implements PreflightJobInterface +type preflightJobs struct { + client rest.Interface + ns string +} + +// newPreflightJobs returns a PreflightJobs +func newPreflightJobs(c *TroubleshootV1beta1Client, namespace string) *preflightJobs { + return &preflightJobs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the preflightJob, and returns the corresponding preflightJob object, and an error if there is any. +func (c *preflightJobs) Get(name string, options v1.GetOptions) (result *v1beta1.PreflightJob, err error) { + result = &v1beta1.PreflightJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("preflightjobs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PreflightJobs that match those selectors. +func (c *preflightJobs) List(opts v1.ListOptions) (result *v1beta1.PreflightJobList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.PreflightJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("preflightjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested preflightJobs. +func (c *preflightJobs) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("preflightjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a preflightJob and creates it. Returns the server's representation of the preflightJob, and an error, if there is any. +func (c *preflightJobs) Create(preflightJob *v1beta1.PreflightJob) (result *v1beta1.PreflightJob, err error) { + result = &v1beta1.PreflightJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("preflightjobs"). + Body(preflightJob). + Do(). + Into(result) + return +} + +// Update takes the representation of a preflightJob and updates it. Returns the server's representation of the preflightJob, and an error, if there is any. +func (c *preflightJobs) Update(preflightJob *v1beta1.PreflightJob) (result *v1beta1.PreflightJob, err error) { + result = &v1beta1.PreflightJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("preflightjobs"). + Name(preflightJob.Name). + Body(preflightJob). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *preflightJobs) UpdateStatus(preflightJob *v1beta1.PreflightJob) (result *v1beta1.PreflightJob, err error) { + result = &v1beta1.PreflightJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("preflightjobs"). + Name(preflightJob.Name). + SubResource("status"). + Body(preflightJob). + Do(). + Into(result) + return +} + +// Delete takes name of the preflightJob and deletes it. Returns an error if one occurs. +func (c *preflightJobs) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("preflightjobs"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *preflightJobs) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("preflightjobs"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched preflightJob. +func (c *preflightJobs) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.PreflightJob, err error) { + result = &v1beta1.PreflightJob{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("preflightjobs"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go new file mode 100644 index 00000000..f867c627 --- /dev/null +++ b/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1/troubleshoot_client.go @@ -0,0 +1,114 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + rest "k8s.io/client-go/rest" +) + +type TroubleshootV1beta1Interface interface { + RESTClient() rest.Interface + AnalyzersGetter + AnalyzerJobsGetter + CollectorsGetter + CollectorJobsGetter + PreflightsGetter + PreflightJobsGetter +} + +// TroubleshootV1beta1Client is used to interact with features provided by the troubleshoot.replicated.com group. +type TroubleshootV1beta1Client struct { + restClient rest.Interface +} + +func (c *TroubleshootV1beta1Client) Analyzers(namespace string) AnalyzerInterface { + return newAnalyzers(c, namespace) +} + +func (c *TroubleshootV1beta1Client) AnalyzerJobs(namespace string) AnalyzerJobInterface { + return newAnalyzerJobs(c, namespace) +} + +func (c *TroubleshootV1beta1Client) Collectors(namespace string) CollectorInterface { + return newCollectors(c, namespace) +} + +func (c *TroubleshootV1beta1Client) CollectorJobs(namespace string) CollectorJobInterface { + return newCollectorJobs(c, namespace) +} + +func (c *TroubleshootV1beta1Client) Preflights(namespace string) PreflightInterface { + return newPreflights(c, namespace) +} + +func (c *TroubleshootV1beta1Client) PreflightJobs(namespace string) PreflightJobInterface { + return newPreflightJobs(c, namespace) +} + +// NewForConfig creates a new TroubleshootV1beta1Client for the given config. +func NewForConfig(c *rest.Config) (*TroubleshootV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &TroubleshootV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new TroubleshootV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *TroubleshootV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new TroubleshootV1beta1Client for the given RESTClient. +func New(c rest.Interface) *TroubleshootV1beta1Client { + return &TroubleshootV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *TroubleshootV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/controller/add_analyzer.go b/pkg/controller/add_analyzer.go new file mode 100644 index 00000000..1436ac21 --- /dev/null +++ b/pkg/controller/add_analyzer.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/analyzer" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, analyzer.Add) +} diff --git a/pkg/controller/add_analyzerjob.go b/pkg/controller/add_analyzerjob.go new file mode 100644 index 00000000..4477a7cd --- /dev/null +++ b/pkg/controller/add_analyzerjob.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/analyzerjob" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, analyzerjob.Add) +} diff --git a/pkg/controller/add_collector.go b/pkg/controller/add_collector.go new file mode 100644 index 00000000..f959119d --- /dev/null +++ b/pkg/controller/add_collector.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/collector" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, collector.Add) +} diff --git a/pkg/controller/add_collectorjob.go b/pkg/controller/add_collectorjob.go new file mode 100644 index 00000000..f10e583b --- /dev/null +++ b/pkg/controller/add_collectorjob.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/collectorjob" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, collectorjob.Add) +} diff --git a/pkg/controller/add_preflight.go b/pkg/controller/add_preflight.go new file mode 100644 index 00000000..d1f3c5fe --- /dev/null +++ b/pkg/controller/add_preflight.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/preflight" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, preflight.Add) +} diff --git a/pkg/controller/add_preflightjob.go b/pkg/controller/add_preflightjob.go new file mode 100644 index 00000000..558954d2 --- /dev/null +++ b/pkg/controller/add_preflightjob.go @@ -0,0 +1,26 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/replicatedhq/troubleshoot/pkg/controller/preflightjob" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, preflightjob.Add) +} diff --git a/pkg/controller/analyzer/analyzer_controller.go b/pkg/controller/analyzer/analyzer_controller.go new file mode 100644 index 00000000..308686e8 --- /dev/null +++ b/pkg/controller/analyzer/analyzer_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzer + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new Analyzer Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileAnalyzer{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("analyzer-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to Analyzer + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Analyzer{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by Analyzer - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.Analyzer{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcileAnalyzer{} + +// ReconcileAnalyzer reconciles a Analyzer object +type ReconcileAnalyzer struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a Analyzer object and makes changes based on the state read +// and what is in the Analyzer.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzers,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzers/status,verbs=get;update;patch +func (r *ReconcileAnalyzer) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the Analyzer instance + instance := &troubleshootv1beta1.Analyzer{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/analyzer/analyzer_controller_suite_test.go b/pkg/controller/analyzer/analyzer_controller_suite_test.go new file mode 100644 index 00000000..251ba346 --- /dev/null +++ b/pkg/controller/analyzer/analyzer_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzer + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/analyzer/analyzer_controller_test.go b/pkg/controller/analyzer/analyzer_controller_test.go new file mode 100644 index 00000000..460b7316 --- /dev/null +++ b/pkg/controller/analyzer/analyzer_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzer + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.Analyzer{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the Analyzer object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller.go b/pkg/controller/analyzerjob/analyzerjob_controller.go new file mode 100644 index 00000000..33121b2f --- /dev/null +++ b/pkg/controller/analyzerjob/analyzerjob_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzerjob + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new AnalyzerJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileAnalyzerJob{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("analyzerjob-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to AnalyzerJob + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.AnalyzerJob{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by AnalyzerJob - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.AnalyzerJob{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcileAnalyzerJob{} + +// ReconcileAnalyzerJob reconciles a AnalyzerJob object +type ReconcileAnalyzerJob struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a AnalyzerJob object and makes changes based on the state read +// and what is in the AnalyzerJob.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzerjobs,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzerjobs/status,verbs=get;update;patch +func (r *ReconcileAnalyzerJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the AnalyzerJob instance + instance := &troubleshootv1beta1.AnalyzerJob{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go b/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go new file mode 100644 index 00000000..2b921fd4 --- /dev/null +++ b/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzerjob + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller_test.go b/pkg/controller/analyzerjob/analyzerjob_controller_test.go new file mode 100644 index 00000000..07fce367 --- /dev/null +++ b/pkg/controller/analyzerjob/analyzerjob_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package analyzerjob + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.AnalyzerJob{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the AnalyzerJob object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/controller/collector/collector_controller.go b/pkg/controller/collector/collector_controller.go new file mode 100644 index 00000000..6588d32e --- /dev/null +++ b/pkg/controller/collector/collector_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collector + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new Collector Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileCollector{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("collector-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to Collector + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Collector{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by Collector - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.Collector{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcileCollector{} + +// ReconcileCollector reconciles a Collector object +type ReconcileCollector struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a Collector object and makes changes based on the state read +// and what is in the Collector.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectors,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectors/status,verbs=get;update;patch +func (r *ReconcileCollector) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the Collector instance + instance := &troubleshootv1beta1.Collector{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/collector/collector_controller_suite_test.go b/pkg/controller/collector/collector_controller_suite_test.go new file mode 100644 index 00000000..57bb98a1 --- /dev/null +++ b/pkg/controller/collector/collector_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collector + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/collector/collector_controller_test.go b/pkg/controller/collector/collector_controller_test.go new file mode 100644 index 00000000..c2cff6f6 --- /dev/null +++ b/pkg/controller/collector/collector_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collector + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.Collector{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the Collector object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/controller/collectorjob/collectorjob_controller.go b/pkg/controller/collectorjob/collectorjob_controller.go new file mode 100644 index 00000000..0f2b4406 --- /dev/null +++ b/pkg/controller/collectorjob/collectorjob_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collectorjob + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new CollectorJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileCollectorJob{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("collectorjob-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to CollectorJob + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.CollectorJob{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by CollectorJob - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.CollectorJob{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcileCollectorJob{} + +// ReconcileCollectorJob reconciles a CollectorJob object +type ReconcileCollectorJob struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a CollectorJob object and makes changes based on the state read +// and what is in the CollectorJob.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectorjobs,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectorjobs/status,verbs=get;update;patch +func (r *ReconcileCollectorJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the CollectorJob instance + instance := &troubleshootv1beta1.CollectorJob{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/collectorjob/collectorjob_controller_suite_test.go b/pkg/controller/collectorjob/collectorjob_controller_suite_test.go new file mode 100644 index 00000000..bce58ed9 --- /dev/null +++ b/pkg/controller/collectorjob/collectorjob_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collectorjob + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/collectorjob/collectorjob_controller_test.go b/pkg/controller/collectorjob/collectorjob_controller_test.go new file mode 100644 index 00000000..5069b440 --- /dev/null +++ b/pkg/controller/collectorjob/collectorjob_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package collectorjob + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.CollectorJob{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the CollectorJob object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go new file mode 100644 index 00000000..c884eca9 --- /dev/null +++ b/pkg/controller/controller.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +// AddToManagerFuncs is a list of functions to add all Controllers to the Manager +var AddToManagerFuncs []func(manager.Manager) error + +// AddToManager adds all Controllers to the Manager +func AddToManager(m manager.Manager) error { + for _, f := range AddToManagerFuncs { + if err := f(m); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/preflight/preflight_controller.go b/pkg/controller/preflight/preflight_controller.go new file mode 100644 index 00000000..cc775c41 --- /dev/null +++ b/pkg/controller/preflight/preflight_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflight + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new Preflight Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcilePreflight{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("preflight-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to Preflight + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Preflight{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by Preflight - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.Preflight{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcilePreflight{} + +// ReconcilePreflight reconciles a Preflight object +type ReconcilePreflight struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a Preflight object and makes changes based on the state read +// and what is in the Preflight.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflights,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflights/status,verbs=get;update;patch +func (r *ReconcilePreflight) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the Preflight instance + instance := &troubleshootv1beta1.Preflight{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/preflight/preflight_controller_suite_test.go b/pkg/controller/preflight/preflight_controller_suite_test.go new file mode 100644 index 00000000..7b81e6b5 --- /dev/null +++ b/pkg/controller/preflight/preflight_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflight + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/preflight/preflight_controller_test.go b/pkg/controller/preflight/preflight_controller_test.go new file mode 100644 index 00000000..5eba378e --- /dev/null +++ b/pkg/controller/preflight/preflight_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflight + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.Preflight{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the Preflight object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/controller/preflightjob/preflightjob_controller.go b/pkg/controller/preflightjob/preflightjob_controller.go new file mode 100644 index 00000000..d68b6f85 --- /dev/null +++ b/pkg/controller/preflightjob/preflightjob_controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflightjob + +import ( + "context" + "reflect" + + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/controller-runtime/pkg/source" +) + +var log = logf.Log.WithName("controller") + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new PreflightJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcilePreflightJob{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("preflightjob-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to PreflightJob + err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.PreflightJob{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by PreflightJob - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &troubleshootv1beta1.PreflightJob{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcilePreflightJob{} + +// ReconcilePreflightJob reconciles a PreflightJob object +type ReconcilePreflightJob struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a PreflightJob object and makes changes based on the state read +// and what is in the PreflightJob.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// Automatically generate RBAC rules to allow the Controller to read and write Deployments +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflightjobs,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflightjobs/status,verbs=get;update;patch +func (r *ReconcilePreflightJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the PreflightJob instance + instance := &troubleshootv1beta1.PreflightJob{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // TODO(user): Change this to be the object type created by your controller + // Define the desired Deployment object + deploy := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-deployment", + Namespace: instance.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "nginx", + Image: "nginx", + }, + }, + }, + }, + }, + } + if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Check if the Deployment already exists + found := &appsv1.Deployment{} + err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Create(context.TODO(), deploy) + return reconcile.Result{}, err + } else if err != nil { + return reconcile.Result{}, err + } + + // TODO(user): Change this for the object type created by your controller + // Update the found object and write the result back if there are any changes + if !reflect.DeepEqual(deploy.Spec, found.Spec) { + found.Spec = deploy.Spec + log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) + err = r.Update(context.TODO(), found) + if err != nil { + return reconcile.Result{}, err + } + } + return reconcile.Result{}, nil +} diff --git a/pkg/controller/preflightjob/preflightjob_controller_suite_test.go b/pkg/controller/preflightjob/preflightjob_controller_suite_test.go new file mode 100644 index 00000000..f86f6179 --- /dev/null +++ b/pkg/controller/preflightjob/preflightjob_controller_suite_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflightjob + +import ( + stdlog "log" + "os" + "path/filepath" + "sync" + "testing" + + "github.com/onsi/gomega" + "github.com/replicatedhq/troubleshoot/pkg/apis" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var cfg *rest.Config + +func TestMain(m *testing.M) { + t := &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, + } + apis.AddToScheme(scheme.Scheme) + + var err error + if cfg, err = t.Start(); err != nil { + stdlog.Fatal(err) + } + + code := m.Run() + t.Stop() + os.Exit(code) +} + +// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and +// writes the request to requests after Reconcile is finished. +func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { + requests := make(chan reconcile.Request) + fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { + result, err := inner.Reconcile(req) + requests <- req + return result, err + }) + return fn, requests +} + +// StartTestManager adds recFn +func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { + stop := make(chan struct{}) + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) + }() + return stop, wg +} diff --git a/pkg/controller/preflightjob/preflightjob_controller_test.go b/pkg/controller/preflightjob/preflightjob_controller_test.go new file mode 100644 index 00000000..310c57dd --- /dev/null +++ b/pkg/controller/preflightjob/preflightjob_controller_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package preflightjob + +import ( + "testing" + "time" + + "github.com/onsi/gomega" + troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var c client.Client + +var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} +var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} + +const timeout = time.Second * 5 + +func TestReconcile(t *testing.T) { + g := gomega.NewGomegaWithT(t) + instance := &troubleshootv1beta1.PreflightJob{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} + + // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a + // channel when it is finished. + mgr, err := manager.New(cfg, manager.Options{}) + g.Expect(err).NotTo(gomega.HaveOccurred()) + c = mgr.GetClient() + + recFn, requests := SetupTestReconcile(newReconciler(mgr)) + g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + + stopMgr, mgrStopped := StartTestManager(mgr, g) + + defer func() { + close(stopMgr) + mgrStopped.Wait() + }() + + // Create the PreflightJob object and expect the Reconcile and Deployment to be created + err = c.Create(context.TODO(), instance) + // The instance object may not be a valid object because it might be missing some required fields. + // Please modify the instance object by adding required fields and then remove the following if statement. + if apierrors.IsInvalid(err) { + t.Logf("failed to create object, got an invalid object error: %v", err) + return + } + g.Expect(err).NotTo(gomega.HaveOccurred()) + defer c.Delete(context.TODO(), instance) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + + deploy := &appsv1.Deployment{} + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Delete the Deployment and expect Reconcile to be called for Deployment deletion + g.Expect(c.Delete(context.TODO(), deploy)).NotTo(gomega.HaveOccurred()) + g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) + g.Eventually(func() error { return c.Get(context.TODO(), depKey, deploy) }, timeout). + Should(gomega.Succeed()) + + // Manually delete Deployment since GC isn't enabled in the test control plane + g.Eventually(func() error { return c.Delete(context.TODO(), deploy) }, timeout). + Should(gomega.MatchError("deployments.apps \"foo-deployment\" not found")) + +} diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go new file mode 100644 index 00000000..296b3f66 --- /dev/null +++ b/pkg/webhook/webhook.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 Replicated, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package webhook + +import ( + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +// AddToManagerFuncs is a list of functions to add all Controllers to the Manager +var AddToManagerFuncs []func(manager.Manager) error + +// AddToManager adds all Controllers to the Manager +// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations;validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete +func AddToManager(m manager.Manager) error { + for _, f := range AddToManagerFuncs { + if err := f(m); err != nil { + return err + } + } + return nil +}