diff --git a/.github/workflows/nexus-operator-integration-checks.yml b/.github/workflows/nexus-operator-integration-checks.yaml similarity index 52% rename from .github/workflows/nexus-operator-integration-checks.yml rename to .github/workflows/nexus-operator-integration-checks.yaml index aaf013f4..99593197 100644 --- a/.github/workflows/nexus-operator-integration-checks.yml +++ b/.github/workflows/nexus-operator-integration-checks.yaml @@ -12,7 +12,7 @@ on: branches: - main env: - OPERATOR_SDK_VERSION: v0.18.1 + OPERATOR_SDK_VERSION: v1.0.1 GO_VERSION: 1.14 jobs: golint: @@ -31,11 +31,10 @@ jobs: with: go-version: ${{ env.GO_VERSION }} id: go - - name: Install Operator-sdk - run: ./hack/ci/install-operator-sdk.sh - name: Check Vet run: | - ./hack/go-vet.sh + make generate + make manifests changed_files=$(git status -s | grep -v 'go.mod\|go.sum' || :) generated_changed_files=$(git status -s | grep zz_generated || :) [[ -z "$generated_changed_files" ]] || (printf "There is change in auto-generated files" && exit 1) @@ -60,108 +59,93 @@ jobs: uses: actions/checkout@v2 - name: Cache dependencies - uses: actions/cache@v1 + uses: actions/cache@v2 with: path: ~/go/pkg/mod/cache key: ${{ runner.os }}-go-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go-cache- + - name: Cache Operator SDK + uses: actions/cache@v2 + with: + path: ${{ env.GOPATH }}/bin/operator-sdk + key: ${{ runner.os }}-sdk-cache-${{ env.OPERATOR_SDK_VERSION }} + restore-keys: | + ${{ runner.os }}-sdk-cache + - name: Install Operator SDK + run: ./hack/ci/install-operator-sdk.sh + - name: Mod Tidy run: | go mod tidy - - name: FMT - run: gofmt -s -l -w cmd/ pkg/ version/ - - - name: Vet - run: go vet ./... - + - name: Cache testenv + uses: actions/cache@v2 + with: + path: ${{ env.PATH }}/nexus-operator/testbin + key: ${{ runner.os }}-testbin-${{ env.OPERATOR_SDK_VERSION }} + restore-keys: | + ${{ runner.os }}-testbin-${{ env.OPERATOR_SDK_VERSION }} - name: Test Packages - run: go test ./pkg/... -count=1 -coverprofile=coverage.txt -covermode=atomic + run: make test - name: Validate codcov yaml file run: curl -vvv --data-binary @codecov.yml https://codecov.io/validate - name: Send Coverage Report uses: codecov/codecov-action@v1 with: - file: ./coverage.txt + file: ./cover.out flags: operator name: operator-test fail_ci_if_error: true integration_tests: - name: Integration Tests - # we should wait for an ok from the other two - needs: [golint, unit_test] - runs-on: ubuntu-latest - env: - CLUSTER_NAME: operator-test - KIND_VERSION: v0.8.1 - CREATE_NAMESPACE: false - NAMESPACE_E2E: default - steps: - - name: Check out code - uses: actions/checkout@v2 - - name: Set up Go ${{ env.GO_VERSION }} - uses: actions/setup-go@v2 - with: - go-version: ${{ env.GO_VERSION }} - id: go - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod/cache - key: ${{ runner.os }}-go-cache-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-cache- - - - name: Cache Binaries - uses: actions/cache@v1 - with: - path: ~/go/bin/ - key: ${{ runner.os }}-go-${{ env.GO_VERSION }} - restore-keys: | - ${{ runner.os }}-go-${{ env.GO_VERSION }} - - - name: Install Operator SDK - run: | - ./hack/ci/install-operator-sdk.sh - - - name: Install KIND - run: | - ./hack/ci/install-kind.sh - echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - - - name: Start KIND - run: ./hack/ci/start-kind.sh - - - name: Generate Manifests - run: ./hack/generate-manifests.sh - - - name: Build Operator Image - env: - BUILDER: docker - CUSTOM_BASE_IMAGE: alpine:latest - run: | - ./hack/go-build.sh - - - name: Load Operator Image - run: ./hack/ci/load-operator-image.sh - - - name: Run e2e test - env: - RUN_WITH_IMAGE: true - TIMEOUT_E2E: 30m - ADDITIONAL_FLAGS: "-coverprofile=coverage_e2e.txt -covermode=atomic" - run: ./hack/run-e2e-test.sh - - - name: Send Coverage Report - uses: codecov/codecov-action@v1 - with: - file: ./coverage_e2e.txt - flags: operator-e2e - name: operator-e2e-test - fail_ci_if_error: false - - - name: Run Operator OLM Integration Test - run: ./hack/ci/operator-olm-test.sh + name: Integration Tests + # we should wait for an ok from the other two + needs: [golint, unit_test] + runs-on: ubuntu-latest + env: + CLUSTER_NAME: operator-test + KIND_VERSION: v0.8.1 + CREATE_NAMESPACE: false + NAMESPACE_E2E: default + steps: + - name: Check out code + uses: actions/checkout@v2 + - name: Set up Go ${{ env.GO_VERSION }} + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + id: go + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod/cache + key: ${{ runner.os }}-go-cache-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-cache- + - name: Cache Binaries + uses: actions/cache@v2 + with: + path: ~/go/bin/ + key: ${{ runner.os }}-go-${{ env.GO_VERSION }} + restore-keys: | + ${{ runner.os }}-go-${{ env.GO_VERSION }} + - name: Install Operator SDK + run: | + ./hack/ci/install-operator-sdk.sh + - name: Install KIND + run: | + ./hack/ci/install-kind.sh + echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH + - name: Start KIND + run: ./hack/ci/start-kind.sh + + - name: Generate Manifests + run: make bundle + + - name: Build Operator Image + run: make operator-build BUILDER=docker + + - name: Run Operator OLM Integration Test + run: make ci-olm-test diff --git a/.gitignore b/.gitignore index bcffaab8..35c6d6f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,88 +1,30 @@ -*.bak -# Temporary Build Files -build/_output -build/_test +testbin/* +# built binary +nexus-operator -# logs -*.log +build +.vscode -# bin tools addition -bin/ - -# Created by https://www.gitignore.io/api/go,vim,emacs,visualstudiocode -### Emacs ### -# -*- mode: gitignore; -*- -*~ -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -*.elc -auto-save-list -tramp -.\#* -# Org-mode -.org-id-locations -*_archive -# flymake-mode -*_flymake.* -# eshell files -/eshell/history -/eshell/lastdir -# elpa packages -/elpa/ -# reftex files -*.rel -# AUCTeX auto folder -/auto/ -# cask packages -.cask/ -dist/ -# Flycheck -flycheck_*.el -# server auth directory -/server/ -# projectiles files -.projectile -projectile-bookmarks.eld -# directory configuration -.dir-locals.el -# saveplace -places -# url cache -url/cache/ -# cedet -ede-projects.el -# smex -smex-items -# company-statistics -company-statistics-cache.el -# anaconda-mode -anaconda-mode/ -### Go ### # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib -# Test binary, build with 'go test -c' +bin + +# Test binary, build with `go test -c` *.test + # Output of the go coverage tool, specifically when used with LiteIDE *.out -### Vim ### -# swap -.sw[a-p] -.*.sw[a-p] -# session -Session.vim -# temporary -.netrwhist -# auto-generated tag files -tags -### VisualStudioCode ### -.vscode/* -.history -# End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode -vendor +# Kubernetes Generated files - skip generated files, except for vendored files + +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia .idea +*.swp +*.swo +*~ diff --git a/.osdk-scorecard.yaml b/.osdk-scorecard.yaml deleted file mode 100644 index 46302e2e..00000000 --- a/.osdk-scorecard.yaml +++ /dev/null @@ -1,11 +0,0 @@ -scorecard: - # Setting a global scorecard option - output: text - plugins: - - basic: - cr-manifest: - - "deploy/crds/apps.m88i.io_v1alpha1_nexus_cr.yaml" - - olm: - cr-manifest: - - "deploy/crds/apps.m88i.io_v1alpha1_nexus_cr.yaml" - csv-path: "deploy/olm-catalog/nexus-operator/0.3.0/nexus-operator.v0.3.0.clusterserviceversion.yaml" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..0bc19a14 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +# Build the manager binary +FROM golang:1.14 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ +COPY pkg/ pkg/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go + +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest +WORKDIR / +COPY --from=builder /workspace/manager . +USER 1001 + +ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index 0a4e7fc0..d4cca470 100644 --- a/Makefile +++ b/Makefile @@ -1,73 +1,153 @@ -# kernel-style V=1 build verbosity -ifeq ("$(origin V)", "command line") - BUILD_VERBOSE = $(V) +SHELL := /bin/bash +# Current Operator version +VERSION ?= 0.4.0 +# Default bundle image tag +BUNDLE_IMG ?= controller-bundle:$(VERSION) +# Options for 'bundle-build' +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) endif +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) +CRD_OPTIONS ?= "crd:trivialVersions=true" + +# Image URL for the operator final image +OPERATOR_IMG ?= quay.io/m88i/nexus-operator:$(VERSION) +export OP_VERSION = $(VERSION) + +BUILDER ?= podman -ifeq ($(BUILD_VERBOSE),1) - Q = +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin else - Q = @ +GOBIN=$(shell go env GOBIN) endif -#export CGO_ENABLED:=0 +all: manager -.PHONY: all -all: build +# Run tests +ENVTEST_ASSETS_DIR=$(shell pwd)/testbin +test: generate-installer fmt vet bundle + mkdir -p ${ENVTEST_ASSETS_DIR} + test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/master/hack/setup-envtest.sh + sed -i "s,#\!.*,#\!\/bin\/bash,g" ${ENVTEST_ASSETS_DIR}/setup-envtest.sh + sed -i "/pipefail/d" ${ENVTEST_ASSETS_DIR}/setup-envtest.sh + source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out -.PHONY: mod -mod: - ./hack/go-mod.sh +generate-installer: generate manifests kustomize + cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMG) + $(KUSTOMIZE) build config/default > nexus-operator.yaml -.PHONY: format -format: - ./hack/go-fmt.sh - -.PHONY: go-generate -go-generate: mod - $(Q)go generate ./... +# Build manager binary +manager: generate fmt vet + go build -o bin/manager main.go -.PHONY: vet -vet: - ./hack/go-vet.sh +# Run against the configured Kubernetes cluster in ~/.kube/config +run: generate fmt vet manifests + go run ./main.go -.PHONY: test -test: - ./hack/go-test.sh +# Install CRDs into a cluster +install: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl apply -f - -.PHONY: lint -lint: - ./hack/go-lint.sh - #./hack/yaml-lint.sh +# Uninstall CRDs from a cluster +uninstall: manifests kustomize + $(KUSTOMIZE) build config/crd | kubectl delete -f - -.PHONY: build -build: - ./hack/go-build.sh +# Deploy controller in the configured Kubernetes cluster in ~/.kube/config +deploy: manifests kustomize + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | kubectl apply -f - -.PHONY: clean -clean: - rm -rf build/_output +# Generate manifests e.g. CRD, RBAC etc. +manifests: controller-gen + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases -.PHONY: addheaders -addheaders: +# Run go fmt against code +fmt: ./hack/addheaders.sh + ./hack/go-fmt.sh -.PHONY: install -install: - ./hack/install.sh +# Run go vet against code +vet: + go vet ./... + ./hack/go-lint.sh -.PHONY: uninstall -uninstall: - ./hack/uninstall.sh +# Generate code +generate: controller-gen + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + ./hack/openapi.sh + +# Build the docker image +docker-build: test + $(BUILDER) build . -t ${IMG} + +# Push the docker image +docker-push: + $(BUILDER) push ${IMG} + +# Build the application and final image +operator-build: generate manifests + $(BUILDER) build . -t ${OPERATOR_IMG} + +# find or download controller-gen +# download controller-gen if necessary +controller-gen: +ifeq (, $(shell which controller-gen)) + @{ \ + set -e ;\ + CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ + cd $$CONTROLLER_GEN_TMP_DIR ;\ + go mod init tmp ;\ + go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0 ;\ + rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ + } +CONTROLLER_GEN=$(GOBIN)/controller-gen +else +CONTROLLER_GEN=$(shell which controller-gen) +endif -.PHONY: olm-integration -olm-integration: - ./hack/olm-integration.sh +kustomize: +ifeq (, $(shell which kustomize)) + @{ \ + set -e ;\ + KUSTOMIZE_GEN_TMP_DIR=$$(mktemp -d) ;\ + cd $$KUSTOMIZE_GEN_TMP_DIR ;\ + go mod init tmp ;\ + go get sigs.k8s.io/kustomize/kustomize/v3@v3.5.4 ;\ + rm -rf $$KUSTOMIZE_GEN_TMP_DIR ;\ + } +KUSTOMIZE=$(GOBIN)/kustomize +else +KUSTOMIZE=$(shell which kustomize) +endif -.PHONY: test-e2e -namespace="nexus-e2e" -create_namespace=true -test-e2e: - NAMESPACE_E2E=$(namespace) CREATE_NAMESPACE=$(create_namespace) ./hack/run-e2e-test.sh +# Generate bundle manifests and metadata, then validate generated files. +.PHONY: bundle +bundle: manifests + operator-sdk generate kustomize manifests -q + cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMG) + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + operator-sdk bundle validate ./bundle + +# Build the bundle image. +.PHONY: bundle-build +bundle-build: + $(BUILDER) build -f bundle.Dockerfile -t $(BUNDLE_IMG) . + + +#################### CUSTOM NEXUS OPERATOR TASKS ###################### +# Run the OLM test on CI +ci-olm-test: + ./hack/ci/load-operator-image.sh + ./hack/ci/operator-olm-test.sh .PHONY: pr-prep create_namespace=true diff --git a/PROJECT b/PROJECT new file mode 100644 index 00000000..a2d2d599 --- /dev/null +++ b/PROJECT @@ -0,0 +1,11 @@ +domain: m88i.io +layout: go.kubebuilder.io/v2 +projectName: nexus-operator +repo: github.com/m88i/nexus-operator +resources: +- group: apps + kind: Nexus + version: v1alpha1 +version: 3-alpha +plugins: + go.sdk.operatorframework.io/v2-alpha: {} diff --git a/README.md b/README.md index de6f4a25..bd853454 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ If you have any questions please either [open an issue](https://github.com/m88i/ ## Quick Install -The installation procedure will create a Namespace named `operators` and will install every resources needed for the operator to run: +The installation procedure will create a Namespace named `nexus-operator-system` and will install every resources needed for the operator to run: ```bash # requires python and kubectl diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..54532aa1 --- /dev/null +++ b/api/v1alpha1/groupversion_info.go @@ -0,0 +1,20 @@ +// Package v1alpha1 contains API Schema definitions for the apps v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=apps.m88i.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "apps.m88i.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/pkg/apis/apps/v1alpha1/nexus_types.go b/api/v1alpha1/nexus_types.go similarity index 99% rename from pkg/apis/apps/v1alpha1/nexus_types.go rename to api/v1alpha1/nexus_types.go index 75dfbb29..fd957aec 100644 --- a/pkg/apis/apps/v1alpha1/nexus_types.go +++ b/api/v1alpha1/nexus_types.go @@ -259,9 +259,8 @@ const ( NexusStatusPending NexusStatusType = "Pending" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - // Nexus custom resource to deploy the Nexus Server +// +kubebuilder:object:root=true // +k8s:openapi-gen=true // +kubebuilder:resource:path=nexus,scope=Namespaced // +kubebuilder:subresource:status @@ -269,6 +268,7 @@ const ( // +operator-sdk:gen-csv:customresourcedefinitions.resources="Deployment,v1,\"A Kubernetes Deployment\"" // +operator-sdk:gen-csv:customresourcedefinitions.resources="Service,v1,\"A Kubernetes Service\"" // +operator-sdk:gen-csv:customresourcedefinitions.resources="PersistentVolumeClaim,v1,\"A Kubernetes PersistentVolumeClaim\"" + type Nexus struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -277,9 +277,8 @@ type Nexus struct { Status NexusStatus `json:"status,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - // NexusList contains a list of Nexus +// +kubebuilder:object:root=true type NexusList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` diff --git a/pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go similarity index 98% rename from pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go rename to api/v1alpha1/zz_generated.deepcopy.go index 36bf85d8..07b13e6f 100644 --- a/pkg/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -13,7 +13,8 @@ // 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 operator-sdk. DO NOT EDIT. + +// Code generated by controller-gen. DO NOT EDIT. package v1alpha1 @@ -28,7 +29,6 @@ func (in *Nexus) DeepCopyInto(out *Nexus) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nexus. @@ -57,7 +57,6 @@ func (in *NexusAutomaticUpdate) DeepCopyInto(out *NexusAutomaticUpdate) { *out = new(int) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusAutomaticUpdate. @@ -82,7 +81,6 @@ func (in *NexusList) DeepCopyInto(out *NexusList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusList. @@ -107,7 +105,6 @@ func (in *NexusList) DeepCopyObject() runtime.Object { func (in *NexusNetworking) DeepCopyInto(out *NexusNetworking) { *out = *in out.TLS = in.TLS - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusNetworking. @@ -123,7 +120,6 @@ func (in *NexusNetworking) DeepCopy() *NexusNetworking { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NexusNetworkingTLS) DeepCopyInto(out *NexusNetworkingTLS) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusNetworkingTLS. @@ -139,7 +135,6 @@ func (in *NexusNetworkingTLS) DeepCopy() *NexusNetworkingTLS { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NexusPersistence) DeepCopyInto(out *NexusPersistence) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusPersistence. @@ -155,7 +150,6 @@ func (in *NexusPersistence) DeepCopy() *NexusPersistence { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NexusProbe) DeepCopyInto(out *NexusProbe) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusProbe. @@ -186,7 +180,6 @@ func (in *NexusSpec) DeepCopyInto(out *NexusSpec) { **out = **in } out.ServerOperations = in.ServerOperations - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusSpec. @@ -209,7 +202,6 @@ func (in *NexusStatus) DeepCopyInto(out *NexusStatus) { copy(*out, *in) } out.ServerOperationsStatus = in.ServerOperationsStatus - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NexusStatus. @@ -225,7 +217,6 @@ func (in *NexusStatus) DeepCopy() *NexusStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OperationsStatus) DeepCopyInto(out *OperationsStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperationsStatus. @@ -241,7 +232,6 @@ func (in *OperationsStatus) DeepCopy() *OperationsStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerOperationsOpts) DeepCopyInto(out *ServerOperationsOpts) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerOperationsOpts. diff --git a/pkg/apis/apps/v1alpha1/zz_generated.openapi.go b/api/v1alpha1/zz_generated.openapi.go similarity index 72% rename from pkg/apis/apps/v1alpha1/zz_generated.openapi.go rename to api/v1alpha1/zz_generated.openapi.go index da384a41..522877e4 100644 --- a/pkg/apis/apps/v1alpha1/zz_generated.openapi.go +++ b/api/v1alpha1/zz_generated.openapi.go @@ -26,59 +26,14 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "./pkg/apis/apps/v1alpha1.Nexus": schema_pkg_apis_apps_v1alpha1_Nexus(ref), - "./pkg/apis/apps/v1alpha1.NexusPersistence": schema_pkg_apis_apps_v1alpha1_NexusPersistence(ref), - "./pkg/apis/apps/v1alpha1.NexusProbe": schema_pkg_apis_apps_v1alpha1_NexusProbe(ref), - "./pkg/apis/apps/v1alpha1.NexusSpec": schema_pkg_apis_apps_v1alpha1_NexusSpec(ref), - "./pkg/apis/apps/v1alpha1.NexusStatus": schema_pkg_apis_apps_v1alpha1_NexusStatus(ref), + "./api/v1alpha1.NexusPersistence": schema__api_v1alpha1_NexusPersistence(ref), + "./api/v1alpha1.NexusProbe": schema__api_v1alpha1_NexusProbe(ref), + "./api/v1alpha1.NexusSpec": schema__api_v1alpha1_NexusSpec(ref), + "./api/v1alpha1.NexusStatus": schema__api_v1alpha1_NexusStatus(ref), } } -func schema_pkg_apis_apps_v1alpha1_Nexus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Nexus custom resource to deploy the Nexus Server", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Ref: ref("./pkg/apis/apps/v1alpha1.NexusSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Ref: ref("./pkg/apis/apps/v1alpha1.NexusStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "./pkg/apis/apps/v1alpha1.NexusSpec", "./pkg/apis/apps/v1alpha1.NexusStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_apps_v1alpha1_NexusPersistence(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema__api_v1alpha1_NexusPersistence(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -113,7 +68,7 @@ func schema_pkg_apis_apps_v1alpha1_NexusPersistence(ref common.ReferenceCallback } } -func schema_pkg_apis_apps_v1alpha1_NexusProbe(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema__api_v1alpha1_NexusProbe(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -161,7 +116,7 @@ func schema_pkg_apis_apps_v1alpha1_NexusProbe(ref common.ReferenceCallback) comm } } -func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema__api_v1alpha1_NexusSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -185,7 +140,7 @@ func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) commo "automaticUpdate": { SchemaProps: spec.SchemaProps{ Description: "Automatic updates configuration", - Ref: ref("./pkg/apis/apps/v1alpha1.NexusAutomaticUpdate"), + Ref: ref("./api/v1alpha1.NexusAutomaticUpdate"), }, }, "imagePullPolicy": { @@ -204,7 +159,7 @@ func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) commo "persistence": { SchemaProps: spec.SchemaProps{ Description: "Persistence definition", - Ref: ref("./pkg/apis/apps/v1alpha1.NexusPersistence"), + Ref: ref("./api/v1alpha1.NexusPersistence"), }, }, "useRedHatImage": { @@ -224,7 +179,7 @@ func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) commo "networking": { SchemaProps: spec.SchemaProps{ Description: "Networking definition", - Ref: ref("./pkg/apis/apps/v1alpha1.NexusNetworking"), + Ref: ref("./api/v1alpha1.NexusNetworking"), }, }, "serviceAccountName": { @@ -237,19 +192,19 @@ func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) commo "livenessProbe": { SchemaProps: spec.SchemaProps{ Description: "LivenessProbe describes how the Nexus container liveness probe should work", - Ref: ref("./pkg/apis/apps/v1alpha1.NexusProbe"), + Ref: ref("./api/v1alpha1.NexusProbe"), }, }, "readinessProbe": { SchemaProps: spec.SchemaProps{ Description: "ReadinessProbe describes how the Nexus container readiness probe should work", - Ref: ref("./pkg/apis/apps/v1alpha1.NexusProbe"), + Ref: ref("./api/v1alpha1.NexusProbe"), }, }, "serverOperations": { SchemaProps: spec.SchemaProps{ Description: "ServerOperations describes the options for the operations performed on the deployed server instance", - Ref: ref("./pkg/apis/apps/v1alpha1.ServerOperationsOpts"), + Ref: ref("./api/v1alpha1.ServerOperationsOpts"), }, }, }, @@ -257,11 +212,11 @@ func schema_pkg_apis_apps_v1alpha1_NexusSpec(ref common.ReferenceCallback) commo }, }, Dependencies: []string{ - "./pkg/apis/apps/v1alpha1.NexusAutomaticUpdate", "./pkg/apis/apps/v1alpha1.NexusNetworking", "./pkg/apis/apps/v1alpha1.NexusPersistence", "./pkg/apis/apps/v1alpha1.NexusProbe", "./pkg/apis/apps/v1alpha1.ServerOperationsOpts", "k8s.io/api/core/v1.ResourceRequirements"}, + "./api/v1alpha1.NexusAutomaticUpdate", "./api/v1alpha1.NexusNetworking", "./api/v1alpha1.NexusPersistence", "./api/v1alpha1.NexusProbe", "./api/v1alpha1.ServerOperationsOpts", "k8s.io/api/core/v1.ResourceRequirements"}, } } -func schema_pkg_apis_apps_v1alpha1_NexusStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema__api_v1alpha1_NexusStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -317,13 +272,13 @@ func schema_pkg_apis_apps_v1alpha1_NexusStatus(ref common.ReferenceCallback) com "serverOperationsStatus": { SchemaProps: spec.SchemaProps{ Description: "ServerOperationsStatus describes the general status for the operations performed in the Nexus server instance", - Ref: ref("./pkg/apis/apps/v1alpha1.OperationsStatus"), + Ref: ref("./api/v1alpha1.OperationsStatus"), }, }, }, }, }, Dependencies: []string{ - "./pkg/apis/apps/v1alpha1.OperationsStatus", "k8s.io/api/apps/v1.DeploymentStatus"}, + "./api/v1alpha1.OperationsStatus", "k8s.io/api/apps/v1.DeploymentStatus"}, } } diff --git a/build/Dockerfile b/build/Dockerfile deleted file mode 100644 index 0eb1f951..00000000 --- a/build/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM registry.redhat.io/ubi8/ubi-minimal:latest - -ENV OPERATOR=/usr/local/bin/nexus-operator \ - USER_UID=1001 \ - USER_NAME=nexus-operator - -# install operator binary -COPY build/_output/bin/nexus-operator ${OPERATOR} - -COPY build/bin /usr/local/bin -RUN /usr/local/bin/user_setup - -ENTRYPOINT ["/usr/local/bin/entrypoint"] - -USER ${USER_UID} diff --git a/build/bin/entrypoint b/build/bin/entrypoint deleted file mode 100755 index 457186bd..00000000 --- a/build/bin/entrypoint +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec ${OPERATOR} $@ diff --git a/build/bin/user_setup b/build/bin/user_setup deleted file mode 100755 index 3cc5c758..00000000 --- a/build/bin/user_setup +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -set -x - -# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be) -echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" >> /etc/passwd -mkdir -p "${HOME}" -chown "${USER_UID}:0" "${HOME}" -chmod ug+rwx "${HOME}" - -# no need for this script to remain in the image after running -rm "$0" \ No newline at end of file diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 6eb71262..5d4c234f 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -3,9 +3,15 @@ FROM scratch LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ -LABEL operators.operatorframework.io.bundle.package.v1=nexus-operator-m88i +LABEL operators.operatorframework.io.bundle.package.v1=nexus-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha +LABEL operators.operatorframework.io.bundle.channel.default.v1= +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.0.1 +LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v2 +LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ +LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 -COPY deploy/olm-catalog/nexus-operator/manifests /manifests/ -COPY deploy/olm-catalog/nexus-operator/metadata/annotations.yaml /metadata/annotations.yaml +COPY bundle/manifests /manifests/ +COPY bundle/metadata /metadata/ +COPY bundle/tests/scorecard /tests/scorecard/ diff --git a/deploy/olm-catalog/nexus-operator/0.3.0/apps.m88i.io_nexus_crd.yaml b/bundle/manifests/apps.m88i.io_nexus.yaml similarity index 61% rename from deploy/olm-catalog/nexus-operator/0.3.0/apps.m88i.io_nexus_crd.yaml rename to bundle/manifests/apps.m88i.io_nexus.yaml index 4c20fb6f..816f1cc9 100644 --- a/deploy/olm-catalog/nexus-operator/0.3.0/apps.m88i.io_nexus_crd.yaml +++ b/bundle/manifests/apps.m88i.io_nexus.yaml @@ -1,6 +1,9 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + creationTimestamp: null name: nexus.apps.m88i.io spec: group: apps.m88i.io @@ -14,17 +17,12 @@ spec: status: {} validation: openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -35,76 +33,51 @@ spec: description: Automatic updates configuration properties: disabled: - description: Whether or not the Operator should perform automatic - updates. Defaults to `false` (auto updates are enabled). Is set - to `false` if `spec.image` is not empty and is different from - the default community image. + description: Whether or not the Operator should perform automatic updates. Defaults to `false` (auto updates are enabled). Is set to `false` if `spec.image` is not empty and is different from the default community image. type: boolean minorVersion: - description: The Nexus image minor version the deployment should - stay in. If left blank and automatic updates are enabled the latest - minor is set. + description: The Nexus image minor version the deployment should stay in. If left blank and automatic updates are enabled the latest minor is set. minimum: 0 type: integer type: object generateRandomAdminPassword: - description: 'GenerateRandomAdminPassword enables the random password - generation. Defaults to `false`: the default password for a newly - created instance is ''admin123'', which should be changed in the first - login. If set to `true`, you must use the automatically generated - ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. - The operator uses the default credentials to create a user for itself - to create default repositories. If set to `true`, the repositories - won''t be created since the operator won''t fetch for the random password.' + description: 'GenerateRandomAdminPassword enables the random password generation. Defaults to `false`: the default password for a newly created instance is ''admin123'', which should be changed in the first login. If set to `true`, you must use the automatically generated ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. The operator uses the default credentials to create a user for itself to create default repositories. If set to `true`, the repositories won''t be created since the operator won''t fetch for the random password.' type: boolean image: - description: 'Full image tag name for this specific deployment. Will - be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' + description: 'Full image tag name for this specific deployment. Will be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' type: string imagePullPolicy: - description: 'The image pull policy for the Nexus image. If left blank - behavior will be determined by the image tag (`Always` if "latest" - and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` - or `Never`.' + description: 'The image pull policy for the Nexus image. If left blank behavior will be determined by the image tag (`Always` if "latest" and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` or `Never`.' enum: - Always - IfNotPresent - Never type: string livenessProbe: - description: LivenessProbe describes how the Nexus container liveness - probe should work + description: LivenessProbe describes how the Nexus container liveness probe should work properties: failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. format: int32 minimum: 1 type: integer initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. + description: Number of seconds after the container has started before probes are initiated. Defaults to 240 seconds. Minimum value is 0. format: int32 minimum: 0 type: integer periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. + description: How often (in seconds) to perform the probe. Defaults to 10 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. format: int32 minimum: 1 type: integer timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. + description: Number of seconds after which the probe times out. Defaults to 15 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer @@ -113,41 +86,30 @@ spec: description: Networking definition properties: expose: - description: Set to `true` to expose the Nexus application. Defaults - to `false`. + description: Set to `true` to expose the Nexus application. Defaults to `false`. type: boolean exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Defaults to Route on OpenShift and Ingress on Kubernetes. Routes - are only available on Openshift and Ingresses are only available - on Kubernetes.' + description: 'Type of networking exposure: NodePort, Route or Ingress. Defaults to Route on OpenShift and Ingress on Kubernetes. Routes are only available on Openshift and Ingresses are only available on Kubernetes.' enum: - NodePort - Route - Ingress type: string host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. + description: Host where the Nexus service is exposed. This attribute is required if the service is exposed via Ingress. type: string nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. + description: NodePort defined in the exposed service. Required if exposed via NodePort. format: int32 type: integer tls: description: TLS/SSL-related configuration properties: mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to `false`. + description: When exposing via Route, set to `true` to only allow encrypted traffic using TLS (disables HTTP in favor of HTTPS). Defaults to `false`. type: boolean secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. + description: When exposing via Ingress, inform the name of the TLS secret containing certificate and private key for TLS encryption. It must be present in the same namespace as the Operator. type: string type: object type: object @@ -155,8 +117,7 @@ spec: description: Persistence definition properties: persistent: - description: Flag to indicate if this instance will be persistent - or not + description: Flag to indicate if this instance will be persistent or not type: boolean storageClass: description: StorageClass used by the managed PVC. @@ -168,39 +129,30 @@ spec: - persistent type: object readinessProbe: - description: ReadinessProbe describes how the Nexus container readiness - probe should work + description: ReadinessProbe describes how the Nexus container readiness probe should work properties: failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. format: int32 minimum: 1 type: integer initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. + description: Number of seconds after the container has started before probes are initiated. Defaults to 240 seconds. Minimum value is 0. format: int32 minimum: 0 type: integer periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. + description: How often (in seconds) to perform the probe. Defaults to 10 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. format: int32 minimum: 1 type: integer timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. + description: Number of seconds after which the probe times out. Defaults to 15 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer @@ -221,8 +173,7 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object requests: additionalProperties: @@ -231,43 +182,24 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object type: object serverOperations: - description: ServerOperations describes the options for the operations - performed on the deployed server instance + description: ServerOperations describes the options for the operations performed on the deployed server instance properties: disableOperatorUserCreation: - description: DisableOperatorUserCreation disables the auto-creation - of the `nexus-operator` user on the deployed server. This user - performs all the operations on the server (such as creating the - community repos). If disabled, the Operator will use the default - `admin` user. Defaults to `false` (always create the user). Setting - this to `true` is not recommended as it grants the Operator more - privileges than it needs and it would not be possible to tell - apart operations performed by the `admin` and the Operator. + description: DisableOperatorUserCreation disables the auto-creation of the `nexus-operator` user on the deployed server. This user performs all the operations on the server (such as creating the community repos). If disabled, the Operator will use the default `admin` user. Defaults to `false` (always create the user). Setting this to `true` is not recommended as it grants the Operator more privileges than it needs and it would not be possible to tell apart operations performed by the `admin` and the Operator. type: boolean disableRepositoryCreation: - description: DisableRepositoryCreation disables the auto-creation - of Apache, JBoss and Red Hat repositories and their addition to - the Maven Public group in this Nexus instance. Defaults to `false` - (always try to create the repos). Set this to `true` to not create - them. Only works if `spec.generateRandomAdminPassword` is `false`. + description: DisableRepositoryCreation disables the auto-creation of Apache, JBoss and Red Hat repositories and their addition to the Maven Public group in this Nexus instance. Defaults to `false` (always try to create the repos). Set this to `true` to not create them. Only works if `spec.generateRandomAdminPassword` is `false`. type: boolean type: object serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR (`metadata.name`). + description: ServiceAccountName is the name of the ServiceAccount used to run the Pods. If left blank, a default ServiceAccount is created with the same name as the Nexus CR (`metadata.name`). type: string useRedHatImage: - description: If you have access to Red Hat Container Catalog, set this - to `true` to use the certified image provided by Sonatype Defaults - to `false` + description: If you have access to Red Hat Container Catalog, set this to `true` to use the certified image provided by Sonatype Defaults to `false` type: boolean required: - persistence @@ -281,26 +213,20 @@ spec: description: Condition status for the Nexus deployment properties: availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. + description: Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. format: int32 type: integer collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. + description: Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet. format: int32 type: integer conditions: - description: Represents the latest available observations of a deployment's - current state. + description: Represents the latest available observations of a deployment's current state. items: - description: DeploymentCondition describes the state of a deployment - at a certain point. + description: DeploymentCondition describes the state of a deployment at a certain point. properties: lastTransitionTime: - description: Last time the condition transitioned from one - status to another. + description: Last time the condition transitioned from one status to another. format: date-time type: string lastUpdateTime: @@ -308,15 +234,13 @@ spec: format: date-time type: string message: - description: A human readable message indicating details about - the transition. + description: A human readable message indicating details about the transition. type: string reason: description: The reason for the condition's last transition. type: string status: - description: Status of the condition, one of True, False, - Unknown. + description: Status of the condition, one of True, False, Unknown. type: string type: description: Type of deployment condition. @@ -335,21 +259,15 @@ spec: format: int32 type: integer replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). + description: Total number of non-terminated pods targeted by this deployment (their labels match the selector). format: int32 type: integer unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. + description: Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created. format: int32 type: integer updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. + description: Total number of non-terminated pods targeted by this deployment that have the desired template spec. format: int32 type: integer type: object @@ -363,8 +281,7 @@ spec: description: Gives more information about a failure status type: string serverOperationsStatus: - description: ServerOperationsStatus describes the general status for - the operations performed in the Nexus server instance + description: ServerOperationsStatus describes the general status for the operations performed in the Nexus server instance properties: communityRepositoriesCreated: type: boolean @@ -390,3 +307,9 @@ spec: - name: v1alpha1 served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/nexus-operator-metrics-reader_rbac.authorization.k8s.io_v1beta1_clusterrole.yaml b/bundle/manifests/nexus-operator-metrics-reader_rbac.authorization.k8s.io_v1beta1_clusterrole.yaml new file mode 100644 index 00000000..c4dddf5b --- /dev/null +++ b/bundle/manifests/nexus-operator-metrics-reader_rbac.authorization.k8s.io_v1beta1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: nexus-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/deploy/olm-catalog/nexus-operator/0.2.0/nexus-operator.v0.2.0.clusterserviceversion.yaml b/bundle/manifests/nexus-operator.clusterserviceversion.yaml similarity index 94% rename from deploy/olm-catalog/nexus-operator/0.2.0/nexus-operator.v0.2.0.clusterserviceversion.yaml rename to bundle/manifests/nexus-operator.clusterserviceversion.yaml index 2292ee6b..b98ff23e 100644 --- a/deploy/olm-catalog/nexus-operator/0.2.0/nexus-operator.v0.2.0.clusterserviceversion.yaml +++ b/bundle/manifests/nexus-operator.clusterserviceversion.yaml @@ -32,69 +32,37 @@ metadata: } } ] - capabilities: Basic Install + capabilities: Seamless Upgrades categories: Developer Tools certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.2.0 + containerImage: quay.io/m88i/nexus-operator:0.4.0 createdAt: "2019-11-16T13:12:22Z" description: Nexus Operator to deploy and manage Nexus 3.x servers + operators.operatorframework.io/builder: operator-sdk-v1.0.1 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 repository: https://github.com/m88i/nexus-operator support: m88i Labs tectonic-visibility: ocs - name: nexus-operator.v0.2.0 + name: nexus-operator.v0.4.0 namespace: placeholder spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: Nexus custom resource to deploy the Nexus Server - displayName: Nexus + - displayName: Nexus kind: Nexus name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: A Kubernetes Deployment - version: v1 - - kind: PersistentVolumeClaim - name: A Kubernetes PersistentVolumeClaim - version: v1 - - kind: Service - name: A Kubernetes Service - version: v1 - specDescriptors: - - description: 'Full image tag name for this specific deployment Default: docker.io/sonatype/nexus3:latest' - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: 'Number of pods replicas desired Default: 1' - displayName: Replicas - path: replicas - - description: Defined Resources for the Nexus instance - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: 'If you have access to Red Hat Container Catalog, turn this to - true to use the certified image provided by Sonatype Default: false' - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - statusDescriptors: - - description: Condition status for the Nexus deployment - displayName: appsv1.DeploymentStatus - path: deploymentStatus version: v1alpha1 description: |- Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world + * Creates an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world * On OpenShift, creates a Route to expose the service outside the cluster + * Automatically creates Apache, Red Hat and JBoss Maven repositories + * Automatically updates Nexus within the same minor version - After installing it, you will have to grab the `admin` user password from the deployed container. There's a file auto generated in `/nexus-data/admin.password`. - Use `cat` to read the file and view the password. Use it to login for the first time and follow the on screen instructions to have the Nexus server ready for use. + [See our documentation](https://github.com/m88i/nexus-operator/blob/main/README.md) for more installation and usage scenarios. If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues) or send an email to our maillist: [nexus-operator@googlegroups.com](mailto:nexus-operator@googlegroups.com) @@ -105,53 +73,12 @@ spec: mediatype: image/svg+xml install: spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.2.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: + clusterPermissions: - rules: - apiGroups: - - "" + - apps resources: - - pods - - services - - services/finalizers - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - - replicationcontrollers - - podtemplates + - deployments verbs: - create - delete @@ -163,10 +90,19 @@ spec: - apiGroups: - apps resources: - - deployments - - daemonsets + - deployments/finalizers + verbs: + - update + - apiGroups: + - apps + resources: - replicasets - - statefulsets + verbs: + - get + - apiGroups: + - apps.m88i.io + resources: + - nexus verbs: - create - delete @@ -176,20 +112,36 @@ spec: - update - watch - apiGroups: - - monitoring.coreos.com + - apps.m88i.io resources: - - servicemonitors + - nexus/status verbs: - get + - patch + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: - create + - get - apiGroups: - - apps - resourceNames: - - nexus-operator + - "" resources: - - deployments/finalizers + - events + - persistentvolumeclaims + - secrets + - serviceaccounts + - services verbs: + - create + - delete + - get + - list + - patch - update + - watch - apiGroups: - "" resources: @@ -197,16 +149,16 @@ spec: verbs: - get - apiGroups: - - apps + - monitoring.coreos.com resources: - - replicasets - - deployments + - servicemonitors verbs: + - create - get - apiGroups: - - apps.m88i.io + - networking.k8s.io resources: - - '*' + - ingresses verbs: - create - delete @@ -228,25 +180,95 @@ spec: - update - watch - apiGroups: - - networking.k8s.io + - authentication.k8s.io resources: - - ingresses + - tokenreviews verbs: - create - - delete + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: default + deployments: + - name: nexus-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + strategy: {} + template: + metadata: + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: {} + - args: + - --metrics-addr=127.0.0.1:8080 + - --enable-leader-election + command: + - /manager + image: quay.io/m88i/nexus-operator:0.4.0 + name: manager + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: - get - list + - watch + - create + - update - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get - update - - watch - serviceAccountName: nexus-operator + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: default strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - - supported: false + - supported: true type: MultiNamespace - supported: true type: AllNamespaces @@ -265,14 +287,14 @@ spec: name: nexus-operator links: - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/master/README.md + url: https://github.com/m88i/nexus-operator/blob/main/README.md - name: Nexus Operator source code repository url: https://github.com/m88i/nexus-operator maintainers: - email: nexus-operator@googlegroups.com name: m88i Labs maturity: alpha - minKubeVersion: 1.11.0 provider: name: m88i Labs - version: 0.2.0 + replaces: nexus-operator.v0.3.0 + version: 0.4.0 diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml new file mode 100644 index 00000000..65acb5c9 --- /dev/null +++ b/bundle/metadata/annotations.yaml @@ -0,0 +1,12 @@ +annotations: + operators.operatorframework.io.bundle.channel.default.v1: "" + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: nexus-operator + operators.operatorframework.io.metrics.builder: operator-sdk-v1.0.1 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v2 + operators.operatorframework.io.test.config.v1: tests/scorecard/ + operators.operatorframework.io.test.mediatype.v1: scorecard+v1 diff --git a/bundle/nexus-operator-m88i.package.yaml b/bundle/nexus-operator-m88i.package.yaml new file mode 100644 index 00000000..884ed31c --- /dev/null +++ b/bundle/nexus-operator-m88i.package.yaml @@ -0,0 +1,5 @@ +channels: + - currentCSV: nexus-operator.v{version} + name: alpha +defaultChannel: alpha +packageName: nexus-operator-m88i \ No newline at end of file diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml new file mode 100644 index 00000000..6a0d903c --- /dev/null +++ b/bundle/tests/scorecard/config.yaml @@ -0,0 +1,49 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: + - entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: basic + test: basic-check-spec-test + - entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-bundle-validation-test + - entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-crds-have-validation-test + - entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-crds-have-resources-test + - entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-spec-descriptors-test + - entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-status-descriptors-test diff --git a/cmd/manager/main.go b/cmd/manager/main.go deleted file mode 100644 index 607766a4..00000000 --- a/cmd/manager/main.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 ( - "context" - "errors" - "flag" - "fmt" - "os" - "runtime" - "strings" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - "go.etcd.io/etcd/version" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - - "github.com/m88i/nexus-operator/pkg/apis" - "github.com/m88i/nexus-operator/pkg/controller" - - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics" - "github.com/operator-framework/operator-sdk/pkg/leader" - "github.com/operator-framework/operator-sdk/pkg/log/zap" - "github.com/operator-framework/operator-sdk/pkg/metrics" - sdkVersion "github.com/operator-framework/operator-sdk/version" - "github.com/spf13/pflag" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client/config" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/manager/signals" -) - -// Change below variables to serve metrics on different host or port. -var ( - metricsHost = "0.0.0.0" - metricsPort int32 = 8383 - operatorMetricsPort int32 = 8686 -) -var log = logf.Log.WithName("cmd") - -func printVersion() { - log.Info(fmt.Sprintf("Operator Version: %s", version.Version)) - log.Info(fmt.Sprintf("Go Version: %s", runtime.Version())) - log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)) - log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version)) -} - -func main() { - // Add the zap logger flag set to the CLI. The flag set must - // be added before calling pflag.Parse(). - pflag.CommandLine.AddFlagSet(zap.FlagSet()) - - // Add flags registered by imported packages (e.g. glog and - // controller-runtime) - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - - pflag.Parse() - - // Use a zap logr.Logger implementation. If none of the zap - // flags are configured (or if the zap flag set is not being - // used), this defaults to a production zap logger. - // - // The logger instantiated here can be changed to any logger - // implementing the logr.Logger interface. This logger will - // be propagated through the whole operator, generating - // uniform and structured logs. - logf.SetLogger(zap.Logger()) - - printVersion() - - namespace, err := k8sutil.GetWatchNamespace() - if err != nil { - log.Error(err, "Failed to get watch namespace") - os.Exit(1) - } - - // Get a config to talk to the apiserver - cfg, err := config.GetConfig() - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - ctx := context.TODO() - // Become the leader before proceeding - err = leader.Become(ctx, "nexus-operator-lock") - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - // Set default manager options - options := manager.Options{ - Namespace: "", - MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), - } - - // Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2) - // Note that this is not intended to be used for excluding namespaces, this is better done via a Predicate - // Also note that you may face performance issues when using this with a high number of namespaces. - // More Info: https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/cache#MultiNamespacedCacheBuilder - if strings.Contains(namespace, ",") { - options.Namespace = "" - options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(namespace, ",")) - } - - // Create a new manager to provide shared dependencies and start components - mgr, err := manager.New(cfg, options) - if err != nil { - log.Error(err, "") - os.Exit(1) - } - - log.Info("Registering Components.") - - // Setup Scheme for all resources - if err := apis.AddToScheme(mgr.GetScheme()); err != nil { - log.Error(err, "") - os.Exit(1) - } - - // Setup all Controllers - if err := controller.AddToManager(mgr); err != nil { - log.Error(err, "") - os.Exit(1) - } - - // Add the Metrics Service - addMetrics(ctx, cfg) - - log.Info("Starting the Cmd.") - - // Start the Cmd - if err := mgr.Start(signals.SetupSignalHandler()); err != nil { - log.Error(err, "Manager exited non-zero") - os.Exit(1) - } -} - -// addMetrics will create the Services and Service Monitors to allow the operator export the metrics by using -// the Prometheus operator -func addMetrics(ctx context.Context, cfg *rest.Config) { - // Get the namespace the operator is currently deployed in. - operatorNs, err := k8sutil.GetOperatorNamespace() - if err != nil { - if errors.Is(err, k8sutil.ErrRunLocal) { - log.Info("Skipping CR metrics server creation; not running in a cluster.") - return - } - } - - if err := serveCRMetrics(cfg, operatorNs); err != nil { - log.Info("Could not generate and serve custom resource metrics", "error", err.Error()) - } - - // Add to the below struct any other metrics ports you want to expose. - servicePorts := []v1.ServicePort{ - {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}}, - {Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}}, - } - - // Create Service object to expose the metrics port(s). - service, err := metrics.CreateMetricsService(ctx, cfg, servicePorts) - if err != nil { - log.Info("Could not create metrics Service", "error", err.Error()) - } - - // CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources - // necessary to configure Prometheus to scrape metrics from this operator. - services := []*v1.Service{service} - - // The ServiceMonitor is created in the same namespace where the operator is deployed - _, err = metrics.CreateServiceMonitors(cfg, operatorNs, services) - if err != nil { - log.Info("Could not create ServiceMonitor object", "error", err.Error()) - // If this operator is deployed to a cluster without the prometheus-operator running, it will return - // ErrServiceMonitorNotPresent, which can be used to safely skip ServiceMonitor creation. - if err == metrics.ErrServiceMonitorNotPresent { - log.Info("Install prometheus-operator in your cluster to create ServiceMonitor objects", "error", err.Error()) - } - } -} - -// serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types. -// It serves those metrics on "http://metricsHost:operatorMetricsPort". -func serveCRMetrics(cfg *rest.Config, operatorNs string) error { - // The function below returns a list of filtered operator/CR specific GVKs. For more control, override the GVK list below - // with your own custom logic. Note that if you are adding third party API schemas, probably you will need to - // customize this implementation to avoid permissions issues. - filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme) - if err != nil { - return err - } - - // The metrics will be generated from the namespaces which are returned here. - // NOTE that passing nil or an empty list of namespaces in GenerateAndServeCRMetrics will result in an error. - ns, err := kubemetrics.GetNamespacesForMetrics(operatorNs) - if err != nil { - return err - } - - // Generate and serve custom resource specific metrics. - err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort) - if err != nil { - return err - } - return nil -} diff --git a/codecov.yml b/codecov.yml index 1893ed2f..12da6a3d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,9 +2,8 @@ flags: operator: paths: - pkg/ - operator-e2e: - paths: - - pkg/ + - controllers/ + - api coverage: status: patch: @@ -15,12 +14,6 @@ coverage: operator-e2e: informational: true project: - operator-e2e: - target: auto - base: auto - threshold: 5% - flags: - - operator-e2e operator: target: auto base: auto @@ -30,6 +23,4 @@ coverage: comment: require_changes: true ignore: - - "test/e2e" - "pkg/test" - - "pkg/apis" diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 00000000..58db114f --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,26 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for +# breaking changes +apiVersion: cert-manager.io/v1alpha2 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 00000000..bebea5a5 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000..90d7c313 --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/deploy/crds/apps.m88i.io_nexus_crd.yaml b/config/crd/bases/apps.m88i.io_nexus.yaml similarity index 99% rename from deploy/crds/apps.m88i.io_nexus_crd.yaml rename to config/crd/bases/apps.m88i.io_nexus.yaml index 4c20fb6f..d021d3d3 100644 --- a/deploy/crds/apps.m88i.io_nexus_crd.yaml +++ b/config/crd/bases/apps.m88i.io_nexus.yaml @@ -1,6 +1,11 @@ + +--- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + creationTimestamp: null name: nexus.apps.m88i.io spec: group: apps.m88i.io @@ -14,7 +19,6 @@ spec: status: {} validation: openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -390,3 +394,9 @@ spec: - name: v1alpha1 served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml new file mode 100644 index 00000000..de2499ae --- /dev/null +++ b/config/crd/kustomization.yaml @@ -0,0 +1,21 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/apps.m88i.io_nexus.yaml +# +kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_nexus.yaml +# +kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +#- patches/cainjection_in_nexus.yaml +# +kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000..6f83d9a9 --- /dev/null +++ b/config/crd/kustomizeconfig.yaml @@ -0,0 +1,17 @@ +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/config/crd/patches/cainjection_in_nexus.yaml b/config/crd/patches/cainjection_in_nexus.yaml new file mode 100644 index 00000000..97fa499d --- /dev/null +++ b/config/crd/patches/cainjection_in_nexus.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: nexus.apps.m88i.io diff --git a/config/crd/patches/webhook_in_nexus.yaml b/config/crd/patches/webhook_in_nexus.yaml new file mode 100644 index 00000000..ca842e70 --- /dev/null +++ b/config/crd/patches/webhook_in_nexus.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: nexus.apps.m88i.io +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml new file mode 100644 index 00000000..2765f3c2 --- /dev/null +++ b/config/default/kustomization.yaml @@ -0,0 +1,70 @@ +# Adds namespace to all resources. +namespace: nexus-operator-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: nexus-operator- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +- ../prometheus + +patchesStrategicMerge: + # Protect the /metrics endpoint by putting it behind auth. + # If you want your controller-manager to expose the /metrics + # endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. +# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. +# 'CERTMANAGER' needs to be enabled to use ca injection +#- webhookcainjection_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +#vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1alpha2 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1alpha2 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000..77e743d1 --- /dev/null +++ b/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,25 @@ +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https + - name: manager + args: + - "--metrics-addr=127.0.0.1:8080" + - "--enable-leader-election" diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000..738de350 --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000..7e79bf99 --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml new file mode 100644 index 00000000..c2f8e2ea --- /dev/null +++ b/config/manager/kustomization.yaml @@ -0,0 +1,8 @@ +resources: +- manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: quay.io/m88i/nexus-operator + newTag: 0.4.0 diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml new file mode 100644 index 00000000..b6c85a52 --- /dev/null +++ b/config/manager/manager.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + labels: + control-plane: controller-manager + spec: + containers: + - command: + - /manager + args: + - --enable-leader-election + image: controller:latest + name: manager + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + terminationGracePeriodSeconds: 10 diff --git a/deploy/olm-catalog/nexus-operator/0.2.1/nexus-operator.v0.2.1.clusterserviceversion.yaml b/config/manifests/bases/nexus-operator.clusterserviceversion.yaml similarity index 94% rename from deploy/olm-catalog/nexus-operator/0.2.1/nexus-operator.v0.2.1.clusterserviceversion.yaml rename to config/manifests/bases/nexus-operator.clusterserviceversion.yaml index a11f859d..32265b26 100644 --- a/deploy/olm-catalog/nexus-operator/0.2.1/nexus-operator.v0.2.1.clusterserviceversion.yaml +++ b/config/manifests/bases/nexus-operator.clusterserviceversion.yaml @@ -32,69 +32,37 @@ metadata: } } ] - capabilities: Basic Install + capabilities: Seamless Upgrades categories: Developer Tools certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.2.1 + containerImage: quay.io/m88i/nexus-operator:0.4.0 createdAt: "2019-11-16T13:12:22Z" description: Nexus Operator to deploy and manage Nexus 3.x servers + operators.operatorframework.io/builder: operator-sdk-v1.0.1 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 repository: https://github.com/m88i/nexus-operator support: m88i Labs tectonic-visibility: ocs - name: nexus-operator.v0.2.1 + name: nexus-operator.v0.4.0 namespace: placeholder spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: Nexus custom resource to deploy the Nexus Server - displayName: Nexus + - displayName: Nexus kind: Nexus name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: A Kubernetes Deployment - version: v1 - - kind: PersistentVolumeClaim - name: A Kubernetes PersistentVolumeClaim - version: v1 - - kind: Service - name: A Kubernetes Service - version: v1 - specDescriptors: - - description: 'Full image tag name for this specific deployment Default: docker.io/sonatype/nexus3:latest' - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: 'Number of pods replicas desired Default: 1' - displayName: Replicas - path: replicas - - description: Defined Resources for the Nexus instance - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: 'If you have access to Red Hat Container Catalog, turn this to - true to use the certified image provided by Sonatype Default: false' - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - statusDescriptors: - - description: Condition status for the Nexus deployment - displayName: appsv1.DeploymentStatus - path: deploymentStatus version: v1alpha1 description: |- Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world + * Creates an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world * On OpenShift, creates a Route to expose the service outside the cluster + * Automatically creates Apache, Red Hat and JBoss Maven repositories + * Automatically updates Nexus within the same minor version - After installing it, you will have to grab the `admin` user password from the deployed container. There's a file auto generated in `/nexus-data/admin.password`. - Use `cat` to read the file and view the password. Use it to login for the first time and follow the on screen instructions to have the Nexus server ready for use. + [See our documentation](https://github.com/m88i/nexus-operator/blob/main/README.md) for more installation and usage scenarios. If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues) or send an email to our maillist: [nexus-operator@googlegroups.com](mailto:nexus-operator@googlegroups.com) @@ -105,54 +73,12 @@ spec: mediatype: image/svg+xml install: spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.2.1 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: + clusterPermissions: - rules: - apiGroups: - - "" + - apps resources: - - pods - - services - - services/finalizers - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - - replicationcontrollers - - podtemplates - - serviceaccounts + - deployments verbs: - create - delete @@ -164,10 +90,19 @@ spec: - apiGroups: - apps resources: - - deployments - - daemonsets + - deployments/finalizers + verbs: + - update + - apiGroups: + - apps + resources: - replicasets - - statefulsets + verbs: + - get + - apiGroups: + - apps.m88i.io + resources: + - nexus verbs: - create - delete @@ -177,20 +112,36 @@ spec: - update - watch - apiGroups: - - monitoring.coreos.com + - apps.m88i.io resources: - - servicemonitors + - nexus/status verbs: - get + - patch + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: - create + - get - apiGroups: - - apps - resourceNames: - - nexus-operator + - "" resources: - - deployments/finalizers + - events + - persistentvolumeclaims + - secrets + - serviceaccounts + - services verbs: + - create + - delete + - get + - list + - patch - update + - watch - apiGroups: - "" resources: @@ -198,16 +149,16 @@ spec: verbs: - get - apiGroups: - - apps + - monitoring.coreos.com resources: - - replicasets - - deployments + - servicemonitors verbs: + - create - get - apiGroups: - - apps.m88i.io + - networking.k8s.io resources: - - '*' + - ingresses verbs: - create - delete @@ -229,25 +180,95 @@ spec: - update - watch - apiGroups: - - networking.k8s.io + - authentication.k8s.io resources: - - ingresses + - tokenreviews verbs: - create - - delete + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: default + deployments: + - name: nexus-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + strategy: {} + template: + metadata: + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: {} + - args: + - --metrics-addr=127.0.0.1:8080 + - --enable-leader-election + command: + - /manager + image: controller:latest + name: manager + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: - get - list + - watch + - create + - update - patch + - delete + - apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get - update - - watch - serviceAccountName: nexus-operator + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: default strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - - supported: false + - supported: true type: MultiNamespace - supported: true type: AllNamespaces @@ -266,15 +287,14 @@ spec: name: nexus-operator links: - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/master/README.md + url: https://github.com/m88i/nexus-operator/blob/main/README.md - name: Nexus Operator source code repository url: https://github.com/m88i/nexus-operator maintainers: - email: nexus-operator@googlegroups.com name: m88i Labs maturity: alpha - minKubeVersion: 1.11.0 provider: name: m88i Labs - replaces: nexus-operator.v0.2.0 - version: 0.2.1 + replaces: nexus-operator.v0.3.0 + version: 0.4.0 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml new file mode 100644 index 00000000..63ca74d7 --- /dev/null +++ b/config/manifests/kustomization.yaml @@ -0,0 +1,4 @@ +resources: +- ../default +- ../samples +- ../scorecard diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml new file mode 100644 index 00000000..ed137168 --- /dev/null +++ b/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml new file mode 100644 index 00000000..9b8047b7 --- /dev/null +++ b/config/prometheus/monitor.yaml @@ -0,0 +1,16 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + selector: + matchLabels: + control-plane: controller-manager diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000..7d62534c --- /dev/null +++ b/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: ["/metrics"] + verbs: ["get"] diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000..618f5e41 --- /dev/null +++ b/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000..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..6cf656be --- /dev/null +++ b/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml new file mode 100644 index 00000000..66c28338 --- /dev/null +++ b/config/rbac/kustomization.yaml @@ -0,0 +1,12 @@ +resources: +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# Comment the following 4 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +- auth_proxy_service.yaml +- auth_proxy_role.yaml +- auth_proxy_role_binding.yaml +- auth_proxy_client_clusterrole.yaml diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000..7dc16c42 --- /dev/null +++ b/config/rbac/leader_election_role.yaml @@ -0,0 +1,33 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000..eed16906 --- /dev/null +++ b/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: default + namespace: system diff --git a/config/rbac/nexus_editor_role.yaml b/config/rbac/nexus_editor_role.yaml new file mode 100644 index 00000000..0c74126f --- /dev/null +++ b/config/rbac/nexus_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit nexus. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nexus-editor-role +rules: +- apiGroups: + - apps.m88i.io + resources: + - nexus + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps.m88i.io + resources: + - nexus/status + verbs: + - get diff --git a/config/rbac/nexus_viewer_role.yaml b/config/rbac/nexus_viewer_role.yaml new file mode 100644 index 00000000..86885f91 --- /dev/null +++ b/config/rbac/nexus_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view nexus. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nexus-viewer-role +rules: +- apiGroups: + - apps.m88i.io + resources: + - nexus + verbs: + - get + - list + - watch +- apiGroups: + - apps.m88i.io + resources: + - nexus/status + verbs: + - get diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml new file mode 100644 index 00000000..92cb9563 --- /dev/null +++ b/config/rbac/role.yaml @@ -0,0 +1,112 @@ + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get +- apiGroups: + - apps.m88i.io + resources: + - nexus + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps.m88i.io + resources: + - nexus/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get +- apiGroups: + - "" + resources: + - events + - persistentvolumeclaims + - secrets + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - get +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/deploy/role_binding.yaml b/config/rbac/role_binding.yaml similarity index 64% rename from deploy/role_binding.yaml rename to config/rbac/role_binding.yaml index d4e4a070..8f265870 100644 --- a/deploy/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,12 +1,12 @@ -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: - name: nexus-operator -subjects: -- kind: ServiceAccount - name: nexus-operator - namespace: ${NAMESPACE} + name: manager-rolebinding roleRef: - kind: ClusterRole - name: nexus-operator apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: default + namespace: system diff --git a/deploy/crds/apps.m88i.io_v1alpha1_nexus_cr.yaml b/config/samples/apps_v1alpha1_nexus.yaml similarity index 100% rename from deploy/crds/apps.m88i.io_v1alpha1_nexus_cr.yaml rename to config/samples/apps_v1alpha1_nexus.yaml diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml new file mode 100644 index 00000000..50ec3f87 --- /dev/null +++ b/config/samples/kustomization.yaml @@ -0,0 +1,4 @@ +## Append samples you want in your CSV to this file as resources ## +resources: +- apps_v1alpha1_nexus.yaml +# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml new file mode 100644 index 00000000..c7704784 --- /dev/null +++ b/config/scorecard/bases/config.yaml @@ -0,0 +1,7 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: [] diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml new file mode 100644 index 00000000..d73509ee --- /dev/null +++ b/config/scorecard/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- bases/config.yaml +patchesJson6902: +- path: patches/basic.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +- path: patches/olm.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +# +kubebuilder:scaffold:patchesJson6902 diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml new file mode 100644 index 00000000..0016b652 --- /dev/null +++ b/config/scorecard/patches/basic.config.yaml @@ -0,0 +1,10 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: basic + test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml new file mode 100644 index 00000000..a39bfc51 --- /dev/null +++ b/config/scorecard/patches/olm.config.yaml @@ -0,0 +1,50 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-bundle-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-crds-have-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-crds-have-resources-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-spec-descriptors-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.0.1 + labels: + suite: olm + test: olm-status-descriptors-test diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 00000000..9cf26134 --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000..25e21e3c --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 00000000..31e0f829 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/pkg/controller/nexus/resource/deployment/deployment.go b/controllers/nexus/resource/deployment/deployment.go similarity index 98% rename from pkg/controller/nexus/resource/deployment/deployment.go rename to controllers/nexus/resource/deployment/deployment.go index b54ac8d4..7331198d 100644 --- a/pkg/controller/nexus/resource/deployment/deployment.go +++ b/controllers/nexus/resource/deployment/deployment.go @@ -26,8 +26,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) const ( diff --git a/pkg/controller/nexus/resource/deployment/deployment_test.go b/controllers/nexus/resource/deployment/deployment_test.go similarity index 97% rename from pkg/controller/nexus/resource/deployment/deployment_test.go rename to controllers/nexus/resource/deployment/deployment_test.go index ce50185d..85aa1e9a 100644 --- a/pkg/controller/nexus/resource/deployment/deployment_test.go +++ b/controllers/nexus/resource/deployment/deployment_test.go @@ -23,9 +23,9 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" + "github.com/m88i/nexus-operator/controllers/nexus/resource/validation" ) func Test_newDeployment_WithoutPersistence(t *testing.T) { diff --git a/pkg/controller/nexus/resource/deployment/manager.go b/controllers/nexus/resource/deployment/manager.go similarity index 96% rename from pkg/controller/nexus/resource/deployment/manager.go rename to controllers/nexus/resource/deployment/manager.go index fa50648d..5051501f 100644 --- a/pkg/controller/nexus/resource/deployment/manager.go +++ b/controllers/nexus/resource/deployment/manager.go @@ -21,13 +21,12 @@ import ( "github.com/RHsyseng/operator-utils/pkg/resource" "github.com/RHsyseng/operator-utils/pkg/resource/compare" - "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/framework" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -42,7 +41,7 @@ var managedObjectsRef = map[string]resource.KubernetesResource{ type Manager struct { nexus *v1alpha1.Nexus client client.Client - log *zap.SugaredLogger + log logger.Logger } // NewManager creates a deployment resources manager @@ -57,8 +56,8 @@ func NewManager(nexus *v1alpha1.Nexus, client client.Client) *Manager { // GetRequiredResources returns the resources initialized by the manager func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) { - m.log.Debugf("Generating required %s", framework.DeploymentKind) - m.log.Debugf("Generating required %s", framework.ServiceKind) + m.log.Debug("Generating required resource", "kind", framework.DeploymentKind) + m.log.Debug("Generating required resource", "kind", framework.ServiceKind) return []resource.KubernetesResource{newDeployment(m.nexus), newService(m.nexus)}, nil } diff --git a/pkg/controller/nexus/resource/deployment/manager_test.go b/controllers/nexus/resource/deployment/manager_test.go similarity index 98% rename from pkg/controller/nexus/resource/deployment/manager_test.go rename to controllers/nexus/resource/deployment/manager_test.go index 3779fbfb..eaff6a14 100644 --- a/pkg/controller/nexus/resource/deployment/manager_test.go +++ b/controllers/nexus/resource/deployment/manager_test.go @@ -26,8 +26,8 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/validation" "github.com/m88i/nexus-operator/pkg/logger" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/resource/deployment/service.go b/controllers/nexus/resource/deployment/service.go similarity index 92% rename from pkg/controller/nexus/resource/deployment/service.go rename to controllers/nexus/resource/deployment/service.go index 2c631104..3bcfa224 100644 --- a/pkg/controller/nexus/resource/deployment/service.go +++ b/controllers/nexus/resource/deployment/service.go @@ -18,8 +18,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) const ( diff --git a/pkg/controller/nexus/resource/deployment/service_test.go b/controllers/nexus/resource/deployment/service_test.go similarity index 90% rename from pkg/controller/nexus/resource/deployment/service_test.go rename to controllers/nexus/resource/deployment/service_test.go index 0a81583a..cd7c1c3f 100644 --- a/pkg/controller/nexus/resource/deployment/service_test.go +++ b/controllers/nexus/resource/deployment/service_test.go @@ -20,8 +20,8 @@ import ( "github.com/stretchr/testify/assert" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) func Test_newService(t *testing.T) { diff --git a/pkg/controller/nexus/resource/interfaces.go b/controllers/nexus/resource/interfaces.go similarity index 97% rename from pkg/controller/nexus/resource/interfaces.go rename to controllers/nexus/resource/interfaces.go index f2238d17..e4798f87 100644 --- a/pkg/controller/nexus/resource/interfaces.go +++ b/controllers/nexus/resource/interfaces.go @@ -20,7 +20,7 @@ import ( "github.com/RHsyseng/operator-utils/pkg/resource" "github.com/RHsyseng/operator-utils/pkg/resource/compare" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" ) // Supervisor is the resources manager for the nexus CR. diff --git a/pkg/controller/nexus/resource/meta/object.go b/controllers/nexus/resource/meta/object.go similarity index 94% rename from pkg/controller/nexus/resource/meta/object.go rename to controllers/nexus/resource/meta/object.go index ba433eba..74bf02e0 100644 --- a/pkg/controller/nexus/resource/meta/object.go +++ b/controllers/nexus/resource/meta/object.go @@ -17,7 +17,7 @@ package meta import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" ) const AppLabel = "app" diff --git a/pkg/controller/nexus/resource/networking/ingress.go b/controllers/nexus/resource/networking/ingress.go similarity index 90% rename from pkg/controller/nexus/resource/networking/ingress.go rename to controllers/nexus/resource/networking/ingress.go index b23e0e49..2997e8a0 100644 --- a/pkg/controller/nexus/resource/networking/ingress.go +++ b/controllers/nexus/resource/networking/ingress.go @@ -18,9 +18,9 @@ import ( "k8s.io/api/networking/v1beta1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) const ( diff --git a/pkg/controller/nexus/resource/networking/ingress_test.go b/controllers/nexus/resource/networking/ingress_test.go similarity index 96% rename from pkg/controller/nexus/resource/networking/ingress_test.go rename to controllers/nexus/resource/networking/ingress_test.go index b921a0a6..987270a4 100644 --- a/pkg/controller/nexus/resource/networking/ingress_test.go +++ b/controllers/nexus/resource/networking/ingress_test.go @@ -23,8 +23,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" ) var ( diff --git a/pkg/controller/nexus/resource/networking/manager.go b/controllers/nexus/resource/networking/manager.go similarity index 94% rename from pkg/controller/nexus/resource/networking/manager.go rename to controllers/nexus/resource/networking/manager.go index 86718777..3f320195 100644 --- a/pkg/controller/nexus/resource/networking/manager.go +++ b/controllers/nexus/resource/networking/manager.go @@ -21,13 +21,12 @@ import ( "github.com/RHsyseng/operator-utils/pkg/resource" "github.com/RHsyseng/operator-utils/pkg/resource/compare" routev1 "github.com/openshift/api/route/v1" - "go.uber.org/zap" networkingv1beta1 "k8s.io/api/networking/v1beta1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" "github.com/m88i/nexus-operator/pkg/cluster/openshift" "github.com/m88i/nexus-operator/pkg/framework" @@ -43,10 +42,9 @@ const ( // Manager is responsible for creating networking resources, fetching deployed ones and comparing them // Use with zero values will result in a panic. Use the NewManager function to get a properly initialized manager type Manager struct { - nexus *v1alpha1.Nexus - client client.Client - log *zap.SugaredLogger - + nexus *v1alpha1.Nexus + client client.Client + log logger.Logger routeAvailable, ingressAvailable, ocp bool } @@ -99,7 +97,7 @@ func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) return nil, fmt.Errorf(resUnavailableFormat, "routes") } - m.log.Debugf("Generating required %s", framework.RouteKind) + m.log.Debug("Generating required resource", "kind", framework.RouteKind) route := m.createRoute() resources = append(resources, route) @@ -108,7 +106,7 @@ func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) return nil, fmt.Errorf(resUnavailableFormat, "ingresses") } - m.log.Debugf("Generating required %s", framework.IngressKind) + m.log.Debug("Generating required resource", "kind", framework.IngressKind) ingress := m.createIngress() resources = append(resources, ingress) } diff --git a/pkg/controller/nexus/resource/networking/manager_test.go b/controllers/nexus/resource/networking/manager_test.go similarity index 98% rename from pkg/controller/nexus/resource/networking/manager_test.go rename to controllers/nexus/resource/networking/manager_test.go index b4dc2650..38be0afa 100644 --- a/pkg/controller/nexus/resource/networking/manager_test.go +++ b/controllers/nexus/resource/networking/manager_test.go @@ -27,8 +27,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" "github.com/m88i/nexus-operator/pkg/logger" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/resource/networking/route.go b/controllers/nexus/resource/networking/route.go similarity index 88% rename from pkg/controller/nexus/resource/networking/route.go rename to controllers/nexus/resource/networking/route.go index 2d7b6de4..9b1ce213 100644 --- a/pkg/controller/nexus/resource/networking/route.go +++ b/controllers/nexus/resource/networking/route.go @@ -19,9 +19,9 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) var serviceKind = (&corev1.Service{}).GroupVersionKind().Kind diff --git a/pkg/controller/nexus/resource/networking/route_test.go b/controllers/nexus/resource/networking/route_test.go similarity index 92% rename from pkg/controller/nexus/resource/networking/route_test.go rename to controllers/nexus/resource/networking/route_test.go index f394ba2f..f9fe0a71 100644 --- a/pkg/controller/nexus/resource/networking/route_test.go +++ b/controllers/nexus/resource/networking/route_test.go @@ -23,9 +23,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) var ( diff --git a/pkg/controller/nexus/resource/persistence/manager.go b/controllers/nexus/resource/persistence/manager.go similarity index 95% rename from pkg/controller/nexus/resource/persistence/manager.go rename to controllers/nexus/resource/persistence/manager.go index 3b310a1d..64d7d5a3 100644 --- a/pkg/controller/nexus/resource/persistence/manager.go +++ b/controllers/nexus/resource/persistence/manager.go @@ -19,12 +19,11 @@ import ( "reflect" "github.com/RHsyseng/operator-utils/pkg/resource" - "go.uber.org/zap" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/framework" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -38,7 +37,7 @@ var managedObjectsRef = map[string]resource.KubernetesResource{ type Manager struct { nexus *v1alpha1.Nexus client client.Client - log *zap.SugaredLogger + log logger.Logger } // NewManager creates a persistence resources manager @@ -58,7 +57,7 @@ func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) return resources, nil } - m.log.Debugf("Generating required %s", framework.PVCKind) + m.log.Debug("Generating required resource", "kind", framework.PVCKind) pvc := newPVC(m.nexus) resources = append(resources, pvc) diff --git a/pkg/controller/nexus/resource/persistence/manager_test.go b/controllers/nexus/resource/persistence/manager_test.go similarity index 98% rename from pkg/controller/nexus/resource/persistence/manager_test.go rename to controllers/nexus/resource/persistence/manager_test.go index 77a23190..9c333e06 100644 --- a/pkg/controller/nexus/resource/persistence/manager_test.go +++ b/controllers/nexus/resource/persistence/manager_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/logger" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/resource/persistence/pvc.go b/controllers/nexus/resource/persistence/pvc.go similarity index 91% rename from pkg/controller/nexus/resource/persistence/pvc.go rename to controllers/nexus/resource/persistence/pvc.go index aa98be03..854acd7d 100644 --- a/pkg/controller/nexus/resource/persistence/pvc.go +++ b/controllers/nexus/resource/persistence/pvc.go @@ -18,8 +18,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) func newPVC(nexus *v1alpha1.Nexus) *corev1.PersistentVolumeClaim { diff --git a/pkg/controller/nexus/resource/persistence/pvc_test.go b/controllers/nexus/resource/persistence/pvc_test.go similarity index 93% rename from pkg/controller/nexus/resource/persistence/pvc_test.go rename to controllers/nexus/resource/persistence/pvc_test.go index e688abda..cf5f68c6 100644 --- a/pkg/controller/nexus/resource/persistence/pvc_test.go +++ b/controllers/nexus/resource/persistence/pvc_test.go @@ -22,8 +22,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/validation" ) func Test_newPVC_defaultValues(t *testing.T) { diff --git a/pkg/controller/nexus/resource/resources.go b/controllers/nexus/resource/resources.go similarity index 89% rename from pkg/controller/nexus/resource/resources.go rename to controllers/nexus/resource/resources.go index c304b7f6..f9a87a76 100644 --- a/pkg/controller/nexus/resource/resources.go +++ b/controllers/nexus/resource/resources.go @@ -20,15 +20,15 @@ import ( "github.com/RHsyseng/operator-utils/pkg/resource" "github.com/RHsyseng/operator-utils/pkg/resource/compare" - "go.uber.org/zap" + "github.com/go-logr/logr" "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/networking" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/persistence" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/security" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/deployment" + "github.com/m88i/nexus-operator/controllers/nexus/resource/networking" + "github.com/m88i/nexus-operator/controllers/nexus/resource/persistence" + "github.com/m88i/nexus-operator/controllers/nexus/resource/security" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -38,7 +38,7 @@ type supervisor struct { client client.Client discoveryClient discovery.DiscoveryInterface managers []Manager - log *zap.SugaredLogger + log logr.Logger } // NewSupervisor creates a new resource manager for nexus CR diff --git a/pkg/controller/nexus/resource/security/manager.go b/controllers/nexus/resource/security/manager.go similarity index 93% rename from pkg/controller/nexus/resource/security/manager.go rename to controllers/nexus/resource/security/manager.go index 51f48be7..bb71f931 100644 --- a/pkg/controller/nexus/resource/security/manager.go +++ b/controllers/nexus/resource/security/manager.go @@ -19,12 +19,11 @@ import ( "reflect" "github.com/RHsyseng/operator-utils/pkg/resource" - "go.uber.org/zap" core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/framework" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -39,7 +38,7 @@ var managedObjectsRef = map[string]resource.KubernetesResource{ type Manager struct { nexus *v1alpha1.Nexus client client.Client - log *zap.SugaredLogger + log logger.Logger } // NewManager creates a security resources Manager @@ -53,8 +52,8 @@ func NewManager(nexus *v1alpha1.Nexus, client client.Client) *Manager { // GetRequiredResources returns the resources initialized by the Manager func (m *Manager) GetRequiredResources() ([]resource.KubernetesResource, error) { - m.log.Debugf("Generating required %s", framework.SvcAccountKind) - m.log.Debugf("Generating required %s", framework.SecretKind) + m.log.Debug("Generating required resource", "kind", framework.SvcAccountKind) + m.log.Debug("Generating required resource", "kind", framework.SecretKind) return []resource.KubernetesResource{defaultServiceAccount(m.nexus), defaultSecret(m.nexus)}, nil } diff --git a/pkg/controller/nexus/resource/security/manager_test.go b/controllers/nexus/resource/security/manager_test.go similarity index 98% rename from pkg/controller/nexus/resource/security/manager_test.go rename to controllers/nexus/resource/security/manager_test.go index 1dca6644..08087dd5 100644 --- a/pkg/controller/nexus/resource/security/manager_test.go +++ b/controllers/nexus/resource/security/manager_test.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/framework" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/resource/security/secret.go b/controllers/nexus/resource/security/secret.go similarity index 87% rename from pkg/controller/nexus/resource/security/secret.go rename to controllers/nexus/resource/security/secret.go index e14da651..052726b2 100644 --- a/pkg/controller/nexus/resource/security/secret.go +++ b/controllers/nexus/resource/security/secret.go @@ -17,8 +17,8 @@ package security import ( corev1 "k8s.io/api/core/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) // defaultSecret all purposes secret used by this instance diff --git a/pkg/controller/nexus/resource/security/service_account.go b/controllers/nexus/resource/security/service_account.go similarity index 87% rename from pkg/controller/nexus/resource/security/service_account.go rename to controllers/nexus/resource/security/service_account.go index 160ae51c..56e9f9e2 100644 --- a/pkg/controller/nexus/resource/security/service_account.go +++ b/controllers/nexus/resource/security/service_account.go @@ -17,8 +17,8 @@ package security import ( corev1 "k8s.io/api/core/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" ) func defaultServiceAccount(nexus *v1alpha1.Nexus) *corev1.ServiceAccount { diff --git a/pkg/controller/nexus/resource/validation/defaults.go b/controllers/nexus/resource/validation/defaults.go similarity index 98% rename from pkg/controller/nexus/resource/validation/defaults.go rename to controllers/nexus/resource/validation/defaults.go index 8ca00f20..e5978ec9 100644 --- a/pkg/controller/nexus/resource/validation/defaults.go +++ b/controllers/nexus/resource/validation/defaults.go @@ -19,7 +19,7 @@ import ( k8sres "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" ) const ( diff --git a/pkg/controller/nexus/resource/validation/events.go b/controllers/nexus/resource/validation/events.go similarity index 89% rename from pkg/controller/nexus/resource/validation/events.go rename to controllers/nexus/resource/validation/events.go index 7e5c8a51..6081059e 100644 --- a/pkg/controller/nexus/resource/validation/events.go +++ b/controllers/nexus/resource/validation/events.go @@ -18,7 +18,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -29,6 +29,6 @@ func createChangedNexusEvent(nexus *v1alpha1.Nexus, scheme *runtime.Scheme, c cl log := logger.GetLoggerWithResource("validation_event", nexus) err := kubernetes.RaiseWarnEventf(nexus, scheme, c, changedNexusReason, "'%s' has been changed in %s/%s. Check the logs for more information", field, nexus.Namespace, nexus.Name) if err != nil { - log.Warnf("Unable to raise event for changing '%s' in Nexus CR: %v", field, err) + log.Error(err, "Unable to raise event for changing in Nexus CR", "field", field) } } diff --git a/pkg/controller/nexus/resource/validation/events_test.go b/controllers/nexus/resource/validation/events_test.go similarity index 96% rename from pkg/controller/nexus/resource/validation/events_test.go rename to controllers/nexus/resource/validation/events_test.go index 05e0a953..43cbf52d 100644 --- a/pkg/controller/nexus/resource/validation/events_test.go +++ b/controllers/nexus/resource/validation/events_test.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/resource/validation/validation.go b/controllers/nexus/resource/validation/validation.go similarity index 75% rename from pkg/controller/nexus/resource/validation/validation.go rename to controllers/nexus/resource/validation/validation.go index faa422b3..820bd41e 100644 --- a/pkg/controller/nexus/resource/validation/validation.go +++ b/controllers/nexus/resource/validation/validation.go @@ -18,30 +18,28 @@ import ( "fmt" "strings" - "go.uber.org/zap" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/update" "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" "github.com/m88i/nexus-operator/pkg/cluster/openshift" - "github.com/m88i/nexus-operator/pkg/controller/nexus/update" "github.com/m88i/nexus-operator/pkg/logger" ) const ( discOCPFailureFormat = "unable to determine if cluster is Openshift: %v" discFailureFormat = "unable to determine if %s are available: %v" // resource type, error - unspecifiedExposeAsFormat = "'spec.exposeAs' left unspecified, setting it to %s" + unspecifiedExposeAsFormat = "'spec.exposeAs' left unspecified, setting to: " ) type Validator struct { - client client.Client - scheme *runtime.Scheme - log *zap.SugaredLogger - + client client.Client + scheme *runtime.Scheme + log logger.Logger routeAvailable, ingressAvailable, ocp bool } @@ -84,37 +82,37 @@ func (v *Validator) validate(nexus *v1alpha1.Nexus) error { func (v *Validator) validateNetworking(nexus *v1alpha1.Nexus) error { if !nexus.Spec.Networking.Expose { - v.log.Debugf("'spec.networking.expose' set to 'false', ignoring networking configuration") + v.log.Debug("'spec.networking.expose' set to 'false', ignoring networking configuration") return nil } if !v.ingressAvailable && nexus.Spec.Networking.ExposeAs == v1alpha1.IngressExposeType { - v.log.Errorf("Ingresses are not available on your cluster. Make sure to be running Kubernetes > 1.14 or if you're running Openshift set 'spec.networking.exposeAs' to '%s'. Alternatively you may also try '%s'", v1alpha1.IngressExposeType, v1alpha1.NodePortExposeType) + v.log.Warn("Ingresses are not available on your cluster. Make sure to be running Kubernetes > 1.14 or if you're running Openshift set ", "spec.networking.exposeAs", v1alpha1.IngressExposeType, "Also try", v1alpha1.NodePortExposeType) return fmt.Errorf("ingress expose required, but unavailable") } if !v.routeAvailable && nexus.Spec.Networking.ExposeAs == v1alpha1.RouteExposeType { - v.log.Errorf("Routes are not available on your cluster. If you're running Kubernetes 1.14 or higher try setting 'spec.networking.exposeAs' to '%s'. Alternatively you may also try '%s'", v1alpha1.IngressExposeType, v1alpha1.NodePortExposeType) + v.log.Warn("Routes are not available on your cluster. If you're running Kubernetes 1.14 or higher try setting ", "'spec.networking.exposeAs'", v1alpha1.IngressExposeType, "Also try", v1alpha1.NodePortExposeType) return fmt.Errorf("route expose required, but unavailable") } if nexus.Spec.Networking.ExposeAs == v1alpha1.NodePortExposeType && nexus.Spec.Networking.NodePort == 0 { - v.log.Errorf("NodePort networking requires a port. Check the Nexus resource 'spec.networking.nodePort' parameter") + v.log.Warn("NodePort networking requires a port. Check the Nexus resource 'spec.networking.nodePort' parameter") return fmt.Errorf("nodeport expose required, but no port informed") } if nexus.Spec.Networking.ExposeAs == v1alpha1.IngressExposeType && len(nexus.Spec.Networking.Host) == 0 { - v.log.Errorf("Ingress networking requires a host. Check the Nexus resource 'spec.networking.host' parameter") + v.log.Warn("Ingress networking requires a host. Check the Nexus resource 'spec.networking.host' parameter") return fmt.Errorf("ingress expose required, but no host informed") } if len(nexus.Spec.Networking.TLS.SecretName) > 0 && nexus.Spec.Networking.ExposeAs != v1alpha1.IngressExposeType { - v.log.Errorf("'spec.networking.tls.secretName' is only available when using an Ingress. Try setting 'spec.networking.exposeAs' to '%s'", v1alpha1.IngressExposeType) + v.log.Warn("'spec.networking.tls.secretName' is only available when using an Ingress. Try setting ", "spec.networking.exposeAs'", v1alpha1.IngressExposeType) return fmt.Errorf("tls secret name informed, but using route") } if nexus.Spec.Networking.TLS.Mandatory && nexus.Spec.Networking.ExposeAs != v1alpha1.RouteExposeType { - v.log.Errorf("'spec.networking.tls.mandatory' is only available when using a Route. Try setting 'spec.networking.exposeAs' to '%s'", v1alpha1.RouteExposeType) + v.log.Warn("'spec.networking.tls.mandatory' is only available when using a Route. Try setting ", "spec.networking.exposeAs'", v1alpha1.RouteExposeType) return fmt.Errorf("tls set to mandatory, but using ingress") } @@ -146,7 +144,7 @@ func (v *Validator) setResourcesDefaults(nexus *v1alpha1.Nexus) { func (v *Validator) setImageDefaults(nexus *v1alpha1.Nexus) { if nexus.Spec.UseRedHatImage { if len(nexus.Spec.Image) > 0 { - v.log.Warnf("Nexus CR configured to the use Red Hat Certified Image, ignoring 'spec.image' field.") + v.log.Warn("Nexus CR configured to the use Red Hat Certified Image, ignoring 'spec.image' field.") } nexus.Spec.Image = NexusCertifiedImage } else if len(nexus.Spec.Image) == 0 { @@ -158,7 +156,7 @@ func (v *Validator) setImageDefaults(nexus *v1alpha1.Nexus) { nexus.Spec.ImagePullPolicy != corev1.PullIfNotPresent && nexus.Spec.ImagePullPolicy != corev1.PullNever { - v.log.Warnf("Invalid 'spec.imagePullPolicy', unsetting the value. The pull policy will be determined by the image tag. Consider setting this value to '%s', '%s' or '%s'", corev1.PullAlways, corev1.PullIfNotPresent, corev1.PullNever) + v.log.Warn("Invalid 'spec.imagePullPolicy', unsetting the value. The pull policy will be determined by the image tag. Valid value are", "#1", corev1.PullAlways, "#2", corev1.PullIfNotPresent, "#3", corev1.PullNever) nexus.Spec.ImagePullPolicy = "" } } @@ -204,16 +202,16 @@ func (v *Validator) setUpdateDefaults(nexus *v1alpha1.Nexus) { image := strings.Split(nexus.Spec.Image, ":")[0] if image != NexusCommunityImage { - v.log.Warnf("Automatic Updates are enabled, but 'spec.image' is not using the community image (%s). Disabling automatic updates", NexusCommunityImage) + v.log.Warn("Automatic Updates are enabled, but 'spec.image' is not using the community image. Disabling automatic updates", "Community Image", NexusCommunityImage) nexus.Spec.AutomaticUpdate.Disabled = true return } if nexus.Spec.AutomaticUpdate.MinorVersion == nil { - v.log.Debugf("Automatic Updates are enabled, but no minor was informed. Fetching the most recent...") + v.log.Debug("Automatic Updates are enabled, but no minor was informed. Fetching the most recent...") minor, err := update.GetLatestMinor() if err != nil { - v.log.Errorf("Unable to fetch the most recent minor: %v. Disabling automatic updates.", err) + v.log.Error(err, "Unable to fetch the most recent minor. Disabling automatic updates.") nexus.Spec.AutomaticUpdate.Disabled = true createChangedNexusEvent(nexus, v.scheme, v.client, "spec.automaticUpdate.disabled") return @@ -221,26 +219,26 @@ func (v *Validator) setUpdateDefaults(nexus *v1alpha1.Nexus) { nexus.Spec.AutomaticUpdate.MinorVersion = &minor } - v.log.Debugf("Fetching the latest micro from minor %d", *nexus.Spec.AutomaticUpdate.MinorVersion) + v.log.Debug("Fetching the latest micro from minor", "MinorVersion", *nexus.Spec.AutomaticUpdate.MinorVersion) tag, ok := update.GetLatestMicro(*nexus.Spec.AutomaticUpdate.MinorVersion) if !ok { // the informed minor doesn't exist, let's try the latest minor - v.log.Warnf("Latest tag for minor version (%d) not found. Trying the latest minor instead", *nexus.Spec.AutomaticUpdate.MinorVersion) + v.log.Warn("Latest tag for minor version not found. Trying the latest minor instead", "Informed tag", *nexus.Spec.AutomaticUpdate.MinorVersion) minor, err := update.GetLatestMinor() if err != nil { - v.log.Errorf("Unable to fetch the most recent minor: %v. Disabling automatic updates.", err) + v.log.Error(err, "Unable to fetch the most recent minor: %v. Disabling automatic updates.") nexus.Spec.AutomaticUpdate.Disabled = true createChangedNexusEvent(nexus, v.scheme, v.client, "spec.automaticUpdate.disabled") return } - v.log.Infof("Setting 'spec.automaticUpdate.minorVersion to %d", minor) + v.log.Info("Setting 'spec.automaticUpdate.minorVersion to", "MinorTag", minor) nexus.Spec.AutomaticUpdate.MinorVersion = &minor // no need to check for the tag existence here, // we would have gotten an error from GetLatestMinor() if it didn't tag, _ = update.GetLatestMicro(minor) } newImage := fmt.Sprintf("%s:%s", image, tag) - v.log.Debugf("Replacing 'spec.image' (%s) with '%s'", nexus.Spec.Image, newImage) + v.log.Debug("Replacing 'spec.image'", "OldImage", nexus.Spec.Image, "NewImage", newImage) nexus.Spec.Image = newImage } @@ -251,16 +249,16 @@ func (v *Validator) setNetworkingDefaults(nexus *v1alpha1.Nexus) { if len(nexus.Spec.Networking.ExposeAs) == 0 { if v.ocp { - v.log.Infof(unspecifiedExposeAsFormat, v1alpha1.RouteExposeType) + v.log.Info(unspecifiedExposeAsFormat, "ExposeType", v1alpha1.RouteExposeType) nexus.Spec.Networking.ExposeAs = v1alpha1.RouteExposeType } else if v.ingressAvailable { - v.log.Infof(unspecifiedExposeAsFormat, v1alpha1.IngressExposeType) + v.log.Info(unspecifiedExposeAsFormat, "ExposeType", v1alpha1.IngressExposeType) nexus.Spec.Networking.ExposeAs = v1alpha1.IngressExposeType } else { // we're on kubernetes < 1.14 // try setting nodePort, validation will catch it if impossible v.log.Info("On Kubernetes, but Ingresses are not available") - v.log.Infof(unspecifiedExposeAsFormat, v1alpha1.NodePortExposeType) + v.log.Info(unspecifiedExposeAsFormat, "ExposeType", v1alpha1.NodePortExposeType) nexus.Spec.Networking.ExposeAs = v1alpha1.NodePortExposeType } } diff --git a/pkg/controller/nexus/resource/validation/validation_test.go b/controllers/nexus/resource/validation/validation_test.go similarity index 99% rename from pkg/controller/nexus/resource/validation/validation_test.go rename to controllers/nexus/resource/validation/validation_test.go index 41301582..073edbec 100644 --- a/pkg/controller/nexus/resource/validation/validation_test.go +++ b/controllers/nexus/resource/validation/validation_test.go @@ -22,8 +22,8 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/update" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/update" "github.com/m88i/nexus-operator/pkg/logger" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/server/log.go b/controllers/nexus/server/log.go similarity index 100% rename from pkg/controller/nexus/server/log.go rename to controllers/nexus/server/log.go diff --git a/pkg/controller/nexus/server/nexus.go b/controllers/nexus/server/nexus.go similarity index 96% rename from pkg/controller/nexus/server/nexus.go rename to controllers/nexus/server/nexus.go index 1b8ceb35..bf2d5d01 100644 --- a/pkg/controller/nexus/server/nexus.go +++ b/controllers/nexus/server/nexus.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -47,7 +47,7 @@ func handleServerOperations(nexus *v1alpha1.Nexus, client client.Client, nexusAP if nexus.Spec.GenerateRandomAdminPassword { return *s.status, nil } - log.Debugf("Initializing server operations in instance %s", nexus.Name) + log.Debug("Initializing server operations") if s.isServerReady() { internalEndpoint, err := s.getNexusEndpoint() if err != nil { diff --git a/pkg/controller/nexus/server/nexus_test.go b/controllers/nexus/server/nexus_test.go similarity index 97% rename from pkg/controller/nexus/server/nexus_test.go rename to controllers/nexus/server/nexus_test.go index f899fe23..f7ca882c 100644 --- a/pkg/controller/nexus/server/nexus_test.go +++ b/controllers/nexus/server/nexus_test.go @@ -29,8 +29,8 @@ import ( "github.com/m88i/aicura/nexus" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/meta" + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource/meta" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/server/repositories.go b/controllers/nexus/server/repositories.go similarity index 92% rename from pkg/controller/nexus/server/repositories.go rename to controllers/nexus/server/repositories.go index 6af497d7..3c5b90d0 100644 --- a/pkg/controller/nexus/server/repositories.go +++ b/controllers/nexus/server/repositories.go @@ -59,7 +59,7 @@ func (r *repositoryOperation) addCommunityReposToMavenCentralGroup() error { return err } if mavenCentral == nil { - log.Warnf("Maven Central repository group not found in the server instance, won't add community repos to the group") + log.Info("Maven Central repository group not found in the server instance, won't add community repos to the group") return nil } @@ -78,7 +78,7 @@ func (r *repositoryOperation) addCommunityReposToMavenCentralGroup() error { } if len(newMembers) > 0 { - log.Debugf("Community repositories to be added in the Maven Central group: %v", newMembers) + log.Debug("Community repositories to be added in the Maven Central group", "repositories", newMembers) mavenCentral.Group.MemberNames = append(mavenCentral.Group.MemberNames, newMembers...) err = r.nexuscli.MavenGroupRepositoryService.Update(*mavenCentral) @@ -97,7 +97,7 @@ func (r *repositoryOperation) createCommunityReposIfNotExists() error { var reposToAdd []nexus.MavenProxyRepository log.Debug("Attempt to create community repositories") for _, repo := range communityMavenProxies { - log.Debugf("Trying to fetch repository %s", repo.Name) + log.Debug("Trying to fetch repository", "Repo", repo.Name) fetchedRepo, err := r.nexuscli.MavenProxyRepositoryService.GetRepoByName(repo.Name) if err != nil { return err @@ -107,7 +107,7 @@ func (r *repositoryOperation) createCommunityReposIfNotExists() error { } } if len(reposToAdd) > 0 { - log.Debugf("Repositories to add %v", reposToAdd) + log.Debug("Repositories to add", "Repos", reposToAdd) if err := r.nexuscli.MavenProxyRepositoryService.Add(reposToAdd...); err != nil { return err } diff --git a/pkg/controller/nexus/server/repositories_test.go b/controllers/nexus/server/repositories_test.go similarity index 100% rename from pkg/controller/nexus/server/repositories_test.go rename to controllers/nexus/server/repositories_test.go diff --git a/pkg/controller/nexus/server/users.go b/controllers/nexus/server/users.go similarity index 100% rename from pkg/controller/nexus/server/users.go rename to controllers/nexus/server/users.go diff --git a/pkg/controller/nexus/server/users_test.go b/controllers/nexus/server/users_test.go similarity index 100% rename from pkg/controller/nexus/server/users_test.go rename to controllers/nexus/server/users_test.go diff --git a/pkg/controller/nexus/update/events.go b/controllers/nexus/update/events.go similarity index 84% rename from pkg/controller/nexus/update/events.go rename to controllers/nexus/update/events.go index 0585c3f0..8f53ae23 100644 --- a/pkg/controller/nexus/update/events.go +++ b/controllers/nexus/update/events.go @@ -18,7 +18,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" ) @@ -30,13 +30,13 @@ const ( func createUpdateSuccessEvent(nexus *v1alpha1.Nexus, scheme *runtime.Scheme, c client.Client, tag string) { err := kubernetes.RaiseInfoEventf(nexus, scheme, c, successfulUpdateReason, "Successfully updated to %s", tag) if err != nil { - log.Warnf("Unable to raise event for successful update of %s to %s: %v", nexus.Name, tag, err) + log.Error(err, "Unable to raise event for successful update", "tag", tag) } } func createUpdateFailureEvent(nexus *v1alpha1.Nexus, scheme *runtime.Scheme, c client.Client, tag string) { err := kubernetes.RaiseWarnEventf(nexus, scheme, c, failedUpdateReason, "Failed to update to %s. Human intervention may be required", tag) if err != nil { - log.Warnf("Unable to raise event for failed update of %s to %s: %v", nexus.Name, tag, err) + log.Error(err, "Unable to raise event for failed update", "tag", tag) } } diff --git a/pkg/controller/nexus/update/events_test.go b/controllers/nexus/update/events_test.go similarity index 97% rename from pkg/controller/nexus/update/events_test.go rename to controllers/nexus/update/events_test.go index 7658c089..92a30c75 100644 --- a/pkg/controller/nexus/update/events_test.go +++ b/controllers/nexus/update/events_test.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/update/log.go b/controllers/nexus/update/log.go similarity index 100% rename from pkg/controller/nexus/update/log.go rename to controllers/nexus/update/log.go diff --git a/pkg/controller/nexus/update/monitor.go b/controllers/nexus/update/monitor.go similarity index 88% rename from pkg/controller/nexus/update/monitor.go rename to controllers/nexus/update/monitor.go index 929e67c3..5bfaf1e6 100644 --- a/pkg/controller/nexus/update/monitor.go +++ b/controllers/nexus/update/monitor.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/logger" ) @@ -63,28 +63,28 @@ func HandleUpdate(nexus *v1alpha1.Nexus, deployed, required *appsv1.Deployment, // if this is a new update, the one that was happening before no longer matters // so we just reset the update state and return if newUpdate, previousTag, targetTag := isNewUpdate(deployed, required); newUpdate { - log.Infof("Update from %s to %s started", previousTag, targetTag) + log.Info("Started tags update", "previous", previousTag, "target", targetTag) // the Nexus status update can be delayed, let's leave it to the reconciler nexus.Status.UpdateConditions = []string{fmt.Sprintf(updateStartFormat, previousTag, targetTag)} return nil } if !alreadyUpdating(nexus) { - log.Debugf("No ongoing update, nothing to check") + log.Debug("No ongoing update, nothing to check") // nothing to monitor, let's return return nil } previousTag, targetTag, err := getUpdateTags(nexus) if err != nil { - log.Warnf("Failed to parse 'status.updateConditions' from %s: %v. Was it tampered with? Unable to monitor ongoing update, human intervention may be required.", deployed.Name, err) + log.Error(err, "Failed to parse 'status.updateConditions'. Was it tampered with? Unable to monitor ongoing update, human intervention may be required.", "deployment", deployed.Name) nexus.Status.UpdateConditions = nil return nil } for _, condition := range deployed.Status.Conditions { if condition.Type == appsv1.DeploymentProgressing && condition.Status == "False" { - log.Errorf("Update to %s failed: %s. %s. Human intervention may be required", targetTag, condition.Reason, condition.Message) + log.Warn("Update failed: Human intervention may be required", "target tag", targetTag, "Reason", condition.Reason, "Message", condition.Message) nexus.Status.UpdateConditions = append(nexus.Status.UpdateConditions, fmt.Sprintf(updateFailedFormat, previousTag, targetTag)) // we must return an error if we can't disable automatic updates @@ -100,7 +100,7 @@ func HandleUpdate(nexus *v1alpha1.Nexus, deployed, required *appsv1.Deployment, } if condition.Type == appsv1.DeploymentProgressing && condition.Reason == "NewReplicaSetAvailable" { - log.Infof("Successfully updated to %s", targetTag) + log.Info("Successfully updated", "tag", targetTag) // the Nexus status update can be delayed, let's leave it to the reconciler nexus.Status.UpdateConditions = append(nexus.Status.UpdateConditions, fmt.Sprintf(updateOKFormat, previousTag, targetTag)) createUpdateSuccessEvent(nexus, scheme, c, targetTag) @@ -129,7 +129,7 @@ func isNewUpdate(deployed, required *appsv1.Deployment) (updating bool, previous updating, err := HigherVersion(requiredImageParts[1], deployedImageParts[1]) if err != nil { - log.Warnf("Unable to check if the required Deployment (%s) is an update when comparing to the deployed one: %v", required.Name, err) + log.Error(err, "Unable to check if the required Deployment is an update when comparing to the deployed one", "deployment", required.Name) return } previousTag = deployedImageParts[1] @@ -163,7 +163,7 @@ func differentImagesOrMinors(deployed, required *appsv1.Deployment) bool { // the deployed one, on the other hand, might have been tampered with depMinor, err := getMinor(deployedImageParts[1]) if err != nil { - log.Warnf("Unable to parse the deployed Deployment's (%s) tag: %v. Cannot determine if this is an update. Has it been tampered with?", deployed.Name, err) + log.Error(err, "Unable to parse the deployed Deployment's tag. Cannot determine if this is an update. Has it been tampered with?", "deployment", deployed.Name) return true } diff --git a/pkg/controller/nexus/update/monitor_test.go b/controllers/nexus/update/monitor_test.go similarity index 99% rename from pkg/controller/nexus/update/monitor_test.go rename to controllers/nexus/update/monitor_test.go index 92d4a04c..fd9e4a52 100644 --- a/pkg/controller/nexus/update/monitor_test.go +++ b/controllers/nexus/update/monitor_test.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/nexus/update/tags.go b/controllers/nexus/update/tags.go similarity index 93% rename from pkg/controller/nexus/update/tags.go rename to controllers/nexus/update/tags.go index ce3fae12..acd0736e 100644 --- a/pkg/controller/nexus/update/tags.go +++ b/controllers/nexus/update/tags.go @@ -27,7 +27,7 @@ const ( communityNexusRegistry = "https://registry.hub.docker.com" communityNexusRepo = "sonatype/nexus3" tagParseFailureFormat = "unable to parse tag \"%s\": %v" - unableToCheckUpdatesFormat = "Unable to check for updates: %v" + unableToCheckUpdatesMsg = "Unable to check for updates" ) const ( @@ -97,20 +97,20 @@ func GetLatestMinor() (int, error) { func fetchUpdates() { if time.Since(lastErr) < errTTL { - log.Debugf("Trying to fetch tags from registry again too fast, must try again later") + log.Debug("Trying to fetch tags from registry again too fast, must try again later") return } tags, err := getTags() if err != nil { lastErr = time.Now() - log.Errorf(unableToCheckUpdatesFormat, err) + log.Error(err, unableToCheckUpdatesMsg) return } lastQuery = time.Now() if err = parseTagsAndUpdate(tags); err != nil { - log.Errorf(unableToCheckUpdatesFormat, err) + log.Error(err, unableToCheckUpdatesMsg) return } } @@ -122,8 +122,8 @@ func getTags() ([]string, error) { } // redirect the lib's logging to ours reg.Logf = func(format string, args ...interface{}) { - format = fmt.Sprintf("Registry: %s", format) - log.Infof(format, args) + format = fmt.Sprintf(fmt.Sprintf("Registry: %s", format), args) + log.Info(format) } repo := communityNexusRepo diff --git a/pkg/controller/nexus/update/tags_test.go b/controllers/nexus/update/tags_test.go similarity index 100% rename from pkg/controller/nexus/update/tags_test.go rename to controllers/nexus/update/tags_test.go diff --git a/controllers/nexus_controller.go b/controllers/nexus_controller.go new file mode 100644 index 00000000..b0725302 --- /dev/null +++ b/controllers/nexus_controller.go @@ -0,0 +1,312 @@ +// Copyright 2020 Nexus Operator and/or its authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controllers + +import ( + "context" + "fmt" + "reflect" + "time" + + resUtils "github.com/RHsyseng/operator-utils/pkg/resource" + "github.com/RHsyseng/operator-utils/pkg/resource/write" + "github.com/go-logr/logr" + routev1 "github.com/openshift/api/route/v1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + appsv1alpha1 "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource" + "github.com/m88i/nexus-operator/controllers/nexus/server" + "github.com/m88i/nexus-operator/controllers/nexus/update" + "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" + "github.com/m88i/nexus-operator/pkg/cluster/openshift" + "github.com/m88i/nexus-operator/pkg/framework" + + "github.com/m88i/nexus-operator/controllers/nexus/resource/validation" +) + +const ( + updatePollWaitTimeout = 500 * time.Millisecond + updateCancelTimeout = 30 * time.Second +) + +// NexusReconciler reconciles a Nexus object +type NexusReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + DiscoveryClient discovery.DiscoveryInterface + Supervisor resource.Supervisor +} + +// +kubebuilder:rbac:groups=apps.m88i.io,resources=nexus,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps.m88i.io,resources=nexus/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=core,resources=services;persistentvolumeclaims;events;secrets;serviceaccounts,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;create +// +kubebuilder:rbac:groups=core,resources=pods,verbs=get +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=get +// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers,verbs=update +// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create +// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=create;delete;get;list;patch;update;watch + +func (r *NexusReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { + _ = context.Background() + _ = r.Log.WithValues("nexus", req.NamespacedName) + + r.Log.Info("Reconciling Nexus") + result := ctrl.Result{} + + // Fetch the Nexus instance + instance := &appsv1alpha1.Nexus{} + err := r.Get(context.TODO(), req.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return result, nil + } + // Error reading the object - requeue the request. + return result, err + } + + v, err := validation.NewValidator(r, r.Scheme, r.DiscoveryClient) + if err != nil { + // Error using the discovery API - requeue the request. + return result, err + } + + validatedNexus, err := v.SetDefaultsAndValidate(instance) + // In case of any errors from here, we should update the Nexus CR and its status + defer r.updateNexus(validatedNexus, instance, &err) + if err != nil { + return result, err + } + + // Initialize the resource managers + err = r.Supervisor.InitManagers(validatedNexus) + if err != nil { + return result, err + } + // Create the objects as desired by the Nexus instance + requiredRes, err := r.Supervisor.GetRequiredResources() + if err != nil { + return result, err + } + // Get the actual deployed objects + deployedRes, err := r.Supervisor.GetDeployedResources() + if err != nil { + return result, err + } + // Get the resource comparator + comparator, err := r.Supervisor.GetComparator() + if err != nil { + return result, err + } + deltas := comparator.Compare(deployedRes, requiredRes) + + writer := write.New(r).WithOwnerController(validatedNexus, r.Scheme) + for resourceType, delta := range deltas { + if !delta.HasChanges() { + continue + } + r.Log.Info("Will ", + "create ", len(delta.Added), + ", update ", len(delta.Updated), + ", delete ", len(delta.Removed), + " instances of ", resourceType) + _, err = writer.AddResources(delta.Added) + if err != nil { + return result, err + } + _, err = writer.UpdateResources(deployedRes[resourceType], delta.Updated) + if err != nil { + return result, err + } + _, err = writer.RemoveResources(delta.Removed) + if err != nil { + return result, err + } + } + + if err = r.ensureServerUpdates(validatedNexus); err != nil { + return result, err + } + + // Check if we are performing an update and act upon it if needed + err = r.handleUpdate(validatedNexus, requiredRes, deployedRes) + return result, err +} + +func (r *NexusReconciler) SetupWithManager(mgr ctrl.Manager) error { + b := ctrl.NewControllerManagedBy(mgr). + For(&appsv1alpha1.Nexus{}). + Owns(&corev1.Service{}). + Owns(&appsv1.Deployment{}). + Owns(&corev1.PersistentVolumeClaim{}). + Owns(&corev1.ServiceAccount{}) + + ocp, err := openshift.IsOpenShift(r.DiscoveryClient) + if err != nil { + return err + } + if ocp { + b.Owns(&routev1.Route{}) + } else { + b.Owns(&networking.Ingress{}) + } + return b.Complete(r) +} + +func (r *NexusReconciler) handleUpdate(nexus *appsv1alpha1.Nexus, required, deployed map[reflect.Type][]resUtils.KubernetesResource) error { + requiredDeployment := required[reflect.TypeOf(appsv1.Deployment{})][0].(*appsv1.Deployment) + deployedDeployments := deployed[reflect.TypeOf(appsv1.Deployment{})] + if len(deployedDeployments) == 0 { + // nothing previously deployed, not an update + return nil + } + deployedDeployment := deployedDeployments[0].(*appsv1.Deployment) + return update.HandleUpdate(nexus, deployedDeployment, requiredDeployment, r.Scheme, r) +} + +func (r *NexusReconciler) ensureServerUpdates(instance *appsv1alpha1.Nexus) error { + r.Log.Info("Performing Nexus server operations if needed") + status, err := server.HandleServerOperations(instance, r) + if err != nil { + return err + } + r.Log.Info("Server Operations finished", "Status", status) + instance.Status.ServerOperationsStatus = status + return nil +} + +func (r *NexusReconciler) updateNexus(nexus *appsv1alpha1.Nexus, originalNexus *appsv1alpha1.Nexus, err *error) { + r.Log.Info("Updating application status before leaving") + + if statusErr := r.getNexusDeploymentStatus(nexus); statusErr != nil { + r.Log.Error(*err, "Error while fetching Nexus Deployment status") + } + + if *err != nil { + nexus.Status.Reason = fmt.Sprintf("Failed to deploy Nexus: %s", *err) + nexus.Status.NexusStatus = appsv1alpha1.NexusStatusFailure + } else { + nexus.Status.Reason = "" + if nexus.Status.DeploymentStatus.AvailableReplicas == nexus.Spec.Replicas { + nexus.Status.NexusStatus = appsv1alpha1.NexusStatusOK + } else { + nexus.Status.NexusStatus = appsv1alpha1.NexusStatusPending + } + } + + if urlErr := r.getNexusURL(nexus); urlErr != nil { + r.Log.Error(urlErr, "Error while fetching Nexus URL status") + } + + if !reflect.DeepEqual(originalNexus.Spec, nexus.Spec) { + r.Log.Info("Updating Nexus instance ", "Nexus instance", nexus.Name) + waitErr := wait.Poll(updatePollWaitTimeout, updateCancelTimeout, func() (bool, error) { + if updateErr := r.Update(context.TODO(), nexus); errors.IsConflict(updateErr) { + newNexus := &appsv1alpha1.Nexus{ObjectMeta: v1.ObjectMeta{ + Name: nexus.Name, + Namespace: nexus.Namespace, + }} + if err := r.Get(context.TODO(), framework.Key(newNexus), newNexus); err != nil { + return false, err + } + // we override only the spec, which we are interested into + newNexus.Spec = nexus.Spec + nexus = newNexus + return false, nil + } else if updateErr != nil { + return false, updateErr + } + return true, nil + }) + if waitErr != nil { + r.Log.Error(waitErr, "Error while updating Nexus status") + } + } + + if !reflect.DeepEqual(originalNexus.Status, nexus.Status) { + r.Log.Info("Updating status for ", "Nexus instance", nexus.Name) + waitErr := wait.Poll(updatePollWaitTimeout, updateCancelTimeout, func() (bool, error) { + if updateErr := r.Status().Update(context.TODO(), nexus); errors.IsConflict(updateErr) { + newNexus := &appsv1alpha1.Nexus{ObjectMeta: v1.ObjectMeta{ + Name: nexus.Name, + Namespace: nexus.Namespace, + }} + if err := r.Get(context.TODO(), framework.Key(newNexus), newNexus); err != nil { + return false, err + } + // we override only the spec, which we are interested into + newNexus.Status = nexus.Status + nexus = newNexus + return false, nil + } else if updateErr != nil { + return false, updateErr + } + return true, nil + }) + if waitErr != nil { + r.Log.Error(waitErr, "Error while updating Nexus status") + } + } + + r.Log.Info("Controller finished reconciliation") +} + +func (r *NexusReconciler) getNexusDeploymentStatus(nexus *appsv1alpha1.Nexus) error { + r.Log.Info("Checking Deployment Status") + deployment := &appsv1.Deployment{} + if err := r.Get(context.TODO(), types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}, deployment); err != nil { + if !errors.IsNotFound(err) { + return err + } + } + nexus.Status.DeploymentStatus = deployment.Status + return nil +} + +func (r *NexusReconciler) getNexusURL(nexus *appsv1alpha1.Nexus) error { + if nexus.Spec.Networking.Expose { + var err error + uri := "" + if nexus.Spec.Networking.ExposeAs == appsv1alpha1.RouteExposeType { + r.Log.Info("Checking Route Status") + uri, err = openshift.GetRouteURI(r, r.DiscoveryClient, types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}) + } else if nexus.Spec.Networking.ExposeAs == appsv1alpha1.IngressExposeType { + r.Log.Info("Checking Ingress Status") + uri, err = kubernetes.GetIngressURI(r, types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}) + } + if err != nil { + return err + } + nexus.Status.NexusRoute = uri + } + return nil +} diff --git a/controllers/nexus_controller_test.go b/controllers/nexus_controller_test.go new file mode 100644 index 00000000..ba38cb16 --- /dev/null +++ b/controllers/nexus_controller_test.go @@ -0,0 +1,106 @@ +// Copyright 2020 Nexus Operator and/or its authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controllers + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/pkg/logger" +) + +var _ = Describe("Nexus Controller", func() { + // Define utility constants for object names and testing timeouts/durations and intervals. + const ( + NexusName = "nexus3" + NexusNamespace = "default" + + cpu = "2" + memory = "2Gi" + exposedPort = 31031 + + timeout = time.Minute * 1 + interval = time.Second * 10 + ) + + var ( + log = logger.GetLogger("integration-test") + defaultNexus = &v1alpha1.Nexus{ + ObjectMeta: metav1.ObjectMeta{ + Name: NexusName, + Namespace: NexusNamespace, + }, + Spec: v1alpha1.NexusSpec{ + Replicas: 1, + UseRedHatImage: false, + Resources: v1.ResourceRequirements{ + Limits: map[v1.ResourceName]resource.Quantity{ + v1.ResourceCPU: resource.MustParse(cpu), + v1.ResourceMemory: resource.MustParse(memory), + }, + }, + Persistence: v1alpha1.NexusPersistence{Persistent: false}, + Networking: v1alpha1.NexusNetworking{ + Expose: true, + ExposeAs: v1alpha1.NodePortExposeType, + NodePort: exposedPort, + }, + }, + } + ) + + Context("When creating a simple Nexus3 instance with no persistence, community image and NodePort exposed", func() { + It("Should have nexusStatus set to Pending", func() { + ctx := context.Background() + nexus := defaultNexus.DeepCopy() + + Expect(k8sClient.Create(ctx, nexus)).Should(Succeed()) + + deployment := &appsv1.Deployment{} + Eventually(func() bool { + err := k8sClient.Get(ctx, types.NamespacedName{Name: NexusName, Namespace: NexusNamespace}, deployment) + return err == nil + }, timeout, interval).Should(BeTrue()) + + // there's no controllers deployed in this environment, so the Deployment would never hava a pod deployed, + // status would never change to "OK". + // We basically verify if the controller is reconciling correct, status will be always Pending + createdNexus := &v1alpha1.Nexus{} + Eventually(func() bool { + log.Info("Waiting for nexus instance to have ", "status", v1alpha1.NexusStatusPending) + err := k8sClient.Get(ctx, types.NamespacedName{Name: NexusName, Namespace: NexusNamespace}, createdNexus) + if errors.IsNotFound(err) { + return false + } else if err != nil { + log.Error(err, "Failed to fetch Nexus instance", "Name", NexusName, "Namespace", NexusNamespace) + return false + } + log.Info("Returning after fetching Nexus instance", "status", createdNexus.Status.NexusStatus) + return createdNexus.Status.NexusStatus == v1alpha1.NexusStatusPending + }, timeout, interval).Should(BeTrue()) + }) + }) + +}) diff --git a/controllers/suite_test.go b/controllers/suite_test.go new file mode 100644 index 00000000..b5f940ee --- /dev/null +++ b/controllers/suite_test.go @@ -0,0 +1,101 @@ +// Copyright 2020 Nexus Operator and/or its authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/client-go/discovery" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + appsv1alpha1 "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers/nexus/resource" + // +kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +var _ = BeforeSuite(func(done Done) { + logf.SetLogger(zap.LoggerTo(GinkgoWriter, true)) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + } + + var err error + cfg, err = testEnv.Start() + Expect(err).ToNot(HaveOccurred()) + Expect(cfg).ToNot(BeNil()) + + err = appsv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + // +kubebuilder:scaffold:scheme + + k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{Scheme: scheme.Scheme}) + Expect(err).ToNot(HaveOccurred()) + Expect(k8sManager).ToNot(BeNil()) + + discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(k8sManager.GetConfig()) + err = (&NexusReconciler{ + Client: k8sManager.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Nexus"), + DiscoveryClient: discoveryClient, + Supervisor: resource.NewSupervisor(k8sManager.GetClient(), discoveryClient), + Scheme: k8sManager.GetScheme(), + }).SetupWithManager(k8sManager) + Expect(err).ToNot(HaveOccurred()) + + go func() { + err = k8sManager.Start(ctrl.SetupSignalHandler()) + Expect(err).ToNot(HaveOccurred()) + }() + + k8sClient = k8sManager.GetClient() + Expect(err).ToNot(HaveOccurred()) + Expect(k8sClient).ToNot(BeNil()) + + close(done) +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).ToNot(HaveOccurred()) +}) diff --git a/deploy/namespace.yaml b/deploy/namespace.yaml deleted file mode 100644 index 8269bfee..00000000 --- a/deploy/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: operators diff --git a/deploy/olm-catalog/nexus-operator/0.1.0/apps.m88i.io_nexus_crd.yaml b/deploy/olm-catalog/nexus-operator/0.1.0/apps.m88i.io_nexus_crd.yaml deleted file mode 100644 index ce7bc74f..00000000 --- a/deploy/olm-catalog/nexus-operator/0.1.0/apps.m88i.io_nexus_crd.yaml +++ /dev/null @@ -1,198 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: nexus.apps.m88i.io -spec: - group: apps.m88i.io - names: - kind: Nexus - listKind: NexusList - plural: nexus - singular: nexus - scope: Namespaced - validation: - openAPIV3Schema: - description: Nexus is the Schema for the nexus 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: - type: object - spec: - description: NexusSpec defines the desired state of Nexus - properties: - image: - description: 'Full image tag name for this specific deployment Default: - docker.io/sonatype/nexus3:latest' - type: string - networking: - description: Networking definition - properties: - expose: - description: Set to `true` to expose the Nexus application. Default - to false. - type: boolean - exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Default to Route on OpenShift and Ingress on Kubernetes.' - enum: - - NodePort - - Route - - Ingress - type: string - host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. - type: string - nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. - format: int32 - type: integer - type: object - persistence: - description: Persistence definition - properties: - persistent: - description: Flag to indicate if this instance will be persistent - or not - type: boolean - volumeSize: - description: 'If persistent, the size of the Volume. Defaults: 10Gi' - type: string - required: - - persistent - type: object - replicas: - description: 'Number of pods replicas desired Default: 1' - format: int32 - maximum: 100 - minimum: 1 - type: integer - resources: - description: Defined Resources for the Nexus instance - properties: - limits: - additionalProperties: - type: string - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - type: string - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - useRedHatImage: - description: 'If you have access to Red Hat Container Catalog, turn - this to true to use the certified image provided by Sonatype Default: - false' - type: boolean - required: - - persistence - - replicas - type: object - status: - description: NexusStatus defines the observed state of Nexus - properties: - deploymentStatus: - description: Condition status for the Nexus deployment - properties: - availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. - format: int32 - type: integer - collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. - format: int32 - type: integer - conditions: - description: Represents the latest available observations of a deployment's - current state. - items: - description: DeploymentCondition describes the state of a deployment - at a certain point. - properties: - lastTransitionTime: - description: Last time the condition transitioned from one - status to another. - format: date-time - type: string - lastUpdateTime: - description: The last time this condition was updated. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of deployment condition. - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: The generation observed by the deployment controller. - format: int64 - type: integer - readyReplicas: - description: Total number of ready pods targeted by this deployment. - format: int32 - type: integer - replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). - format: int32 - type: integer - unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. - format: int32 - type: integer - updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. - format: int32 - type: integer - type: object - nexusRoute: - description: Route for external service access - type: string - nexusStatus: - description: Will be "OK" when all objects are created successfully - type: string - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/olm-catalog/nexus-operator/0.1.0/nexus-operator.v0.1.0.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/0.1.0/nexus-operator.v0.1.0.clusterserviceversion.yaml deleted file mode 100644 index f0e40fa5..00000000 --- a/deploy/olm-catalog/nexus-operator/0.1.0/nexus-operator.v0.1.0.clusterserviceversion.yaml +++ /dev/null @@ -1,271 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "apps.m88i.io/v1alpha1", - "kind": "Nexus", - "metadata": { - "name": "nexus3" - }, - "spec": { - "networking": { - "expose": true - }, - "persistence": { - "persistent": true, - "volumeSize": "10Gi" - }, - "replicas": 1, - "resources": { - "limits": { - "cpu": "2", - "memory": "2Gi" - }, - "requests": { - "cpu": "1", - "memory": "2Gi" - } - }, - "useRedHatImage": false - } - } - ] - capabilities: Basic Install - categories: Developer Tools - certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.1.0 - createdAt: "2019-11-16T13:12:22Z" - description: Nexus Operator to deploy and manage Nexus 3.x servers - repository: https://github.com/m88i/nexus-operator - support: m88i Labs - tectonic-visibility: ocs - labels: - nexus-operator: "true" - name: nexus-operator.v0.1.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Representation of a Nexus 3.x server - displayName: Nexus - kind: Nexus - name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: "" - version: apps/v1 - - kind: Service - name: "" - version: v1 - - kind: PersistentVolumeClaim - name: "" - version: v1 - specDescriptors: - - description: Replicas - displayName: Replicas - path: replicas - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:podCount - - description: Image - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: Resources - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: Volume Size - displayName: Volume Size - path: persistence.volumeSize - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:label - - description: Indicates if is using a Red Hat certifed image or not - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Indicates if Nexus service should be exposed - displayName: Expose - path: networking.expose - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - - description: Networking expose method - displayName: Expose As - path: networking.exposeAs - statusDescriptors: - - description: Nexus server deployment conditions - displayName: Deployment Conditions - path: deploymentStatus.conditions - x-descriptors: - - urn:alm:descriptor:io.kubernetes.conditions - - description: Nexus Operator Status - displayName: Nexus Operator Status - path: nexusStatus - - description: External Route - displayName: External Route - path: nexusRoute - x-descriptors: - - urn:alm:descriptor:org.w3:link - version: v1alpha1 - description: |- - Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: - - * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world - * On OpenShift, creates a Route to expose the service outside the cluster - - After installing it, you will have to grab the `admin` user password from the deployed container. There's a file auto generated in `/nexus-data/admin.password`. - Use `cat` to read the file and view the password. Use it to login for the first time and follow the on screen instructions to have the Nexus server ready for use. - - If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues). - - *Please note that the operator is an individual work and it's not provided nor supported by Sonatype.* - displayName: Nexus Operator - icon: - - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgcm9sZT0iaW1nIgogICB2aWV3Qm94PSI4LjM3IDUuODcgNTYxLjI0MTYzIDQ3My40NDQ0NSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnNDE2NyIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic29uYXR5cGUtbmV4dXMtY3JvcC5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTIuNCAodW5rbm93bikiCiAgIHdpZHRoPSI1NjEuMjQxNjQiCiAgIGhlaWdodD0iNDczLjQ0NDQ2Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE0MTczIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT5Tb25hdHlwZSBOZXh1cyBsb2dvPC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczQxNzEiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijk5MCIKICAgICBpZD0ibmFtZWR2aWV3NDE2OSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMS4wNTE1OCIKICAgICBpbmtzY2FwZTpjeD0iMjgwLjQ2NzY3IgogICAgIGlua3NjYXBlOmN5PSIxMDcuOTk0NDQiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc0MTY3IiAvPgogIDx0aXRsZQogICAgIGlkPSJ0aXRsZTM5NjMiPlNvbmF0eXBlIE5leHVzIGxvZ288L3RpdGxlPgogIDxzdHlsZQogICAgIGlkPSJzdHlsZTM5NjUiPnN2ZyB7ZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2MDAgNzY0fTwvc3R5bGU+CiAgPHN0eWxlCiAgICAgaWQ9InN0eWxlMzk2NyI+LnN0NXtmaWxsOiNkNGQ0ZDR9LnN0NTR7ZmlsbDojMzI2Nzk4fS5zdDU1e2ZpbGw6I2ViZWJlYn0uc3Q1NntmaWxsOiMwMjAyMDJ9LnN0NTd7ZmlsbDojZWNlY2VjfS5zdDU4e2ZpbGw6IzAxMDEwMX0uc3Q2MHtmaWxsOiMwNDA0MDR9LnN0NjF7ZmlsbDojYmRiZGJkfS5zdDYye2ZpbGw6I2U4ZThlOH0uc3Q2M3tmaWxsOiNjZGNkY2V9LnN0NjR7ZmlsbDojY2ZjZmNmfTwvc3R5bGU+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAxLjksNS41IDQuNSwxMC42IDguNiwxNSA3LjIsNC45IDE1LjEsNi4xIDIzLjcsNi4xIDE2MS43OTk5OTcsLTAuMiAzMjMuNTk5OTk3LC0wLjIgNDg1LjM5OTk5NywwIDguNiwwIDE2LjUsLTEuMiAyMy43LC02LjEgNCwtNC4zIDYuNywtOS40IDguNiwtMTUgMC42LC02LjMgLTAuNywtMTIuMiAtMy4xLC0xOCAtNi42LC05LjMgLTE1LjUsLTEyLjggLTI2LjksLTEyLjggLTE2My4zLDAuMiAtMzI2LjYsMC4yIC00ODkuODk5OTk3LDAgLTExLjQsMCAtMjAuMywzLjUgLTI2LjksMTIuOCAtMi41LDUuOCAtMy44LDExLjggLTMuMiwxOCB6IG0gMC4xLC04Mi4zIGMgMi4xLDUuMSA0LjQsMTAgOC4zLDEzLjkgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNTk5OTk3LC0wLjEgMzI1LjE5OTk5NywtMC4xIDQ4Ny43OTk5OTcsMCA3LjYsMCAxNC43LC0wLjggMjEuNCwtNC43IDIuMywtMi43IDQuNywtNS40IDcsLTguMSAxLC0zLjIgMiwtNi40IDMsLTkuNyAwLjQsLTYuNSAtMS44LC0xMi4zIC00LjgsLTE3LjkgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTEuNCwzLjcgLTQuOSw2LjUgLTQuNywxMSAwLjIsMy41IDAuMiw2LjcgMC4zLDkuOCB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk2OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzNjMuODcgYyAxLjEsMi4xIC0wLjMsNC45IDEuNiw2LjggMi40LDMuOSA1LDcuNyA4LjUsMTAuOSA2LjQsMy44IDEzLjMsNC43IDIwLjYsNC43IDE2My4wOTk5OTcsLTAuMSAzMjYuMTk5OTk3LC0wLjEgNDg5LjE5OTk5NywwIDgsMCAxNS4xLC0xLjQgMjEuNiwtNS45IDQuNSwtNC42IDYuOCwtMTAuNCA4LjYsLTE2LjUgMC4yLC02IC0xLjQsLTExLjUgLTQuMSwtMTYuNyAtNi4zLC04LjEgLTE0LjUsLTExLjIgLTI0LjgsLTExLjIgLTE2NC4yLDAuMSAtMzI4LjMsMC4xIC00OTIuNDk5OTk3LDAgLTEwLjMsMCAtMTguNSwzLjEgLTI0LjgsMTEuMiAtMi41LDUuMiAtNC4xLDEwLjggLTMuOSwxNi43IHoiCiAgICAgaWQ9InBhdGgzOTcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIDEuNCw2LjMgNC4xLDExLjkgOC42LDE2LjUgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNzk5OTk3LC0wLjEgMzI1LjQ5OTk5NywtMC4xIDQ4OC4yOTk5OTcsMCA4LjIsMCAxNS42LC0xLjMgMjIuNCwtNS44IDMuOSwtNCA2LjMsLTguOSA4LjMsLTEzLjkgMCwtMy4yIDAuMSwtNi40IDAuMSwtOS42IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTEgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTIuOSw1LjcgLTUuMSwxMS42IC00LjcsMTguMSB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk3MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywyODEuNzcgYyAxLjMsNi4zIDQuMiwxMS44IDguNiwxNi41IDYuNiw0LjQgMTMuNyw1LjkgMjEuNyw1LjkgMTYzLjE5OTk5NywtMC4xIDMyNi40OTk5OTcsLTAuMSA0ODkuNjk5OTk3LDAgOCwwIDE1LjEsLTEuNSAyMS43LC01LjkgMy44LC00IDYuNCwtOC44IDguMywtMTMuOSBsIDAuMywtOC4xIC00LjgsLTEyLjMgYyAtNi40LC03LjIgLTE0LjMsLTEwLjEgLTI0LC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC0xMC4zLDAgLTE4LjUsMy4xIC0yNC44LDExLjIgLTIuOCw1LjIgLTQuNCwxMC43IC00LjIsMTYuNyB6IG0gMCwxNjQuMyBjIDEuMyw2LjMgNC4yLDExLjggOC42LDE2LjUgNi42LDQuNCAxMy43LDUuOSAyMS43LDUuOSAxNjMuMTk5OTk3LC0wLjEgMzI2LjQ5OTk5NywtMC4xIDQ4OS42OTk5OTcsMCA4LDAgMTUuMSwtMS41IDIxLjcsLTUuOSAzLjgsLTQgNi40LC04LjggOC4zLC0xMy45IDAuMSwtMy4yIDAuMSwtNi40IDAuMiwtOS41IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTAuOSAtNi42LC03LjYgLTE0LjgsLTEwLjIgLTI0LjgsLTEwLjIgLTE2My43LDAuMiAtMzI3LjUsMC4yIC00OTEuMTk5OTk3LDAgLTkuOSwwIC0xOC4xLDIuNiAtMjQuNywxMC4xIC0zLjEsNS41IC01LjIsMTEuNCAtNC44LDE3LjkgeiIKICAgICBpZD0icGF0aDM5NzUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNDMuNjg3NjYzLDIzMi45NyBIIDQyMi4yODc2NiBjIDM3LjYsMCA3NS4yLDAuMiAxMTIuOCwtMC4xIDE0LjIsLTAuMSAyNS41LC02IDMxLjcsLTE5LjUgNS4zLC0xMS42IDIuOCwtMjQuNSAtNS45LC0zMC40IDUsNC45IDUuNSwxMS4xIDQuNywxNy41IC0wLjMsMS4xIC0wLjYsMi4xIC0wLjksMy4yIDEsOC45IC03LjUsMTkuMiAtMTQuNSwyMiAtNC43LDEuOSAtOS41LDMuMSAtMTQuOCwzLjEgLTE2NC4yLC0wLjEgLTMyOC4zLC0wLjEgLTQ5Mi40OTk5OTcsLTAuMSAtMTUuOSwwIC0yNi42LC04LjMgLTI5LjYsLTIyLjggLTAuMywtMS4zIC0wLjYsLTIuNSAtMC4yLC0zLjcgLTAuMiwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuOCwtNi41IC0wLjQsLTEyLjcgNC43LC0xNy42IC02LjIsNC4zIC05Ljk5OTk5OTcsMTQuNCAtOC4yOTk5OTk3LDIyLjUgMy4zOTk5OTk3LDE3LjYgMTYuMTk5OTk5NywyNy43IDM0LjY5OTk5OTcsMjcuNyB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk3NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjQ4NzY2MywyMDAuNjcgYyAwLjIsMC42IDAuMywxLjIgMC41LDEuOCAwLjIsLTAuNSAwLjUsLTEgMS4xLC0xLjQgLTAuNiwtNi4zIDAuNywtMTIuMiAzLjEsLTE4IC01LjEsNC45IC01LjUsMTEuMSAtNC43LDE3LjYgeiBtIDU1MS40OTk5OTcsMC4zIGMgMC4zLDAuOSAwLjUsMS44IDAuNiwyLjggMC4zLC0xIDAuNywtMi4xIDAuOSwtMy4yIDAuOCwtNi41IDAuNCwtMTIuNiAtNC43LC0xNy41IDIuNSw1LjcgMy44LDExLjcgMy4yLDE3LjkgeiBNIDQ0LjI4NzY2MywzOTcuMjcgSCA0NzEuODg3NjYgYyAyMS4xLDAgNDIuMiwwLjEgNjMuMywwIDE4LjMsLTAuMSAzMC4zLC05LjkgMzQsLTI3LjQgMS44LC04LjcgLTIuMywtMTkuMSAtOS4xLC0yMi43IDUsNC41IDYsMTAuNCA1LjYsMTYuNyAtMC4zLDEuMyAtMC42LDIuNSAtMC45LDMuOCAwLjUsOS43IC02LjksMjAuNiAtMTcuMSwyMy43IC0zLjcsMS4xIC03LjUsMS45IC0xMS42LDEuOSAtMTY0LjcsLTAuMSAtMzI5LjQsLTAuMSAtNDk0LjA5OTk5NywtMC4xIC0xNS43LDAgLTI1LjQsLTcuNyAtMjguOCwtMjIuNyAtMC4yLC0wLjkgLTAuNCwtMS44IC0wLjUsLTIuNiAtMC4zLC0xLjMgLTAuNSwtMi43IC0wLjUsLTQuMSAtMC4xLC02LjIgMC43LC0xMi4xIDUuNywtMTYuNSAtNi43LDMuNiAtMTAuODk5OTk5NywxNC4xIC05LjA5OTk5OTcsMjIuNyAzLjc5OTk5OTcsMTcuOSAxNS45OTk5OTk3LDI3LjMgMzUuNDk5OTk5NywyNy4zIHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTc5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjA4NzY2LDM2My44NyBjIDAuNCwxLjIgMC41LDIuNSAwLjYsMy43IDAuMywtMS4yIDAuNywtMi41IDAuOSwtMy44IDAuNCwtNi4zIC0wLjYsLTEyLjIgLTUuNiwtMTYuNyAyLjgsNS4zIDQuNCwxMC44IDQuMSwxNi44IHogbSAtNTUxLjg5OTk5NywtMC4yIGMgMCwxLjQgMC4yLDIuOCAwLjUsNC4xIC0wLjEsLTEuNCAwLC0yLjcgMS4yLC0zLjkgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LjEsNC40IC01LjksMTAuMyAtNS44LDE2LjUgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5ODEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTkuMjg3NjYsNDI4LjA3IGMgMy41LDMgNS4xLDcgNi4yLDExLjMgMCwwLjMgMC4xLDAuNyAwLjEsMSAyLjgsMy4zIDEuMiw3LjYgMC45LDExLjIgLTAuNiw3LjYgLTMuMSwxNC42IC0xMSwxOCAtMS40LDAuOSAtMi44LDEuOSAtNC4xLDIuOCAtNCw0LjQgLTkuNCw0LjIgLTE0LjcsNC4yIEggNDAuNDg3NjYzIGMgLTUsMCAtMTAuMiwwLjEgLTE0LC00LjIgLTYuNCwtNC44IC0xMS41LC0xMC41IC0xMy40LC0xOC42IC0wLjQsLTIgLTEsLTQgLTAuNCwtNS45IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjEsLTEzIDYuNCwtMTcuOCAtNy42LDMuOSAtOS42OTk5OTk3LDExIC0xMC4wOTk5OTk3LDE4LjUgLTEsMTguMiAxMy41OTk5OTk3LDMyLjggMzIuNTk5OTk5NywzMi44IDQ5LjksMC4xIDk5LjY5OTk5NywwIDE0OS41OTk5OTcsMCBoIDM0NC41IGMgMTAuNCwwIDE5LjUsLTMuMSAyNi42LC0xMS4yIDExLjMsLTEyLjUgMTAuMSwtMzIgLTIuNSwtNDAgeiIKICAgICBjbGFzcz0ic3Q1NyIKICAgICBpZD0icGF0aDM5ODUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWNlY2VjIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuNTg3NjYsNDQwLjQ3IGMgMCwtMC4zIC0wLjEsLTAuNyAtMC4xLC0xIC0xLjEsLTQuMyAtMi43LC04LjMgLTYuMiwtMTEuMyAxLjYsMy42IDMuMSw3LjMgNC43LDEwLjkgMC43LDAuNCAxLjIsMC45IDEuNiwxLjQgeiBtIC01NTMuMTk5OTk3LDUuNSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS4zIDEuMSwtMiAtMC40LC02LjUgMS43LC0xMi40IDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IgogICAgIGNsYXNzPSJzdDU3IgogICAgIGlkPSJwYXRoMzk4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlY2VjZWMiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQ0LjE4NzY2MywzMTUuMTcgSCA0MzguMzg3NjYgYyAzMi4yLDAgNjQuNCwwLjIgOTYuNiwtMC4xIDE0LjUsLTAuMSAyNiwtNS41IDMxLjksLTE5LjkgNSwtMTIuMiAyLC0yNS4yIC03LjcsLTMxLjMgMy44LDMuMyA1LjUsNy43IDYuMywxMi41IDAuMSwwLjkgMC4xLDEuOCAwLjEsMi43IDIuOSw3IDAuNSwxNi44IC02LDIyLjIgLTIuOCwyLjMgLTUuNSw0LjYgLTguMyw3IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjI4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtNi44LC01LjEgLTEyLjEsLTExLjEgLTEzLjQsLTE5LjkgLTAuMiwtMS41IC0wLjYsLTMuMSAtMC4zLC00LjUgLTAuMiwtMC43IC0wLjMsLTEuMyAtMC40LC0yIC0wLjQsLTYuMyAwLjYsLTEyLjIgNS42LC0xNi44IC02LjcsMy42IC0xMC44OTk5OTk3LDE0LjEgLTkuMDk5OTk5NywyMi43IDMuNzk5OTk5NywxOCAxNS42OTk5OTk3LDI3LjQgMzUuMjk5OTk5NywyNy40IHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTg5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTIuMzg3NjYzLDI4MS43NyBjIDAuMSwwLjcgMC4zLDEuMyAwLjQsMiAwLjIsLTAuNyAwLjUsLTEuNCAxLjEsLTIgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LDQuNSAtNi4xLDEwLjQgLTUuNiwxNi43IHogbSA1NTMuMzk5OTk3LC0yLjggYyAwLC0wLjkgMCwtMS44IC0wLjEsLTIuNyAtMC44LC00LjggLTIuNSwtOS4yIC02LjMsLTEyLjUgbCA0LjgsMTIuMyBjIDAuNiwxIDEuMSwxLjkgMS42LDIuOSB6IE0gMzIuNTg3NjYzLDY2LjA3IGMgOC41LDEuNyAxNywxLjMgMjUuNiwxLjMgSCA1MzMuMDg3NjYgYyAxMSwwIDIxLC0yLjUgMjguOCwtMTEuMSAxMS4yLC0xMi40IDkuMiwtMzQuOCAtMi41LC00MC4yIDMuNSwzIDUuMSw3IDYuMiwxMS4zIDAuMSwxLjEgMC4yLDIuMiAwLjIsMy4zIDMuMiw5LjMgLTAuNiwyMS40IC04LjgsMjUuNiAtMS44LDEuNCAtMy43LDIuOCAtNS41LDQuMiAtMy43LDMuMyAtOC4xLDQuMiAtMTIuOCw0LjIgSCAzOS40ODc2NjMgYyAtNC43LDAgLTkuMiwtMC45IC0xMi44LC00LjIgLTYuOCwtNS4xIC0xMi4xLC0xMS4xIC0xMy40LC0xOS45IC0wLjIsLTEuNSAtMC42LC0zLjEgLTAuMywtNC41IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjIsLTEzIDYuNCwtMTcuOCAtMi43LDAuNiAtNC4zLDIuNyAtNS43LDQuOCAtMTEuMDk5OTk5NywxNi41IC0wLjIsNDEuMiAxOS40LDQ1LjEgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsMjYuOTcgYyAwLjcsMS4xIDEuMywyLjQgMS43LDMuNiAwLC0xLjEgLTAuMSwtMi4yIC0wLjIsLTMuMyAtMSwtNC4zIC0yLjcsLTguMyAtNi4yLC0xMS4zIDEuNiwzLjcgMy4yLDcuNCA0LjcsMTEgeiBtIC01NTEuNTk5OTk3LDYuOSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS40IDEuMSwtMiAtMC40LC02LjUgMS44LC0xMi4zIDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IG0gMzEuMywxMTUuNiBIIDQwOS43ODc2NiBjIDQxLjgsMCA4My41LDAuMSAxMjUuMywtMC4xIDE0LjUsLTAuMSAyNi4xLC01LjUgMzIsLTE5LjkgNSwtMTIuMiAyLC0yNS4zIC03LjcsLTMxLjQgNS4xLDQuNyA2LjksMTAuNyA2LjQsMTcuNCAtMC4yLDEuNCAtMC41LDIuOCAtMC45LDQuMiAwLjUsNi43IC0yLjUsMTIuMyAtNy4yLDE3LjMgLTEuOSwyIC00LjEsMy43IC02LjEsNS41IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjU4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtMiwtMS4yIC00LjUsLTEuNyAtNS42LC00LjIgLTguMSwtNC4yIC0xMS44OTk5OTk3LC0xNi4yIC04LjgsLTI1LjQgMCwtMS4xIDAsLTIuMyAwLjEsLTMuNCAwLjUsLTQuNyAyLjksLTguMyA2LjQsLTExLjMgLTcuNSw0LjcgLTExLjY5OTk5OTcsMTUuMiAtOS43OTk5OTk3LDI0LjEgMy42OTk5OTk3LDE3LjkgMTUuNDk5OTk5NywyNy4yIDM0LjU5OTk5OTcsMjcuMiB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC4xODc2NiwxMTYuMDcgYyAwLjMsMS4zIDAuNSwyLjUgMC42LDMuNyAwLjQsLTEuNCAwLjcsLTIuNyAwLjksLTQuMiAwLjUsLTYuOCAtMS4zLC0xMi43IC02LjQsLTE3LjQgMy4xLDUuNiA1LjMsMTEuNCA0LjksMTcuOSB6IG0gLTU1MS44OTk5OTcsLTYuNiBjIDAsMS4xIC0wLjEsMi4zIC0wLjEsMy40IDAuNCwtMS4zIDEsLTIuNiAxLjgsLTMuOCAtMC4yLC00LjQgMy4zLC03LjIgNC43LC0xMSAtMy41LDMuMSAtNS45LDYuNyAtNi40LDExLjQgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOS44ODc2NjMsMjI1Ljk3IGMgMS41LDAuNCAzLjIsMC4xIDQuOSwwLjEgSCA1MzMuMzg3NjYgYyA3LjEsMCAxMy44LC0xLjEgMTkuNiwtNS42IDEuMSwtMC44IDEuOSwtMS42IDIuMywtMi43IC0wLjMsMC4yIC0wLjUsMC40IC0wLjgsMC42IC01LjQsNC4xIC0xMS41LDUuNiAtMTguMiw1LjYgSCA0MS45ODc2NjMgYyAtNi43LDAgLTEyLjgsLTEuNSAtMTguMSwtNS41IDMuMyw1LjkgMTAsNi4xIDE2LDcuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQxLjg4NzY2MywyMjMuOTcgSCA1MzYuMTg3NjYgYyA2LjcsMCAxMi44LC0xLjUgMTguMiwtNS42IDAuMywtMC4yIDAuNiwtMC40IDAuOCwtMC42IDAuMiwtMC41IDAuMywtMS4xIDAuMiwtMS44IC03LjIsNC45IC0xNS4xLDYuMSAtMjMuNyw2LjEgLTE2MS44LC0wLjIgLTMyMy42LC0wLjIgLTQ4NS4zOTk5OTcsMCAtOC42LDAgLTE2LjUsLTEuMiAtMjMuNywtNi4xIDAuMywxIDAuNywxLjggMS4yLDIuNiA1LjQsNCAxMS40LDUuNCAxOC4xLDUuNCB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1NS45ODc2NiwyMTcuMTcgYyAwLjIsMC43IDAuMiwxLjMgMCwxLjkgMi43LC0yLjYgNC42LC01LjYgNiwtOS4xIC0xLjUsMi43IC0zLjQsNS4xIC02LDcuMiB6IG0gLTUzMy45OTk5OTcsMCBjIC0yLjQsLTEuOSAtNC4yLC00LjIgLTUuNywtNi43IDEuNCwzLjIgMy4zLDYgNS42LDguNCAtMC4xLC0wLjQgLTAuMSwtMSAwLjEsLTEuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDIxNy4xNyBjIDAuMSwtMC40IDAuMywtMC44IDAuNiwtMS4yIC00LC00LjMgLTYuNywtOS40IC04LjYsLTE1IDAuMywzLjQgMS4xLDYuNiAyLjMsOS41IDEuNSwyLjYgMy40LDQuOCA1LjcsNi43IHogbSA1MzkuOTk5OTk3LC03LjMgYyAxLC0yLjcgMS43LC01LjcgMiwtOC45IC0xLjksNS41IC00LjUsMTAuNiAtOC42LDE1IDAuMywwLjQgMC41LDAuOSAwLjYsMS4yIDIuNiwtMi4xIDQuNSwtNC41IDYsLTcuMyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDIxOS4wNyBjIC0wLjQsMS4yIC0xLjcsMi4xIC0zLDMgLTUuMSwzLjYgLTEwLjcsNS4zIC0xNi45LDUuNCBIIDQ0LjU4NzY2MyBjIC03LjEsMCAtMTMuOCwtMS4yIC0xOS43LC01LjQgLTEuMywtMC45IC0yLjYsLTEuOSAtMywtMy4xIC0yLjQsLTIuNCAtNC4yLC01LjIgLTUuNiwtOC40IC0xLjUsLTIuNSAtMi41LC01LjIgLTMuNCwtOC4xIC0wLjQsMS4xIC0wLjEsMi40IDAuMiwzLjcgMy4xLDE0LjUgMTMuNywyMi44IDI5LjYsMjIuOCAxNjQuMTk5OTk3LDAgMzI4LjI5OTk5NywwIDQ5Mi40OTk5OTcsMC4xIDUuMywwIDEwLjEsLTEuMyAxNC44LC0zLjEgNy4xLC0yLjggMTUuNiwtMTMuMSAxNC41LC0yMiAtMC43LDIuMiAtMS42LDQuMiAtMi42LDYuMSAtMS4yLDMuNCAtMy4yLDYuNCAtNS44LDkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAxOSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAtMC41LDAuNCAtMC45LDAuOSAtMS4xLDEuNCAwLjgsMi45IDEuOSw1LjYgMy40LDguMSAtMS4zLC0yLjggLTIuMSwtNiAtMi4zLC05LjUgeiBtIDU0Ny44OTk5OTcsOC45IGMgMS4xLC0xLjkgMS45LC00IDIuNiwtNi4xIC0wLjEsLTAuOSAtMC4zLC0xLjkgLTAuNiwtMi44IC0wLjMsMy4zIC0xLDYuMiAtMiw4LjkgeiBtIC02LDcuMyBjIC0wLjIsMC4yIC0wLjUsMC40IC0wLjgsMC42IC0wLjQsMS4xIC0xLjIsMS45IC0yLjMsMi43IC01LjgsNC41IC0xMi41LDUuNiAtMTkuNiw1LjYgSCA0NC42ODc2NjMgYyAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjksLTEuNCAtMTIuNywtMS42IC0xNi4xLC03LjQgMCwwIC0wLjEsMCAtMC4xLC0wLjEgLTAuNiwtMC40IC0xLjEsLTAuOCAtMS43LC0xLjMgLTAuMiwwLjcgLTAuMiwxLjIgLTAuMSwxLjcgNC42LDQuNiAxMC44LDcuNSAxOCw3LjkgMi4zLDAuMSA0LjYsMC4xIDcsMC4xIEggNTMwLjk4NzY2IGMgNS4xLDAgMTAuMSwwIDE1LjEsLTEuOCA0LC0xLjUgNy4zLC0zLjUgOS45LC02IDAuMiwtMC42IDAuMywtMS4yIDAsLTEuOSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDIxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNjg3NjYzLDIxOC40NyBjIC0wLjMsLTAuNyAtMC43LC0xLjUgLTEuMSwtMi41IC0wLjMsMC40IC0wLjUsMC45IC0wLjYsMS4yIDAuNiwwLjUgMS4xLDAuOSAxLjcsMS4zIHogbSA1MzEuNTk5OTk3LC0wLjcgYyAwLjMsLTAuMiAwLjUsLTAuNCAwLjgsLTAuNiAtMC4xLC0wLjQgLTAuMywtMC44IC0wLjYsLTEuMiAwLDAuNyAtMC4xLDEuMyAtMC4yLDEuOCB6IG0gLTI0LjIsOS4xIEggNDYuODg3NjYzIGMgLTIuMywwIC00LjYsMC4xIC03LC0wLjEgLTcuMiwtMC40IC0xMy41LC0zLjMgLTE4LC03LjkgMC40LDEuMyAxLjcsMi4yIDMsMy4xIDUuOSw0LjIgMTIuNSw1LjQgMTkuNyw1LjQgMTU0LjU5OTk5NywtMC4xIDMwOS4xOTk5OTcsMCA0NjMuNzk5OTk3LDAgaCAyNy44IGMgNi4yLDAgMTEuOCwtMS44IDE2LjksLTUuNCAxLjMsLTAuOSAyLjYsLTEuOCAzLC0zIC0yLjYsMi41IC01LjksNC41IC05LjksNiAtNSwxLjkgLTEwLDEuOSAtMTUuMSwxLjkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDM4LjQ4NzY2MywxNDIuMzcgYyAyLjQsMC42IDUuMSwwLjEgNy42LDAuMSBIIDUzNC41ODc2NiBjIDUuMywwIDEwLjYsMCAxNS4zLC0yLjkgMC43LC0xIDEuNCwtMi4xIDIuMSwtMy4xIC01LjUsMyAtMTEuNCwzLjkgLTE3LjYsMy45IC0xNjMuOCwtMC4xIC0zMjcuNSwtMC4xIC00OTEuMjk5OTk3LDAgLTcuMSwwIC0xMy41LC0xLjUgLTE5LjYsLTUuMSAzLjMsNS41IDkuNiw1LjggMTUsNy4xIHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDI1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuMjg3NjYzLDE0MC40NyBjIDE2My43OTk5OTcsLTAuMSAzMjcuNDk5OTk3LC0wLjEgNDkxLjI5OTk5NywwIDYuMiwwIDEyLjEsLTAuOCAxNy42LC0zLjkgMC43LC0wLjkgMS4zLC0xLjkgMiwtMi44IC02LjYsMy44IC0xMy44LDQuNyAtMjEuNCw0LjcgLTE2Mi42LC0wLjEgLTMyNS4yLC0wLjEgLTQ4Ny43OTk5OTcsMCAtOC4yLDAgLTE1LjYsLTEuMyAtMjIuNCwtNS44IDAuMywxLjEgMC43LDIgMS4yLDIuOCA1LjksMy42IDEyLjQsNSAxOS41LDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwMjciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NDguOTg3NjYsMTQxLjc3IGMgLTAuNCwwLjMgLTAuOCwwLjUgLTEuMiwwLjggMC4xLC0wLjEgMC4yLC0wLjEgMC40LC0wLjIgMi45LC0xLjggNS41LC0zLjggNy43LC02LjEgLTAuOCwwLjYgLTEuNiwxLjIgLTIuNSwxLjcgLTEuMiwxLjUgLTMuMSwyLjUgLTQuNCwzLjggeiBtIDExLjcsLTEyLjkgYyAtMC4zLDEuMSAtMC43LDIuMiAtMS4yLDMuMSAxLjUsLTIuMiAyLjcsLTQuNiAzLjUsLTcuMiAtMC4yLDAuNSAtMC40LDEgLTAuNiwxLjQgLTAuNiwxIC0xLjIsMS44IC0xLjcsMi43IHogbSAtMTU1LjksMTUuNiBIIDQ1Ljc4NzY2MyBjIC02LjgsMCAtMTMuNSwtMC41IC0xOS40LC00LjMgLTIuNCwtMS41IC01LC0zIC00LjQsLTYuMSAtNCwtMy40IC02LjUsLTcuOCAtOC4yLC0xMi42IC0wLjIsMy45IDEuMSw3LjMgMywxMC41IDEuMywxLjkgMi45LDMuNyA0LjksNS40IDIuNSwxLjggNSwzLjUgNy43LDQuOCA0LjEsMiA4LjQsMi41IDEyLjgsMi41IEggNTM1Ljg4NzY2IGMgMi4xLDAgNC4xLC0wLjEgNi4xLC0wLjUgLTEuOSwwLjIgLTMuOSwwLjIgLTUuOCwwLjIgLTQzLjcsMC4xIC04Ny42LDAuMSAtMTMxLjQsMC4xIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsMTM0LjE3IGMgMC4xLC0wLjUgMC4yLC0xIDAuNSwtMS41IC0zLjksLTQgLTYuMywtOC45IC04LjMsLTEzLjkgLTAuMiwxIC0wLjMsMS45IC0wLjQsMi44IDEuNyw0LjggNC4yLDkuMSA4LjIsMTIuNiB6IG0gNTQwLjI5OTk5NywtNy45IGMgMC4yLC0wLjUgMC40LC0xIDAuNiwtMS40IDAuOCwtMi43IDEuMywtNS41IDEuMiwtOC43IC0xLDMuMiAtMiw2LjQgLTMsOS43IC0wLjEsMS4xIC0wLjMsMi4xIC0wLjUsMy4xIDAuNiwtMSAxLjIsLTEuOCAxLjcsLTIuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU5LjQ4NzY2LDEzMS45NyBjIC0wLjksMS43IC0yLjEsMy4xIC0zLjYsNC40IC0yLjIsMi4yIC00LjgsNC4yIC03LjcsNi4xIC0wLjEsMC4xIC0wLjIsMC4xIC0wLjQsMC4yIC0xLjgsMS4xIC0zLjcsMS41IC01LjcsMS44IC0yLDAuMyAtNCwwLjUgLTYuMSwwLjUgSCA0Mi4yODc2NjMgYyAtNC41LDAgLTguOCwtMC41IC0xMi44LC0yLjUgLTIuNywtMS40IC01LjMsLTMgLTcuNywtNC44IC0yLC0xLjcgLTMuNiwtMy41IC00LjksLTUuNCAxLjMsMi4yIDIuOCw0LjIgNC4zLDYuMyAxLDIuNSAzLjYsMyA1LjYsNC4yIDEyLjQsMy43IDI1LjIsMi44IDM3LjksMi44IEggNTE0LjQ4NzY2IGMgMTIuNCwwIDI1LDAuOSAzNy4yLC0yLjggMi4xLC0xLjggNC4zLC0zLjUgNi4xLC01LjUgNC43LC01IDcuNywtMTAuNiA3LjIsLTE3LjMgLTAuNSwxLjcgLTEuMSwzLjQgLTEuOCw1IC0xLjEsMi40IC0yLjMsNC44IC0zLjcsNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTYyLjg4NzY2LDEyNC43NyBjIDAuNywtMS42IDEuMywtMy4zIDEuOCwtNSAtMC4xLC0xLjIgLTAuMywtMi40IC0wLjYsLTMuNyAwLjEsMy4yIC0wLjQsNi4xIC0xLjIsOC43IHogbSAtOS41LDEzLjMgYyAtMSwwLjYgLTIuMiwxLjIgLTMuNCwxLjcgLTQuOCwyLjggLTEwLDIuOSAtMTUuMywyLjkgLTE2Mi44LC0wLjEgLTMyNS43LDAgLTQ4OC40OTk5OTcsMCAtMi42LDAgLTUuMiwwLjUgLTcuNiwtMC4xIC01LjUsLTEuMyAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4yLC0wLjEgLTAuMywtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjYsMy4xIDIuMSw0LjYgNC40LDYuMSA1LjksMy44IDEyLjUsNC4zIDE5LjQsNC4zIDExOS42OTk5OTcsLTAuMSAyMzkuMjk5OTk3LDAgMzU4Ljk5OTk5NywwIGggMTMxLjUgYyAxLjksMCAzLjksMCA1LjgsLTAuMiAxLjksLTAuMyAzLjgsLTAuOSA1LjcsLTEuOCAwLjQsLTAuMiAwLjgsLTAuNSAxLjIsLTAuOCAxLjIsLTEuMyAzLjEsLTIuMyA0LjMsLTMuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMzg3NjYzLDEzNS4yNyBjIDAuMSwwLjEgMC4yLDAuMSAwLjMsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjIsMC41IC0wLjQsMSAtMC41LDEuNSAwLjUsMC4zIDAuOSwwLjcgMS40LDEuMSB6IG0gNTI0LjM5OTk5Nyw3LjMgYyAtMS44LDAuOSAtMy43LDEuNCAtNS43LDEuOCAyLC0wLjMgMy45LC0wLjggNS43LC0xLjggeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjc4NzY2MywxMTguNTcgYyAwLC0wLjIgLTAuMSwtMC40IC0wLjEsLTAuNSAwLDEuNiAwLjEsMy4xIDAuMyw0LjcgMC4xLC0wLjcgMC4yLC0xLjQgMC41LC0yLjEgLTAuMywtMC43IC0wLjUsLTEuNCAtMC43LC0yLjEgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwMzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi43ODc2NjMsMTE4LjU3IGMgMC4yLDAuNyAwLjQsMS40IDAuNiwyIDAuMiwtMC42IDAuNCwtMS4yIDAuNywtMS45IDAsLTMuMiAtMC4xLC02LjQgLTAuMSwtOS42IC0wLjgsMy4xIC0xLjMsNiAtMS4zLDguOSAwLDAuMiAwLjEsMC40IDAuMSwwLjYgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwNDEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi45ODc2NjMsMTIyLjY3IGMgLTAuMiwtMS41IC0wLjMsLTMuMSAtMC4zLC00LjcgLTAuNCwtMS43IC0wLjUsLTMuNCAtMC41LC01LjEgLTMuMDk5OTk5Nyw5LjIgMC43LDIxLjIgOC44LDI1LjQgLTQuNCwtNC41IC04LjksLTkuMSAtOCwtMTUuNiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA0MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjk4NzY2MywxMDkuMTcgYyAtMC43LDEuMiAtMS4zLDIuNSAtMS44LDMuOCAwLDEuNyAwLjEsMy40IDAuNSw1LjEgMC4xLC0yLjkgMC41LC01LjkgMS4zLC04LjkgeiBtIC0wLjIsMTIuMyAtMC4zLC0wLjkgYyAtMC4yLDAuNyAtMC40LDEuNCAtMC41LDIuMSAwLjUsMy4zIDEuNyw2LjQgMy44LDkuMyAtMS45LC0zLjEgLTMuMiwtNi41IC0zLC0xMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTMuNzg3NjYzLDEyMS40NyBjIDAsLTAuOSAwLjIsLTEuOCAwLjQsLTIuOCAtMC4zLDAuNiAtMC41LDEuMyAtMC43LDEuOSB6IG0gMywxMC42IGMgLTIsLTIuOSAtMy4yLC02IC0zLjgsLTkuMyAtMC45LDYuNSAzLjYsMTEuMSA4LDE1LjcgLTEuNSwtMi4yIC0zLC00LjMgLTQuMiwtNi40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIC0wLjgsMC43IC0xLjYsMS4zIC0yLjQsMS45IDAsMC4zIDAsMC42IC0wLjEsMC44IDAuOCwtMC44IDEuNywtMS43IDIuNSwtMi43IHoiCiAgICAgY2xhc3M9InN0NjMiCiAgICAgaWQ9InBhdGg0MDQ5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NkY2RjZSIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIDEuOCwtMi4zIDMuMywtNC44IDQuNCwtNy42IC0yLjMsMi43IC00LjcsNS40IC03LDguMSAwLjEsMC42IDAuMiwxIDAuMiwxLjUgMC44LC0wLjcgMS42LC0xLjMgMi40LC0yIHogbSAtMi42LDIuOCBjIDAsLTAuMyAwLjEsLTAuNSAwLjEsLTAuOCAtMC42LDAuNCAtMS4xLDAuNyAtMS43LDEuMSAtMC4xLDAuMSAtMC4zLDAuMSAtMC40LDAuMiAtMC43LDEgLTEuNCwyLjEgLTIuMSwzLjEgMS40LC0xLjEgMi44LC0yLjMgNC4xLC0zLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTIuMTg3NjYsMTM2LjY3IGMgMC4xLC0wLjEgMC4zLC0wLjEgMC40LC0wLjIgMC42LC0wLjMgMS4yLC0wLjcgMS43LC0xLjEgMCwtMC41IC0wLjEsLTEgLTAuMiwtMS41IC0wLjYsMC45IC0xLjMsMS44IC0xLjksMi44IHogbSA0LjYsLTMuMyBjIC0wLjgsMSAtMS42LDEuOSAtMi41LDIuOCAtMC4xLDAuNyAtMC40LDEuMyAtMC45LDEuOSAwLjksLTAuNSAxLjcsLTEuMSAyLjUsLTEuNyAxLjQsLTEuNCAyLjYsLTIuOCAzLjYsLTQuNCAwLjUsLTAuOSAwLjksLTIgMS4yLC0zLjEgLTEuMiwxLjYgLTIuNSwzLjIgLTMuOSw0LjUgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjAuNjg3NjYsMTI4Ljg3IGMgMC4zLC0xIDAuNCwtMiAwLjUsLTMuMSAtMS4xLDIuOCAtMi42LDUuNCAtNC40LDcuNiAxLjQsLTEuMyAyLjcsLTIuOSAzLjksLTQuNSB6IG0gLTEuMiwzLjEgYyAtMS4xLDEuNSAtMi4zLDMgLTMuNiw0LjQgMS40LC0xLjMgMi42LC0yLjcgMy42LC00LjQgeiBtIC05LjUsNy43IGMgMS4yLC0wLjUgMi4zLC0xLjEgMy40LC0xLjcgMC40LC0wLjUgMC43LC0xLjIgMC45LC0xLjkgLTEuNCwxLjQgLTIuOCwyLjYgLTQuMywzLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyOC4yODc2NjMsMzg3Ljg3IGMgMiwxLjEgNC4yLDEuOSA2LjUsMi41IEggNTQwLjI4NzY2IGMgNSwtMS45IDExLjIsLTIgMTQuMSwtNy4yIC02LjIsMy44IC0xMi45LDUuMSAtMjAuMiw1LjEgLTE2My41LC0wLjEgLTMyNy4xLC0wLjEgLTQ5MC41OTk5OTcsMCAtNi40LDAgLTEyLjUsLTAuNiAtMTguMSwtNCAtMC4xLC0wLjEgLTAuMiwtMC4xIC0wLjMsLTAuMiAxLDEuMSAyLjIsMiAyLjcsMy40IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjUuNTg3NjYzLDM4NC4yNyBjIDUuNiwzLjQgMTEuNyw0IDE4LjEsNCAxNjMuNDk5OTk3LC0wLjEgMzI3LjA5OTk5NywtMC4xIDQ5MC41OTk5OTcsMCA3LjMsMCAxNCwtMS40IDIwLjIsLTUuMSAwLjUsLTAuOCAwLjgsLTEuNyAxLjEsLTIuOCAtNi41LDQuNiAtMTMuNyw1LjkgLTIxLjYsNS45IC0xNjMuMSwtMC4xIC0zMjYuMiwtMC4xIC00ODkuMTk5OTk3LDAgLTcuNCwwIC0xNC4zLC0wLjkgLTIwLjYsLTQuNyAwLjEsMS4xIDAuNywxLjggMS4zLDIuNiAtMC4xLDAgMCwwLjEgMC4xLDAuMSB6IG0gOS4yLDYuMSBjIC0yLjMsLTAuNiAtNC41LC0xLjQgLTYuNSwtMi41IDEuOCwyIDQuMSwyLjQgNi41LDIuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgYyAwLjcsMi4xIDEuNyw0LjEgMi45LDUuOSAtMC42LC0xLjEgLTEuMSwtMi4zIC0xLjUsLTMuNSAtMC41LC0wLjggLTAuOSwtMS42IC0xLjQsLTIuNCB6IG0gNTQxLjA5OTk5Nyw5LjEgYyAwLjEsMC41IDAuMiwxIDAuMSwxLjQgMi41LC0yLjUgNC41LC01LjQgNS44LC04LjcgLTEuNSwyLjYgLTMuNCw1LjEgLTUuOSw3LjMgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgMS41LDIuNCBjIC0wLjQsLTEuNCAtMC43LC0yLjkgLTAuOSwtNC41IC0xLjksLTEuOSAtMC41LC00LjcgLTEuNiwtNi44IC0wLjQsMy4xIDAsNiAxLDguOSB6IG0gNTQ2Ljk5OTk5NywxLjcgYyAxLjMsLTMuMiAyLjEsLTYuOCAyLjEsLTEwLjYgLTEuOCw2IC00LjEsMTEuOCAtOC42LDE2LjUgMC4zLDAuNSAwLjUsMSAwLjYsMS41IDIuNSwtMi4yIDQuNCwtNC43IDUuOSwtNy40IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTYuMTg3NjYsMzgzLjI3IGMgLTAuMywxLjkgLTIuMywzLjEgLTQsNC4xIC00LjIsMi41IC04LjcsNCAtMTMuNyw0LjMgaCAtMC42IGMgLTEuNCwwLjMgLTIuOCwwLjEgLTQuMiwwIEggNDQuMDg3NjYzIGMgLTEuMywwLjEgLTIuNywwLjMgLTQsMCBoIC0wLjYgYyAtNC4xLC0wLjMgLTguMiwtMC4zIC0xMS44LC0yLjcgLTEsLTEuMiAtMi41LC0yLjIgLTMuNCwtMy40IC0yLjgsLTEuOCAtNSwtNC4xIC02LjUsLTYuOSAtMS4zLC0xLjkgLTIuMiwtMy45IC0yLjksLTUuOSAtMC4zLC0wLjUgLTAuNiwtMC45IC0wLjgsLTEuNCAtMC43LC0xLjEgLTEuMiwtMi4zIC0xLjUsLTMuNSAwLjEsMC45IDAuMywxLjcgMC41LDIuNiAzLjUsMTQuOSAxMy4yLDIyLjYgMjguOSwyMi42IDE2NC42OTk5OTcsMCAzMjkuMzk5OTk3LDAgNDk0LjA5OTk5NywwLjEgNCwwIDcuOSwtMC44IDExLjYsLTEuOSAxMC4yLC0zLjEgMTcuNiwtMTQuMSAxNy4xLC0yMy43IC0wLjcsMi40IC0xLjYsNC43IC0yLjcsNi45IC0xLjQsMy4zIC0zLjQsNi4zIC01LjksOC44IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjEuOTg3NjYsMzc0LjQ3IGMgMS4yLC0yLjEgMiwtNC41IDIuNywtNi45IC0wLjEsLTEuMyAtMC4zLC0yLjUgLTAuNiwtMy43IDAsMy44IC0wLjgsNy40IC0yLjEsMTAuNiB6IG0gLTU0Ni45OTk5OTcsLTEuNyBjIC0wLjksLTIuOCAtMS40LC01LjggLTEuMSwtOC45IC0xLjEsMS4yIC0xLjMsMi42IC0xLjIsMy45IDAuMywxLjIgMC43LDIuNCAxLjUsMy41IDAuMiwwLjUgMC41LDEgMC44LDEuNSB6IG0gMTEsMTMuOCBjIDAuOCwwLjUgMS41LDAuOSAyLjMsMS40IGwgLTAuMywtMC4zIGMgLTAuNywtMC40IC0xLjQsLTAuOCAtMiwtMS4xIHogbSA1MzAuMDk5OTk3LC00LjcgYyAtMC40LDAuNCAtMC45LDAuOCAtMS40LDEuMiAtMC4xLDAuMSAtMC4yLDAuMSAtMC4zLDAuMiAtMi45LDUuMiAtOS4xLDUuMyAtMTQuMSw3LjIgbCAtMC42LDAuNiBjIDEuNCwtMC4xIDIuOCwtMC40IDQuMiwtMC43IDQuOSwtMS4zIDkuMSwtMy43IDEyLjQsLTcgMCwtMC42IC0wLjEsLTEgLTAuMiwtMS41IHogbSAtNTIxLjI5OTk5Nyw4LjUgYyAxLjIsMC4zIDIuNCwwLjUgMy42LDAuNiAtMC4yLC0wLjIgLTAuNSwtMC40IC0wLjcsLTAuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0Ljc4NzY2LDM4Mi45NyBjIDAuNSwtMC40IDAuOSwtMC44IDEuNCwtMS4yIC0wLjEsLTAuNSAtMC4zLC0wLjkgLTAuNiwtMS41IC0wLjMsMS4xIC0wLjYsMiAtMS4xLDIuOCAwLDAgMC4xLDAgMC4zLC0wLjEgeiBtIC01MDkuNzk5OTk3LDguNyBoIC0wLjggNDg5LjU5OTk5NyAtMC42IGMgLTE2Mi44LDAuMSAtMzI1LjUsMC4xIC00ODguMTk5OTk3LDAgeiBtIDQ5NC42OTk5OTcsLTAuOCBjIC0wLjUsMC40IC0xLjEsMC43IC0xLjcsMC44IGggMC42IGMgNC45LC0wLjMgOS41LC0xLjggMTMuNywtNC4zIDEuOCwtMS4xIDMuOCwtMi4yIDQsLTQuMSAtMy4zLDMuMyAtNy41LDUuNyAtMTIuNCw3IC0xLjUsMC4zIC0yLjksMC41IC00LjIsMC42IHogbSAtNTA0Ljg5OTk5NywtMC41IGMgLTIuNCwtMC4xIC00LjcsLTAuNSAtNi41LC0yLjUgLTAuOCwtMC40IC0xLjYsLTAuOSAtMi4zLC0xLjQgbCAtMS41LC0wLjkgYyAwLjksMS4yIDIuNCwyLjIgMy40LDMuNCAzLjYsMi40IDcuNywyLjQgMTEuOCwyLjcgaCAwLjYgYyAtMC42LC0wLjEgLTEuMiwtMC40IC0xLjcsLTAuOCAtMS40LDAgLTIuNiwtMC4zIC0zLjgsLTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIC0wLjgsLTAuNSAtMS41LC0xLjEgLTIuMSwtMS43IDAuNywwLjggMS40LDEuNiAyLjIsMi4zIC0wLjEsLTAuMSAtMC4xLC0wLjMgLTAuMSwtMC42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIDAsLTAuNSAwLjEsLTEgMC40LC0xLjYgLTMuNCwtMy4xIC02LC02LjkgLTguNSwtMTAuOSAxLjMsNC4xIDMuMyw3LjYgNiwxMC43IDAuNywwLjcgMS40LDEuMyAyLjEsMS44IHogbSA0LjQsNC41IGMgLTAuNSwtMS40IC0xLjcsLTIuMyAtMi43LC0zLjQgLTAuNiwtMC4zIC0xLjEsLTAuNiAtMS42LC0xIHYgMC42IGMgMS4zLDEuMyAyLjgsMi42IDQuMywzLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNS4yODc2NjMsMzg0LjA3IGMgLTAuNiwtMC43IC0xLjIsLTEuNSAtMS4zLC0yLjYgLTAuMiwwLjYgLTAuMywxLjEgLTAuNCwxLjYgMC42LDAuNCAxLjEsMC43IDEuNywxIHogbSAtMSwxLjMgYyAtMC4zLC0wLjUgLTAuNSwtMSAtMC42LC0xLjYgLTAuOCwtMC44IC0xLjUsLTEuNSAtMi4yLC0yLjMgLTIsLTEuOCAtMy42LC0zLjkgLTUuMSwtNi4yIDAuNCwxLjMgMC45LDIuNCAxLjUsMy41IDEuNywyLjQgMy45LDQuNyA2LjQsNi42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDc1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuNDg3NjYzLDM4MS4zNyBjIC0yLjYsLTMuMSAtNC43LC02LjYgLTYsLTEwLjcgMC4yLDEuNiAwLjUsMy4xIDAuOSw0LjUgMS41LDIuMyAzLjEsNC40IDUuMSw2LjIgeiBtIC0zLjYsLTIuNyBjIDEuNSwyLjggMy43LDUuMSA2LjUsNi45IC0wLjEsLTAuMSAtMC4xLC0wLjIgLTAuMiwtMC4zIC0yLjQsLTEuOCAtNC42LC00LjEgLTYuMywtNi42IHogbSA1LjgsNS4xIGMgMC4xLDAuNiAwLjMsMS4xIDAuNiwxLjYgMC42LDAuNCAxLjEsMC44IDEuNywxLjIgMC43LDAuNCAxLjMsMC43IDIsMSAtMS41LC0xLjIgLTMsLTIuNSAtNC4zLC0zLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNC4yODc2NjMsMzg1LjM3IGMgMC4xLDAuMSAwLjEsMC4yIDAuMiwwLjMgbCAxLjUsMC45IGMgLTAuNiwtMC40IC0xLjIsLTAuOCAtMS43LC0xLjIgeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOC40ODc2NjMsNjAuMjcgYyAxLjUsMC40IDMuMiwwLjEgNC45LDAuMSAxNjMuNzk5OTk3LDAgMzI3LjQ5OTk5NywwIDQ5MS4yOTk5OTcsMC4xIDYsMCAxMS40LC0xLjMgMTYuNiwtNC4yIDEuNiwtMC45IDMuMSwtMS45IDMuOCwtMy41IC0wLjEsMC4xIC0wLjMsMC4yIC0wLjQsMC4zIC02LjMsMy45IC0xMy4xLDUuMyAtMjAuNSw1LjMgLTE2My40LC0wLjEgLTMyNi45LC0wLjEgLTQ5MC4yOTk5OTcsMCAtNy4zLDAgLTE0LC0xLjMgLTIwLjEsLTUuMSAzLDUuMyA5LjMsNS42IDE0LjcsNyB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA4MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQzLjc4NzY2Myw1OC4zNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjYgMC41LC0xLjQgMC41LC0yLjIgLTYuOCw0LjYgLTE0LjIsNS44IC0yMi40LDUuOCAtMTYyLjgsLTAuMSAtMzI1LjUsLTAuMSAtNDg4LjI5OTk5NywwIC04LjIsMCAtMTUuNiwtMS4zIC0yMi40LC01LjggMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuMywzLjcgMTMsNSAyMC4yLDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwODMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsNTEuODcgYyAtMi45LC0yLjUgLTUuMSwtNS41IC02LjYsLTguOCAxLjQsNC4yIDMuNyw3LjggNi45LDExIC0wLjQsLTAuNiAtMC41LC0xLjMgLTAuMywtMi4yIHogbSA1MTAuMTk5OTk3LDEwLjUgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjI5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzUuNzg3NjYgYyA0LjUsMCA4LjgsLTAuNSAxMi44LC0yLjUgMS40LC0wLjcgMi43LC0xLjcgNCwtMi43IC0zLjksMi45IC04LjUsNC40IC0xMy40LDQuOCAtMi40LDAuMiAtNC43LDAuMSAtNywwLjEgeiBtIDMyLjEsLTIzIGMgLTEuNyw0LjggLTQuMiw5LjIgLTguMiwxMi42IDAuNCwxLjkgLTAuNiwzLjIgLTEuOSw0LjMgMC42LC0wLjUgMS4zLC0wLjkgMiwtMS4zIDIuNCwtMS43IDQuMywtMy44IDUuOCwtNi4yIDEuNSwtMi45IDIuNCwtNiAyLjMsLTkuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDg1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDUxLjg3IGMgMC4xLC0wLjQgMC4zLC0wLjkgMC41LC0xLjQgLTQuNSwtNC43IC03LjIsLTEwLjMgLTguNiwtMTYuNSAwLDMuMyAwLjUsNi40IDEuNCw5LjIgMS42LDMuMyAzLjgsNi4yIDYuNyw4LjcgeiBNIDU2NC4yODc2NiwzOS4zNyBjIDAsLTAuOSAtMC4yLC0xLjggLTAuNCwtMi44IC0yLjEsNS4xIC00LjQsMTAgLTguMywxMy45IDAuMywwLjUgMC41LDEgMC42LDEuNCAzLjksLTMuNCA2LjMsLTcuNyA4LjEsLTEyLjUgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1Ni4xODc2Niw1NC44NyBjIC0wLjcsMC40IC0xLjMsMC44IC0yLDEuMyAtMC41LDAuNCAtMSwwLjggLTEuNSwxLjEgbCAtMC4xLDAuMSBjIC0xLjMsMSAtMi41LDEuOSAtNCwyLjcgLTQsMiAtOC4zLDIuNSAtMTIuOCwyLjUgSCA0MS45ODc2NjMgYyAtNC4yLDAgLTguMywtMC41IC0xMi4yLC0yLjQgLTAuOSwtMC42IC0xLjcsLTEuMSAtMi41LC0xLjcgLTAuNiwtMC40IC0xLjMsLTAuOCAtMS45LC0xLjIgLTEuMywtMC45IC0yLjYsLTEuOSAtMy4zLC0zLjEgLTMuMSwtMy4yIC01LjUsLTYuOCAtNi45LC0xMSAtMS4xLC0yLjIgLTEuOSwtNC42IC0yLjUsLTcuMiAtMC4zLDEuNCAwLjEsMyAwLjMsNC41IDEuMyw4LjggNi42LDE0LjkgMTMuNCwxOS45IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjM4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjgsLTEuNCAzLjcsLTIuOCA1LjUsLTQuMiAxLjgsLTIuNCAzLjYsLTQuOSA1LC03LjUgLTEuMywyLjQgLTMuMiw0LjUgLTUuNiw2LjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIC0wLjYsMC42IC0wLjksMS4zIC0xLjEsMiAwLjYsMi41IDEuNCw0LjkgMi41LDcuMiAtMC45LC0yLjggLTEuNCwtNS45IC0xLjQsLTkuMiB6IG0gNTQyLjE5OTk5NywxNy45IGMgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy41LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjUsLTEuNCAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC45IC0wLjEsMS42IDAuMiwyLjIgMS41LDEuNiAzLjMsMyA1LjEsNC40IDUuNiwzLjQgMTIsMy45IDE4LjYsMy45IDE2Mi4wOTk5OTcsLTAuMSAzMjQuMTk5OTk3LC0wLjEgNDg2LjI5OTk5NywtMC4xIDIuMywwIDQuNiwwLjEgNywtMC4xIDQuOSwtMC40IDkuNSwtMS45IDEzLjQsLTQuOCAwLjUsLTAuNCAxLjEsLTAuOCAxLjYsLTEuMiAxLjQsLTEgMi40LC0yLjMgMiwtNC4yIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwOTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMy4yODc2NjMsNTMuMDcgYyAwLjEsMC4xIDAuMywwLjEgMC40LDAuMiAtMC41LC0wLjggLTAuOSwtMS43IC0xLjIsLTIuOCAtMC4zLDAuNSAtMC40LDEgLTAuNSwxLjQgMC40LDAuNCAwLjgsMC44IDEuMywxLjIgeiBtIDUzMi43OTk5OTcsLTEuMiBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjUsMi4yIDAuNSwtMC4yIDAuOCwtMC41IDEuMSwtMC44IHogbSAtMy40LDUuNSBjIDAuNSwtMC40IDEsLTAuNyAxLjUsLTEuMSAtMC42LDAuNCAtMS4xLDAuOCAtMS42LDEuMiAwLC0wLjEgMCwtMC4xIDAuMSwtMC4xIHogTSAyNS4zODc2NjMsNTcuMjcgYyAwLjYsMC41IDEuMiwwLjkgMS45LDEuMiAtMS45LC0xLjQgLTMuNiwtMi44IC01LjEsLTQuNCAwLjYsMS4zIDIsMi4zIDMuMiwzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC41ODc2NiwzOC40NyBjIDAuMiwwLjYgMC4zLDEuMiAwLjQsMS44IDAuMiwtMS40IDAuMywtMi45IDAuMywtNC40IDAsMC4yIDAsMC4zIC0wLjEsMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDk1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDM4LjQ3IGMgMC4yLC0wLjcgMC41LC0xLjQgMC43LC0yLjEgMCwtMC4yIDAsLTAuMyAwLjEsLTAuNSAwLC0yLjggLTAuNCwtNS44IC0xLjMsLTguOSAwLDMuMiAtMC4xLDYuNCAtMC4xLDkuNiAwLjIsMC43IDAuNCwxLjMgMC42LDEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAsMS41IC0wLjEsMyAtMC4zLDQuNCAxLjEsNi42IC0zLjUsMTEuMyAtOCwxNS45IDguMiwtNC4yIDEyLC0xNi4zIDguOCwtMjUuNiAwLDEuOCAtMC4xLDMuNiAtMC41LDUuMyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAuNCwtMS44IDAuNSwtMy41IDAuNCwtNS4zIC0wLjQsLTEuMyAtMSwtMi41IC0xLjcsLTMuNiAwLjksMy4xIDEuMyw2LjEgMS4zLDguOSB6IG0gLTEsMy41IGMgMC4yLDMuNSAtMC44LDYuNSAtMi4zLDkuNCAxLjUsLTIuNSAyLjYsLTUuMyAzLC04LjQgLTAuMSwtMC42IC0wLjIsLTEuMiAtMC40LC0xLjggLTAuMSwwLjIgLTAuMiwwLjUgLTAuMywwLjggeiBtIC0wLjQsLTIuOCBjIDAuMiwwLjkgMC4zLDEuOSAwLjQsMi44IGwgMC4zLC0wLjkgYyAtMC4yLC0wLjYgLTAuNCwtMS4yIC0wLjcsLTEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEwMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC45ODc2Niw0MC4yNyBjIC0wLjUsMy4xIC0xLjUsNS45IC0zLDguNCAtMS40LDIuNiAtMy4yLDUgLTUsNy41IDQuNSwtNC42IDksLTkuMyA4LC0xNS45IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTAzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDMwOC4wNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTQsLTEuMyAtMjAuMSwtNS4xIDMsNS4zIDkuMyw1LjYgMTQuNyw3IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MTA1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuODg3NjYzLDMwNi4xNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjcgMC41LC0xLjQgMC40LC0yLjMgLTYuNiw0LjQgLTEzLjcsNS45IC0yMS43LDUuOSAtMTYzLjIsLTAuMSAtMzI2LjUsLTAuMSAtNDg5LjY5OTk5NywwIC04LDAgLTE1LjEsLTEuNSAtMjEuNywtNS45IDAuMywxLjEgMC43LDIgMS4yLDIuOCA2LjMsMy44IDEzLDUuMSAyMC4zLDUuMSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDEwNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDUzMi4xODc2NiwzMTAuMTcgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjM5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzYuMDg3NjYgYyA0LjMsMCA4LjMsLTAuNiAxMi4xLC0yLjQgMS42LC0wLjggMywtMS44IDQuMywtMi45IC00LDIuOSAtOC42LDQuNSAtMTMuNSw0LjkgLTIuMSwwLjIgLTQuNSwwLjEgLTYuOCwwLjEgeiBtIDIzLjksLTEwLjUgYyAwLjQsMS42IC0wLjMsMi43IC0xLjMsMy43IDEuMywtMS4xIDIuNiwtMi4zIDQsLTMuNSAxLjUsLTEuNCAyLjcsLTIuOSAzLjcsLTQuNSAxLjEsLTIuNiAxLjksLTUuMyAxLjgsLTguMiAtMS44LDQuOCAtNC4yLDkuMiAtOC4yLDEyLjUgeiBtIC01MzQuMTk5OTk3LDAgYyAtMi45LC0yLjUgLTUsLTUuNSAtNi42LC04LjggMS40LDQuMiAzLjcsNy44IDYuOCwxMSAtMC4yLC0wLjYgLTAuMywtMS4zIC0wLjIsLTIuMiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTA5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjE4NzY2LDI4Ny4yNyBjIDAsLTAuOSAtMC4xLC0xLjkgLTAuNCwtMi45IC0yLDUuMSAtNC41LDkuOSAtOC4zLDEzLjkgMC4zLDAuNSAwLjUsMSAwLjYsMS40IDQsLTMuMyA2LjQsLTcuNyA4LjEsLTEyLjQgeiBtIC01NDIuMjk5OTk3LDEyLjQgYyAwLjEsLTAuNCAwLjMsLTAuOSAwLjYsLTEuNCAtNC40LC00LjcgLTcuMywtMTAuMiAtOC42LC0xNi41IDAsMy4zIDAuNSw2LjQgMS40LDkuMiAxLjYsMy4yIDMuNyw2LjIgNi42LDguNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTExIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU4Ljc4NzY2LDI5OS45NyBjIC0xLjMsMS4yIC0yLjYsMi4zIC00LDMuNSAtMC41LDAuNSAtMS4xLDEgLTEuNywxLjQgLTAuMSwwLjEgLTAuMiwwLjIgLTAuNCwwLjMgLTEuNCwxLjEgLTIuOCwyLjEgLTQuMywyLjkgLTMuOCwxLjggLTcuOSwyLjQgLTEyLjEsMi40IEggNDIuMDg3NjYzIGMgLTQuMiwwIC04LjMsLTAuNSAtMTIuMiwtMi40IC0wLjksLTAuNiAtMS43LC0xLjEgLTIuNSwtMS43IC0wLjYsLTAuNCAtMS4zLC0wLjggLTEuOSwtMS4zIC0xLjIsLTAuOSAtMi42LC0xLjkgLTMuMiwtMy4xIC0zLjEsLTMuMiAtNS41LC02LjggLTYuOCwtMTEgLTEuMSwtMi4zIC0xLjksLTQuNiAtMi41LC03LjIgLTAuMywxLjQgMC4xLDMgMC4zLDQuNSAxLjMsOC44IDYuNiwxNC45IDEzLjQsMTkuOSAxMi4yLDMuNyAyNC43LDIuOCAzNy4yLDIuOCBIIDUxMy42ODc2NiBjIDEyLjcsMCAyNS40LDAuOSAzNy45LC0yLjggMi44LC0yLjMgNS41LC00LjYgOC4zLC03IDAuOSwtMS45IDEuOSwtMy44IDIuNywtNS44IC0xLjEsMS43IC0yLjMsMy4yIC0zLjgsNC42IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsMjgxLjc3IGMgLTAuNiwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNiwyLjUgMS40LDQuOSAyLjUsNy4yIC0wLjksLTIuOCAtMS40LC01LjkgLTEuNCwtOS4yIHogbSA1NDIuMTk5OTk3LDE3LjkgYyAtMC4zLDAuMyAtMC43LDAuNiAtMSwwLjggLTAuNywxLjYgLTIuMiwyLjYgLTMuOCwzLjUgLTUuMiwyLjkgLTEwLjYsNC4yIC0xNi42LDQuMiAtMTYzLjgsLTAuMSAtMzI3LjYsLTAuMSAtNDkxLjI5OTk5NywtMC4xIC0xLjYsMCAtMy4zLDAuMyAtNC45LC0wLjEgLTUuNCwtMS41IC0xMS43LC0xLjcgLTE0LjgsLTcgLTAuMSwtMC4xIC0wLjMsLTAuMSAtMC40LC0wLjIgLTAuNSwtMC40IC0wLjksLTAuOCAtMS40LC0xLjIgLTAuMiwwLjggLTAuMSwxLjYgMC4yLDIuMiAxLjUsMS42IDMuMywzIDUuMSw0LjQgNS42LDMuNCAxMiwzLjkgMTguNiwzLjkgMTYyLjA5OTk5NywtMC4xIDMyNC4xOTk5OTcsLTAuMSA0ODYuMzk5OTk3LC0wLjEgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNiwtMiAxMy41LC00LjkgMC4xLC0wLjEgMC4yLC0wLjIgMC40LC0wLjMgMC42LC0wLjUgMS4xLC0wLjkgMS43LC0xLjQgMSwtMC44IDEuNywtMiAxLjMsLTMuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDI5OS42NyBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjQsMi4zIDAuMywtMC4zIDAuNywtMC42IDEsLTAuOSB6IG0gLTUzMi43OTk5OTcsMS4yIGMgMC4xLDAuMSAwLjMsMC4xIDAuNCwwLjIgLTAuNSwtMC44IC0wLjksLTEuOCAtMS4yLC0yLjggLTAuMywwLjUgLTAuNSwxIC0wLjYsMS40IDAuNSwwLjQgMC45LDAuOCAxLjQsMS4yIHogbSAyLjEsNC4yIGMgMC42LDAuNSAxLjMsMC45IDEuOSwxLjMgLTEuOSwtMS40IC0zLjYsLTIuOCAtNS4xLC00LjQgMC42LDEuMiAyLDIuMSAzLjIsMy4xIHogbSA1MjkuMzk5OTk3LC0xLjYgYyAtMC42LDAuNSAtMS4xLDAuOSAtMS43LDEuNCAwLjYsLTAuNSAxLjIsLTAuOSAxLjcsLTEuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDI4Ni4wNyBjIDAuMiwwLjYgMC40LDEuMiAwLjUsMS44IDAuMiwtMS40IDAuMiwtMi44IDAuMiwtNC4yIDAsMC4yIC0wLjEsMC40IC0wLjEsMC42IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTE5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjE4NzY2LDI4NC4yNyBjIDAuMSwtMC4yIDAuMSwtMC40IDAuMSwtMC42IC0wLjEsLTIuNCAtMC41LC00LjkgLTEuMiwtNy40IGwgLTAuMyw4LjEgYyAwLjMsMC42IDAuNiwxLjEgMC44LDEuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4xODc2NiwyODcuODcgYyAwLjksNS4xIC0yLjQsOS4yIC01LjQsMTMuNCA2LjUsLTUuNSA4LjksLTE1LjIgNiwtMjIuMiAwLDEuNSAtMC4xLDMuMSAtMC40LDQuNiAwLDEuNCAtMC4xLDIuOCAtMC4yLDQuMiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwyODMuNTcgYyAwLjMsLTEuNSAwLjQsLTMuMSAwLjQsLTQuNiAtMC40LC0xIC0xLC0yIC0xLjYsLTIuOCAwLjcsMi42IDEuMSw1IDEuMiw3LjQgeiBtIC0xLjEsMy43IGMgMC4xLDIuOSAtMC43LDUuNiAtMS44LDguMiAxLjUsLTIuNCAyLjMsLTUgMi43LC03LjYgLTAuMSwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuMSwwLjQgLTAuMiwwLjggLTAuNCwxLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxMjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjQuNTg3NjYsMjg2LjA3IGMgLTAuMiwtMC42IC0wLjQsLTEuMSAtMC44LC0xLjcgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAuMiwtMC40IDAuMywtMC44IDAuNCwtMS4yIHogbSAwLjYsMS44IGMgLTAuNCwyLjcgLTEuMiw1LjIgLTIuNyw3LjYgLTAuOCwxLjkgLTEuOCwzLjggLTIuNyw1LjggMi45LC00LjIgNi4zLC04LjMgNS40LC0xMy40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTI3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDQ3Mi4zNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTMuOSwtMS4zIC0yMC4xLC01LjEgMyw1LjMgOS4zLDUuNSAxNC43LDcgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA0My43ODc2NjMsNDcwLjQ3IGMgMTYzLjM5OTk5NywtMC4xIDMyNi44OTk5OTcsLTAuMSA0OTAuMjk5OTk3LDAgNy40LDAgMTQuMiwtMS40IDIwLjUsLTUuMyAwLjEsLTAuMSAwLjMsLTAuMiAwLjQsLTAuMyAwLjMsLTAuNyAwLjUsLTEuNCAwLjQsLTIuMyAtNi42LDQuNCAtMTMuNyw1LjkgLTIxLjcsNS45IC0xNjMuMiwtMC4xIC0zMjYuNSwtMC4xIC00ODkuNjk5OTk3LDAgLTgsMCAtMTUuMSwtMS41IC0yMS43LC01LjkgMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuNCwzLjcgMTMuMSw1LjEgMjAuMyw1LjEgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMzEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS44ODc2NjMsNDYzLjk3IGMgLTMuMSwtMi43IC01LjQsLTYgLTcsLTkuNiAxLjQsNC41IDMuOSw4LjMgNy4yLDExLjcgLTAuMiwtMC42IC0wLjMsLTEuMyAtMC4yLC0yLjEgeiBtIDU0Mi4yOTk5OTcsLTEyLjUgYyAtMS43LDQuOCAtNC4yLDkuMSAtOC4xLDEyLjUgMC42LDIuNSAtMS41LDQgLTMuMyw1LjQgLTQsMi45IC04LjYsNC41IC0xMy42LDQuOSAtMi4zLDAuMiAtNC42LDAuMSAtNywwLjEgLTE2Mi4xLDAgLTMyNC4zLDAgLTQ4Ni4zOTk5OTcsMC4xIC03LDAgLTEzLjcsLTAuNiAtMTkuNSwtNC41IDEuMSwwLjkgMi4yLDEuOCAzLjQsMi43IDQuMiwxLjcgOC41LDIuMSAxMywyLjEgSCA1MzUuMjg3NjYgYyA0LjcsMCA5LjIsLTAuNSAxMy42LC0yLjMgMS45LC0xLjQgMy43LC0yLjkgNS44LC00IDIuNywtMS42IDQuOSwtMy44IDYuNiwtNi41IDEuOSwtMy4yIDMuMSwtNi42IDIuOSwtMTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuODg3NjYzLDQ2My45NyBjIDAuMSwtMC40IDAuMywtMC45IDAuNiwtMS40IC00LjQsLTQuNyAtNy4zLC0xMC4yIC04LjYsLTE2LjUgLTAuMSwzLjEgMC4zLDUuOCAxLjEsOC40IDEuNiwzLjYgMy44LDYuOCA2LjksOS41IHogbSA1NDIuMjk5OTk3LC0xMi41IGMgMCwtMC45IC0wLjIsLTEuOSAtMC40LC0yLjkgLTIsNS4xIC00LjUsOS45IC04LjMsMTMuOSAwLjMsMC41IDAuNSwxIDAuNiwxLjQgNCwtMy4zIDYuNCwtNy42IDguMSwtMTIuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0LjY4NzY2LDQ2OC40NyBjIC0yLjEsMS4xIC0zLjksMi42IC01LjgsNCAtNC4zLDEuOCAtOC45LDIuMyAtMTMuNiwyLjMgSCA0Mi42ODc2NjMgYyAtNC41LDAgLTguOCwtMC40IC0xMywtMi4xIC0xLjIsLTAuOSAtMi4zLC0xLjcgLTMuNCwtMi43IC0wLjMsLTAuMiAtMC42LC0wLjQgLTAuOSwtMC43IC0xLjMsLTEgLTIuNywtMS45IC0zLjMsLTMuMiAtMy4zLC0zLjQgLTUuOCwtNy4yIC03LjIsLTExLjcgLTAuOSwtMiAtMS42LC00LjIgLTIuMSwtNi40IC0wLjYsMS45IC0wLjEsMy45IDAuNCw1LjkgMS44LDguMSA3LDEzLjggMTMuNCwxOC42IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjU4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjQsLTAuOSAyLjgsLTEuOSA0LjEsLTIuOCAyLC0yLjUgNC4xLC01IDUuNywtNy43IC0xLjcsMi42IC0zLjksNC44IC02LjYsNi41IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsNDQ2LjA3IGMgLTAuNSwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNSwyLjIgMS4yLDQuNCAyLjEsNi40IC0wLjcsLTIuNiAtMS4xLC01LjQgLTEsLTguNCB6IG0gNTE4LjM5OTk5NywyOC40IGMgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNSwtMiAxMy42LC00LjkgMS45LC0xLjQgMy45LC0yLjkgMy4zLC01LjQgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy42LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjQsLTEuNSAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC44IC0wLjEsMS41IDAuMiwyLjEgMS4zLDEuNCAyLjcsMi42IDQuMiwzLjkgNS45LDMuOSAxMi41LDQuNSAxOS41LDQuNSAxNjIuMDk5OTk3LC0wLjEgMzI0LjE5OTk5NywwIDQ4Ni4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMjg3NjYzLDQ2NS4xNyBjIDAuMSwwLjEgMC4zLDAuMSAwLjQsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjMsMC41IC0wLjUsMSAtMC42LDEuNCAwLjUsMC40IDAuOSwwLjggMS40LDEuMiB6IG0gNTMyLjc5OTk5NywtMS4yIGMgLTAuMSwtMC40IC0wLjMsLTAuOSAtMC42LC0xLjQgMCwwLjkgLTAuMiwxLjYgLTAuNCwyLjMgMC4zLC0wLjMgMC43LC0wLjYgMSwtMC45IHogbSAtNTMwLjY5OTk5Nyw1LjMgYyAwLjMsMC4yIDAuNiwwLjQgMC45LDAuNyAtMS41LC0xLjIgLTIuOSwtMi41IC00LjIsLTMuOSAwLjYsMS4zIDIsMi4zIDMuMywzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDE0MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgYyAwLjIsMC44IDAuMywxLjUgMC40LDIuMyAwLjQsLTEuOCAwLjUsLTMuNiAwLjUsLTUuNSAtMC4xLDAuMyAtMC4xLDAuNiAtMC4yLDEgLTAuMiwwLjYgLTAuNCwxLjQgLTAuNywyLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuMTg3NjYsNDQ4LjQ3IGMgMC4xLC0wLjMgMC4xLC0wLjYgMC4yLC0xIDAsLTIuOCAtMC41LC01LjcgLTEuNCwtOC40IC0wLjEsMy4yIC0wLjEsNi40IC0wLjIsOS41IDAuMywwLjcgMC41LDEuNCAwLjYsMi4xIDAuNCwtMC43IDAuNiwtMS41IDAuOCwtMi4yIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjM4NzY2LDQ0Ny40NyBjIDAsMS45IC0wLjIsMy43IC0wLjUsNS41IDAuNSw1LjggLTIuNiwxMS4yIC05LjMsMTYuNyA3LjksLTMuNCAxMC40LC0xMC41IDExLC0xOCAwLjMsLTMuNiAxLjksLTcuOSAtMC45LC0xMS4yIDAuMSwyLjMgMC4xLDQuNyAtMC4zLDcgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsNDM5LjA3IGMgMC45LDIuOCAxLjMsNS42IDEuNCw4LjQgMC40LC0yLjMgMC40LC00LjcgMC4yLC03LjEgLTAuNCwtMC40IC0wLjksLTAuOSAtMS42LC0xLjMgeiBtIDAuMiwxMi40IGMgMC4yLDQgLTEuMSw3LjMgLTMsMTAuNSAxLjcsLTIuNiAyLjksLTUuNyAzLjYsLTguOSAtMC4xLC0wLjggLTAuMiwtMS41IC0wLjQsLTIuMyAwLDAuMiAtMC4xLDAuNCAtMC4yLDAuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE0OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgLTAuNiwtMi4xIGMgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAsLTAuNCAwLjEsLTAuNiAwLjIsLTAuOCB6IG0gMC40LDIuMiBjIC0wLjYsMy4yIC0xLjksNi4zIC0zLjYsOC45IC0xLjYsMi43IC0zLjcsNS4yIC01LjcsNy43IDYuNywtNS40IDkuNywtMTAuOCA5LjMsLTE2LjYgeiBtIC01MjIuMTk5OTk3LDIzIGMgLTUuNywwIC0xMSwtMS4xIC0xNi4xLC0zLjUgMy44LDQuMyA4LjksNC4yIDE0LDQuMiBIIDUzNi43ODc2NiBjIDUuMywwIDEwLjYsMC4yIDE0LjcsLTQuMiAtNS4xLDIuNCAtMTAuNSwzLjUgLTE2LjEsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTEzLjU4NzY2LDQ3NS4yNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuMSwyLjQgMTAuNCwzLjUgMTYuMSwzLjUgSCA1MzUuMjg3NjYgYyA1LjcsMCAxMSwtMS4xIDE2LjEsLTMuNSAtMTIuNCwzLjcgLTI1LjEsMi44IC0zNy44LDIuOCB6IG0gMTkuNiwtMTYzLjUgYyAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIC02LjQsMCAtMTIuNCwtMSAtMTguMiwtMy41IDMuNywzLjMgOC4xLDQuMiAxMi44LDQuMiBIIDUzOC41ODc2NiBjIDQuNywwIDkuMiwtMC45IDEyLjgsLTQuMiAtNS44LDIuNSAtMTEuOCwzLjUgLTE4LjIsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTMzLjE4NzY2LDMxMS43NyBjIDYuNCwwIDEyLjQsLTEgMTguMiwtMy41IC0xMi40LDMuNyAtMjUuMiwyLjggLTM3LjksMi44IEggNjMuNjg3NjYzIGMgLTEyLjQsMCAtMjUsMC45IC0zNy4yLC0yLjggNS44LDIuNiAxMS44LDMuNSAxOC4yLDMuNSAxNjIuODk5OTk3LC0wLjEgMzI1LjY5OTk5NywtMC4xIDQ4OC40OTk5OTcsMCB6IE0gNDQuNzg3NjYzLDYzLjk3IGMgLTYuNCwwIC0xMi40LC0xIC0xOC4yLC0zLjUgMy43LDMuMyA4LjEsNC4yIDEyLjgsNC4yIEggNTM4LjU4NzY2IGMgNC43LDAgOS4yLC0wLjkgMTIuOCwtNC4yIC01LjgsMi42IC0xMS44LDMuNSAtMTguMiwzLjUgLTE2Mi44LC0wLjEgLTMyNS42LC0wLjEgLTQ4OC4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJNIDUxMy41ODc2Niw2My4xNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuOCwyLjYgMTEuOCwzLjUgMTguMiwzLjUgMTYyLjc5OTk5NywtMC4xIDMyNS41OTk5OTcsLTAuMSA0ODguMzk5OTk3LDAgNi40LDAgMTIuNCwtMSAxOC4yLC0zLjUgLTEyLjQsMy43IC0yNS4xLDIuOCAtMzcuOCwyLjggeiBtIC00NjguNzk5OTk3LDgyLjkgYyAtNi40LDAgLTEyLjQsLTEgLTE4LjIsLTMuNSAzLjcsMy4zIDguMSw0LjIgMTIuOCw0LjIgSCA1MzguNTg3NjYgYyA0LjcsMCA5LjIsLTAuOSAxMi44LC00LjIgLTUuOCwyLjUgLTExLjgsMy41IC0xOC4yLDMuNSAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTE0LjI4NzY2LDE0NS4yNyBIIDY0LjQ4NzY2MyBjIC0xMi43LDAgLTI1LjQsMC45IC0zNy45LC0yLjggNS44LDIuNSAxMS44LDMuNSAxOC4yLDMuNSAxNjIuNzk5OTk3LC0wLjEgMzI1LjU5OTk5NywtMC4xIDQ4OC4zOTk5OTcsMCA2LjQsMCAxMi40LC0xIDE4LjIsLTMuNSAtMTIuMSwzLjggLTI0LjcsMi44IC0zNy4xLDIuOCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQwLjI4NzY2MywzOTEuMDcgaCAxLjYgYyAxLjEsMCAyLjIsLTAuMiAzLjMsLTAuMiBIIDUzMi43ODc2NiBjIDAuOCwwIDEuNiwwLjEgMi40LDAuMSAxLjEsMCAyLjIsLTAuMSAzLjMsLTAuMSAwLjYsLTAuMSAxLjIsLTAuMyAxLjgsLTAuNyBIIDM3LjY4NzY2MyBjIDAuOSwwLjYgMS44LDAuOSAyLjYsMC45IHogbSA0OTguMTk5OTk3LC0wLjEgYyAtMS4xLDAuMSAtMi4yLDAuMSAtMy4zLDAuMSAxLjEsMC4xIDIuMiwwLjIgMy4zLC0wLjEgeiBtIC00OTQuMzk5OTk3LDAuNyBoIC00IGMgMS4zLDAuMyAyLjcsMC4xIDQsMCB6IG0gNDkzLjc5OTk5NywwIGggLTQuMiBjIDEuNCwwLjEgMi45LDAuMyA0LjIsMCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQ1LjE4NzY2MywzOTAuOTcgYyAtMS4xLDAgLTIuMiwwLjEgLTMuMywwLjIgSCA1MzUuMDg3NjYgYyAtMC44LDAgLTEuNiwtMC4xIC0yLjQsLTAuMSAtMTYyLjQsMCAtMzI0LjksMCAtNDg3LjQ5OTk5NywtMC4xIHogbSA0OTQuNDk5OTk3LC0wLjEgYyAwLjIsLTAuMiAwLjQsLTAuMyAwLjYsLTAuNiAtMC42LDAuMyAtMS4yLDAuNSAtMS44LDAuNyAwLjQsMCAwLjgsMCAxLjIsLTAuMSB6IG0gLTUwMS45OTk5OTcsLTAuNSBjIDAuMiwwLjMgMC41LDAuNSAwLjcsMC42IDAuNCwwIDAuNywwLjEgMS4xLDAuMSBoIDAuOCBjIC0wLjgsMCAtMS43LC0wLjMgLTIuNiwtMC43IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MTYzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTM4LjQ4NzY2LDM5MC45NyBjIC0xLjEsMC4yIC0yLjIsMC4yIC0zLjMsMC4xIEggMzkuNTg3NjYzIGMgLTAuNCwwIC0wLjcsLTAuMSAtMS4xLC0wLjEgMC41LDAuNCAxLjEsMC42IDEuNywwLjggSCA1MzcuODg3NjYgYyAwLjYsLTAuMSAxLjIsLTAuNCAxLjcsLTAuOCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+Cjwvc3ZnPgo= - mediatype: image/svg+xml - install: - spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.1.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: - - rules: - - apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - - limitranges - - componentstatuses - - persistentvolumes - - bindings - - replicationcontrollers - - resourcequotas - - podtemplates - - serviceaccounts - verbs: - - '*' - - apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - '*' - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - apps - resources: - - replicasets - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - '*' - verbs: - - '*' - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - '*' - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - '*' - serviceAccountName: nexus-operator - strategy: deployment - installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - nexus - - sonatype - - maven - - docker - - ci - - continuous integration - - continuous delivery - - repository - - repository manager - - dev tools - - "" - links: - - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/master/README.md - - name: Source - url: https://github.com/m88i/nexus-operator - maintainers: - - email: ricardozanini@gmail.com - name: m88i Labs - maturity: alpha - provider: - name: m88i Labs - version: 0.1.0 diff --git a/deploy/olm-catalog/nexus-operator/0.2.0/apps.m88i.io_nexus_crd.yaml b/deploy/olm-catalog/nexus-operator/0.2.0/apps.m88i.io_nexus_crd.yaml deleted file mode 100644 index dd2c6975..00000000 --- a/deploy/olm-catalog/nexus-operator/0.2.0/apps.m88i.io_nexus_crd.yaml +++ /dev/null @@ -1,230 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: nexus.apps.m88i.io -spec: - group: apps.m88i.io - names: - kind: Nexus - listKind: NexusList - plural: nexus - singular: nexus - scope: Namespaced - validation: - openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NexusSpec defines the desired state of Nexus - properties: - image: - description: 'Full image tag name for this specific deployment Default: - docker.io/sonatype/nexus3:latest' - type: string - networking: - description: Networking definition - properties: - expose: - description: Set to `true` to expose the Nexus application. Default - to false. - type: boolean - exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Default to Route on OpenShift and Ingress on Kubernetes.' - enum: - - NodePort - - Route - - Ingress - type: string - host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. - type: string - nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. - format: int32 - type: integer - tls: - description: TLS/SSL-related configuration - properties: - mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to false. - type: boolean - secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. - type: string - type: object - type: object - persistence: - description: Persistence definition - properties: - persistent: - description: Flag to indicate if this instance will be persistent - or not - type: boolean - storageClass: - description: StorageClass used by the managed PVC. - type: string - volumeSize: - description: 'If persistent, the size of the Volume. Defaults: 10Gi' - type: string - required: - - persistent - type: object - replicas: - description: 'Number of pods replicas desired Default: 1' - format: int32 - maximum: 100 - minimum: 1 - type: integer - resources: - description: Defined Resources for the Nexus instance - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR. - type: string - useRedHatImage: - description: 'If you have access to Red Hat Container Catalog, turn - this to true to use the certified image provided by Sonatype Default: - false' - type: boolean - required: - - persistence - - replicas - - useRedHatImage - type: object - status: - description: NexusStatus defines the observed state of Nexus - properties: - deploymentStatus: - description: Condition status for the Nexus deployment - properties: - availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. - format: int32 - type: integer - collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. - format: int32 - type: integer - conditions: - description: Represents the latest available observations of a deployment's - current state. - items: - description: DeploymentCondition describes the state of a deployment - at a certain point. - properties: - lastTransitionTime: - description: Last time the condition transitioned from one - status to another. - format: date-time - type: string - lastUpdateTime: - description: The last time this condition was updated. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of deployment condition. - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: The generation observed by the deployment controller. - format: int64 - type: integer - readyReplicas: - description: Total number of ready pods targeted by this deployment. - format: int32 - type: integer - replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). - format: int32 - type: integer - unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. - format: int32 - type: integer - updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. - format: int32 - type: integer - type: object - nexusRoute: - description: Route for external service access - type: string - nexusStatus: - description: Will be "OK" when all objects are created successfully - type: string - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/olm-catalog/nexus-operator/0.2.1/apps.m88i.io_nexus_crd.yaml b/deploy/olm-catalog/nexus-operator/0.2.1/apps.m88i.io_nexus_crd.yaml deleted file mode 100644 index dd2c6975..00000000 --- a/deploy/olm-catalog/nexus-operator/0.2.1/apps.m88i.io_nexus_crd.yaml +++ /dev/null @@ -1,230 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: nexus.apps.m88i.io -spec: - group: apps.m88i.io - names: - kind: Nexus - listKind: NexusList - plural: nexus - singular: nexus - scope: Namespaced - validation: - openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NexusSpec defines the desired state of Nexus - properties: - image: - description: 'Full image tag name for this specific deployment Default: - docker.io/sonatype/nexus3:latest' - type: string - networking: - description: Networking definition - properties: - expose: - description: Set to `true` to expose the Nexus application. Default - to false. - type: boolean - exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Default to Route on OpenShift and Ingress on Kubernetes.' - enum: - - NodePort - - Route - - Ingress - type: string - host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. - type: string - nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. - format: int32 - type: integer - tls: - description: TLS/SSL-related configuration - properties: - mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to false. - type: boolean - secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. - type: string - type: object - type: object - persistence: - description: Persistence definition - properties: - persistent: - description: Flag to indicate if this instance will be persistent - or not - type: boolean - storageClass: - description: StorageClass used by the managed PVC. - type: string - volumeSize: - description: 'If persistent, the size of the Volume. Defaults: 10Gi' - type: string - required: - - persistent - type: object - replicas: - description: 'Number of pods replicas desired Default: 1' - format: int32 - maximum: 100 - minimum: 1 - type: integer - resources: - description: Defined Resources for the Nexus instance - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR. - type: string - useRedHatImage: - description: 'If you have access to Red Hat Container Catalog, turn - this to true to use the certified image provided by Sonatype Default: - false' - type: boolean - required: - - persistence - - replicas - - useRedHatImage - type: object - status: - description: NexusStatus defines the observed state of Nexus - properties: - deploymentStatus: - description: Condition status for the Nexus deployment - properties: - availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. - format: int32 - type: integer - collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. - format: int32 - type: integer - conditions: - description: Represents the latest available observations of a deployment's - current state. - items: - description: DeploymentCondition describes the state of a deployment - at a certain point. - properties: - lastTransitionTime: - description: Last time the condition transitioned from one - status to another. - format: date-time - type: string - lastUpdateTime: - description: The last time this condition was updated. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of deployment condition. - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: The generation observed by the deployment controller. - format: int64 - type: integer - readyReplicas: - description: Total number of ready pods targeted by this deployment. - format: int32 - type: integer - replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). - format: int32 - type: integer - unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. - format: int32 - type: integer - updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. - format: int32 - type: integer - type: object - nexusRoute: - description: Route for external service access - type: string - nexusStatus: - description: Will be "OK" when all objects are created successfully - type: string - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/olm-catalog/nexus-operator/0.3.0/nexus-operator.v0.3.0.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/0.3.0/nexus-operator.v0.3.0.clusterserviceversion.yaml deleted file mode 100644 index 7bf7b7e3..00000000 --- a/deploy/olm-catalog/nexus-operator/0.3.0/nexus-operator.v0.3.0.clusterserviceversion.yaml +++ /dev/null @@ -1,323 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "apps.m88i.io/v1alpha1", - "kind": "Nexus", - "metadata": { - "name": "nexus3" - }, - "spec": { - "networking": { - "expose": false - }, - "persistence": { - "persistent": false - }, - "replicas": 1, - "resources": { - "limits": { - "cpu": "2", - "memory": "2Gi" - }, - "requests": { - "cpu": "1", - "memory": "2Gi" - } - }, - "useRedHatImage": false - } - } - ] - capabilities: Seamless Upgrades - categories: Developer Tools - certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.3.0 - createdAt: "2019-11-16T13:12:22Z" - description: Nexus Operator to deploy and manage Nexus 3.x servers - repository: https://github.com/m88i/nexus-operator - support: m88i Labs - tectonic-visibility: ocs - name: nexus-operator.v0.3.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Nexus custom resource to deploy the Nexus Server - displayName: Nexus - kind: Nexus - name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: A Kubernetes Deployment - version: v1 - - kind: PersistentVolumeClaim - name: A Kubernetes PersistentVolumeClaim - version: v1 - - kind: Service - name: A Kubernetes Service - version: v1 - specDescriptors: - - description: Automatic updates configuration - displayName: Automatic Update - path: automaticUpdate - - description: 'GenerateRandomAdminPassword enables the random password generation. - Defaults to `false`: the default password for a newly created instance is - ''admin123'', which should be changed in the first login. If set to `true`, - you must use the automatically generated ''admin'' password, stored in the - container''s file system at `/nexus-data/admin.password`. The operator uses - the default credentials to create a user for itself to create default repositories. - If set to `true`, the repositories won''t be created since the operator - won''t fetch for the random password.' - displayName: Generate Random Admin Password - path: generateRandomAdminPassword - - description: 'Full image tag name for this specific deployment. Will be ignored - if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: 'The image pull policy for the Nexus image. If left blank behavior - will be determined by the image tag (`Always` if "latest" and `IfNotPresent` - otherwise). Possible values: `Always`, `IfNotPresent` or `Never`.' - displayName: Image Pull Policy - path: imagePullPolicy - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:imagePullPolicy - - description: Number of pod replicas desired. Defaults to 0. - displayName: Replicas - path: replicas - - description: Defined Resources for the Nexus instance - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: ServerOperations describes the options for the operations performed - on the deployed server instance - displayName: Server Operations - path: serverOperations - - description: ServiceAccountName is the name of the ServiceAccount used to - run the Pods. If left blank, a default ServiceAccount is created with the - same name as the Nexus CR (`metadata.name`). - displayName: Service Account - path: serviceAccountName - - description: If you have access to Red Hat Container Catalog, set this to - `true` to use the certified image provided by Sonatype Defaults to `false` - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - statusDescriptors: - - description: Condition status for the Nexus deployment - displayName: appsv1.DeploymentStatus - path: deploymentStatus - - description: Route for external service access - displayName: Nexus Route - path: nexusRoute - - description: Will be "OK" when this Nexus instance is up - displayName: Nexus Status - path: nexusStatus - - description: Gives more information about a failure status - displayName: Reason - path: reason - x-descriptors: - - urn:alm:descriptor:io.kubernetes.phase:reason - - description: Conditions reached during an update - displayName: Update Conditions - path: updateConditions - version: v1alpha1 - description: |- - Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: - - * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world - * On OpenShift, creates a Route to expose the service outside the cluster - - [See our documentation](https://github.com/m88i/nexus-operator/blob/main/README.md) for more installation and usage scenarios. - - If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues) or send an email to our maillist: [nexus-operator@googlegroups.com](mailto:nexus-operator@googlegroups.com) - - *Please note that the operator is an individual work and it's not provided nor supported by Sonatype.* - displayName: Nexus Operator - icon: - - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgcm9sZT0iaW1nIgogICB2aWV3Qm94PSI4LjM3IDUuODcgNTYxLjI0MTYzIDQ3My40NDQ0NSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnNDE2NyIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic29uYXR5cGUtbmV4dXMtY3JvcC5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTIuNCAodW5rbm93bikiCiAgIHdpZHRoPSI1NjEuMjQxNjQiCiAgIGhlaWdodD0iNDczLjQ0NDQ2Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE0MTczIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT5Tb25hdHlwZSBOZXh1cyBsb2dvPC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczQxNzEiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijk5MCIKICAgICBpZD0ibmFtZWR2aWV3NDE2OSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMS4wNTE1OCIKICAgICBpbmtzY2FwZTpjeD0iMjgwLjQ2NzY3IgogICAgIGlua3NjYXBlOmN5PSIxMDcuOTk0NDQiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc0MTY3IiAvPgogIDx0aXRsZQogICAgIGlkPSJ0aXRsZTM5NjMiPlNvbmF0eXBlIE5leHVzIGxvZ288L3RpdGxlPgogIDxzdHlsZQogICAgIGlkPSJzdHlsZTM5NjUiPnN2ZyB7ZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2MDAgNzY0fTwvc3R5bGU+CiAgPHN0eWxlCiAgICAgaWQ9InN0eWxlMzk2NyI+LnN0NXtmaWxsOiNkNGQ0ZDR9LnN0NTR7ZmlsbDojMzI2Nzk4fS5zdDU1e2ZpbGw6I2ViZWJlYn0uc3Q1NntmaWxsOiMwMjAyMDJ9LnN0NTd7ZmlsbDojZWNlY2VjfS5zdDU4e2ZpbGw6IzAxMDEwMX0uc3Q2MHtmaWxsOiMwNDA0MDR9LnN0NjF7ZmlsbDojYmRiZGJkfS5zdDYye2ZpbGw6I2U4ZThlOH0uc3Q2M3tmaWxsOiNjZGNkY2V9LnN0NjR7ZmlsbDojY2ZjZmNmfTwvc3R5bGU+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAxLjksNS41IDQuNSwxMC42IDguNiwxNSA3LjIsNC45IDE1LjEsNi4xIDIzLjcsNi4xIDE2MS43OTk5OTcsLTAuMiAzMjMuNTk5OTk3LC0wLjIgNDg1LjM5OTk5NywwIDguNiwwIDE2LjUsLTEuMiAyMy43LC02LjEgNCwtNC4zIDYuNywtOS40IDguNiwtMTUgMC42LC02LjMgLTAuNywtMTIuMiAtMy4xLC0xOCAtNi42LC05LjMgLTE1LjUsLTEyLjggLTI2LjksLTEyLjggLTE2My4zLDAuMiAtMzI2LjYsMC4yIC00ODkuODk5OTk3LDAgLTExLjQsMCAtMjAuMywzLjUgLTI2LjksMTIuOCAtMi41LDUuOCAtMy44LDExLjggLTMuMiwxOCB6IG0gMC4xLC04Mi4zIGMgMi4xLDUuMSA0LjQsMTAgOC4zLDEzLjkgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNTk5OTk3LC0wLjEgMzI1LjE5OTk5NywtMC4xIDQ4Ny43OTk5OTcsMCA3LjYsMCAxNC43LC0wLjggMjEuNCwtNC43IDIuMywtMi43IDQuNywtNS40IDcsLTguMSAxLC0zLjIgMiwtNi40IDMsLTkuNyAwLjQsLTYuNSAtMS44LC0xMi4zIC00LjgsLTE3LjkgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTEuNCwzLjcgLTQuOSw2LjUgLTQuNywxMSAwLjIsMy41IDAuMiw2LjcgMC4zLDkuOCB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk2OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzNjMuODcgYyAxLjEsMi4xIC0wLjMsNC45IDEuNiw2LjggMi40LDMuOSA1LDcuNyA4LjUsMTAuOSA2LjQsMy44IDEzLjMsNC43IDIwLjYsNC43IDE2My4wOTk5OTcsLTAuMSAzMjYuMTk5OTk3LC0wLjEgNDg5LjE5OTk5NywwIDgsMCAxNS4xLC0xLjQgMjEuNiwtNS45IDQuNSwtNC42IDYuOCwtMTAuNCA4LjYsLTE2LjUgMC4yLC02IC0xLjQsLTExLjUgLTQuMSwtMTYuNyAtNi4zLC04LjEgLTE0LjUsLTExLjIgLTI0LjgsLTExLjIgLTE2NC4yLDAuMSAtMzI4LjMsMC4xIC00OTIuNDk5OTk3LDAgLTEwLjMsMCAtMTguNSwzLjEgLTI0LjgsMTEuMiAtMi41LDUuMiAtNC4xLDEwLjggLTMuOSwxNi43IHoiCiAgICAgaWQ9InBhdGgzOTcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIDEuNCw2LjMgNC4xLDExLjkgOC42LDE2LjUgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNzk5OTk3LC0wLjEgMzI1LjQ5OTk5NywtMC4xIDQ4OC4yOTk5OTcsMCA4LjIsMCAxNS42LC0xLjMgMjIuNCwtNS44IDMuOSwtNCA2LjMsLTguOSA4LjMsLTEzLjkgMCwtMy4yIDAuMSwtNi40IDAuMSwtOS42IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTEgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTIuOSw1LjcgLTUuMSwxMS42IC00LjcsMTguMSB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk3MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywyODEuNzcgYyAxLjMsNi4zIDQuMiwxMS44IDguNiwxNi41IDYuNiw0LjQgMTMuNyw1LjkgMjEuNyw1LjkgMTYzLjE5OTk5NywtMC4xIDMyNi40OTk5OTcsLTAuMSA0ODkuNjk5OTk3LDAgOCwwIDE1LjEsLTEuNSAyMS43LC01LjkgMy44LC00IDYuNCwtOC44IDguMywtMTMuOSBsIDAuMywtOC4xIC00LjgsLTEyLjMgYyAtNi40LC03LjIgLTE0LjMsLTEwLjEgLTI0LC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC0xMC4zLDAgLTE4LjUsMy4xIC0yNC44LDExLjIgLTIuOCw1LjIgLTQuNCwxMC43IC00LjIsMTYuNyB6IG0gMCwxNjQuMyBjIDEuMyw2LjMgNC4yLDExLjggOC42LDE2LjUgNi42LDQuNCAxMy43LDUuOSAyMS43LDUuOSAxNjMuMTk5OTk3LC0wLjEgMzI2LjQ5OTk5NywtMC4xIDQ4OS42OTk5OTcsMCA4LDAgMTUuMSwtMS41IDIxLjcsLTUuOSAzLjgsLTQgNi40LC04LjggOC4zLC0xMy45IDAuMSwtMy4yIDAuMSwtNi40IDAuMiwtOS41IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTAuOSAtNi42LC03LjYgLTE0LjgsLTEwLjIgLTI0LjgsLTEwLjIgLTE2My43LDAuMiAtMzI3LjUsMC4yIC00OTEuMTk5OTk3LDAgLTkuOSwwIC0xOC4xLDIuNiAtMjQuNywxMC4xIC0zLjEsNS41IC01LjIsMTEuNCAtNC44LDE3LjkgeiIKICAgICBpZD0icGF0aDM5NzUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNDMuNjg3NjYzLDIzMi45NyBIIDQyMi4yODc2NiBjIDM3LjYsMCA3NS4yLDAuMiAxMTIuOCwtMC4xIDE0LjIsLTAuMSAyNS41LC02IDMxLjcsLTE5LjUgNS4zLC0xMS42IDIuOCwtMjQuNSAtNS45LC0zMC40IDUsNC45IDUuNSwxMS4xIDQuNywxNy41IC0wLjMsMS4xIC0wLjYsMi4xIC0wLjksMy4yIDEsOC45IC03LjUsMTkuMiAtMTQuNSwyMiAtNC43LDEuOSAtOS41LDMuMSAtMTQuOCwzLjEgLTE2NC4yLC0wLjEgLTMyOC4zLC0wLjEgLTQ5Mi40OTk5OTcsLTAuMSAtMTUuOSwwIC0yNi42LC04LjMgLTI5LjYsLTIyLjggLTAuMywtMS4zIC0wLjYsLTIuNSAtMC4yLC0zLjcgLTAuMiwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuOCwtNi41IC0wLjQsLTEyLjcgNC43LC0xNy42IC02LjIsNC4zIC05Ljk5OTk5OTcsMTQuNCAtOC4yOTk5OTk3LDIyLjUgMy4zOTk5OTk3LDE3LjYgMTYuMTk5OTk5NywyNy43IDM0LjY5OTk5OTcsMjcuNyB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk3NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjQ4NzY2MywyMDAuNjcgYyAwLjIsMC42IDAuMywxLjIgMC41LDEuOCAwLjIsLTAuNSAwLjUsLTEgMS4xLC0xLjQgLTAuNiwtNi4zIDAuNywtMTIuMiAzLjEsLTE4IC01LjEsNC45IC01LjUsMTEuMSAtNC43LDE3LjYgeiBtIDU1MS40OTk5OTcsMC4zIGMgMC4zLDAuOSAwLjUsMS44IDAuNiwyLjggMC4zLC0xIDAuNywtMi4xIDAuOSwtMy4yIDAuOCwtNi41IDAuNCwtMTIuNiAtNC43LC0xNy41IDIuNSw1LjcgMy44LDExLjcgMy4yLDE3LjkgeiBNIDQ0LjI4NzY2MywzOTcuMjcgSCA0NzEuODg3NjYgYyAyMS4xLDAgNDIuMiwwLjEgNjMuMywwIDE4LjMsLTAuMSAzMC4zLC05LjkgMzQsLTI3LjQgMS44LC04LjcgLTIuMywtMTkuMSAtOS4xLC0yMi43IDUsNC41IDYsMTAuNCA1LjYsMTYuNyAtMC4zLDEuMyAtMC42LDIuNSAtMC45LDMuOCAwLjUsOS43IC02LjksMjAuNiAtMTcuMSwyMy43IC0zLjcsMS4xIC03LjUsMS45IC0xMS42LDEuOSAtMTY0LjcsLTAuMSAtMzI5LjQsLTAuMSAtNDk0LjA5OTk5NywtMC4xIC0xNS43LDAgLTI1LjQsLTcuNyAtMjguOCwtMjIuNyAtMC4yLC0wLjkgLTAuNCwtMS44IC0wLjUsLTIuNiAtMC4zLC0xLjMgLTAuNSwtMi43IC0wLjUsLTQuMSAtMC4xLC02LjIgMC43LC0xMi4xIDUuNywtMTYuNSAtNi43LDMuNiAtMTAuODk5OTk5NywxNC4xIC05LjA5OTk5OTcsMjIuNyAzLjc5OTk5OTcsMTcuOSAxNS45OTk5OTk3LDI3LjMgMzUuNDk5OTk5NywyNy4zIHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTc5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjA4NzY2LDM2My44NyBjIDAuNCwxLjIgMC41LDIuNSAwLjYsMy43IDAuMywtMS4yIDAuNywtMi41IDAuOSwtMy44IDAuNCwtNi4zIC0wLjYsLTEyLjIgLTUuNiwtMTYuNyAyLjgsNS4zIDQuNCwxMC44IDQuMSwxNi44IHogbSAtNTUxLjg5OTk5NywtMC4yIGMgMCwxLjQgMC4yLDIuOCAwLjUsNC4xIC0wLjEsLTEuNCAwLC0yLjcgMS4yLC0zLjkgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LjEsNC40IC01LjksMTAuMyAtNS44LDE2LjUgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5ODEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTkuMjg3NjYsNDI4LjA3IGMgMy41LDMgNS4xLDcgNi4yLDExLjMgMCwwLjMgMC4xLDAuNyAwLjEsMSAyLjgsMy4zIDEuMiw3LjYgMC45LDExLjIgLTAuNiw3LjYgLTMuMSwxNC42IC0xMSwxOCAtMS40LDAuOSAtMi44LDEuOSAtNC4xLDIuOCAtNCw0LjQgLTkuNCw0LjIgLTE0LjcsNC4yIEggNDAuNDg3NjYzIGMgLTUsMCAtMTAuMiwwLjEgLTE0LC00LjIgLTYuNCwtNC44IC0xMS41LC0xMC41IC0xMy40LC0xOC42IC0wLjQsLTIgLTEsLTQgLTAuNCwtNS45IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjEsLTEzIDYuNCwtMTcuOCAtNy42LDMuOSAtOS42OTk5OTk3LDExIC0xMC4wOTk5OTk3LDE4LjUgLTEsMTguMiAxMy41OTk5OTk3LDMyLjggMzIuNTk5OTk5NywzMi44IDQ5LjksMC4xIDk5LjY5OTk5NywwIDE0OS41OTk5OTcsMCBoIDM0NC41IGMgMTAuNCwwIDE5LjUsLTMuMSAyNi42LC0xMS4yIDExLjMsLTEyLjUgMTAuMSwtMzIgLTIuNSwtNDAgeiIKICAgICBjbGFzcz0ic3Q1NyIKICAgICBpZD0icGF0aDM5ODUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWNlY2VjIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuNTg3NjYsNDQwLjQ3IGMgMCwtMC4zIC0wLjEsLTAuNyAtMC4xLC0xIC0xLjEsLTQuMyAtMi43LC04LjMgLTYuMiwtMTEuMyAxLjYsMy42IDMuMSw3LjMgNC43LDEwLjkgMC43LDAuNCAxLjIsMC45IDEuNiwxLjQgeiBtIC01NTMuMTk5OTk3LDUuNSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS4zIDEuMSwtMiAtMC40LC02LjUgMS43LC0xMi40IDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IgogICAgIGNsYXNzPSJzdDU3IgogICAgIGlkPSJwYXRoMzk4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlY2VjZWMiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQ0LjE4NzY2MywzMTUuMTcgSCA0MzguMzg3NjYgYyAzMi4yLDAgNjQuNCwwLjIgOTYuNiwtMC4xIDE0LjUsLTAuMSAyNiwtNS41IDMxLjksLTE5LjkgNSwtMTIuMiAyLC0yNS4yIC03LjcsLTMxLjMgMy44LDMuMyA1LjUsNy43IDYuMywxMi41IDAuMSwwLjkgMC4xLDEuOCAwLjEsMi43IDIuOSw3IDAuNSwxNi44IC02LDIyLjIgLTIuOCwyLjMgLTUuNSw0LjYgLTguMyw3IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjI4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtNi44LC01LjEgLTEyLjEsLTExLjEgLTEzLjQsLTE5LjkgLTAuMiwtMS41IC0wLjYsLTMuMSAtMC4zLC00LjUgLTAuMiwtMC43IC0wLjMsLTEuMyAtMC40LC0yIC0wLjQsLTYuMyAwLjYsLTEyLjIgNS42LC0xNi44IC02LjcsMy42IC0xMC44OTk5OTk3LDE0LjEgLTkuMDk5OTk5NywyMi43IDMuNzk5OTk5NywxOCAxNS42OTk5OTk3LDI3LjQgMzUuMjk5OTk5NywyNy40IHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTg5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTIuMzg3NjYzLDI4MS43NyBjIDAuMSwwLjcgMC4zLDEuMyAwLjQsMiAwLjIsLTAuNyAwLjUsLTEuNCAxLjEsLTIgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LDQuNSAtNi4xLDEwLjQgLTUuNiwxNi43IHogbSA1NTMuMzk5OTk3LC0yLjggYyAwLC0wLjkgMCwtMS44IC0wLjEsLTIuNyAtMC44LC00LjggLTIuNSwtOS4yIC02LjMsLTEyLjUgbCA0LjgsMTIuMyBjIDAuNiwxIDEuMSwxLjkgMS42LDIuOSB6IE0gMzIuNTg3NjYzLDY2LjA3IGMgOC41LDEuNyAxNywxLjMgMjUuNiwxLjMgSCA1MzMuMDg3NjYgYyAxMSwwIDIxLC0yLjUgMjguOCwtMTEuMSAxMS4yLC0xMi40IDkuMiwtMzQuOCAtMi41LC00MC4yIDMuNSwzIDUuMSw3IDYuMiwxMS4zIDAuMSwxLjEgMC4yLDIuMiAwLjIsMy4zIDMuMiw5LjMgLTAuNiwyMS40IC04LjgsMjUuNiAtMS44LDEuNCAtMy43LDIuOCAtNS41LDQuMiAtMy43LDMuMyAtOC4xLDQuMiAtMTIuOCw0LjIgSCAzOS40ODc2NjMgYyAtNC43LDAgLTkuMiwtMC45IC0xMi44LC00LjIgLTYuOCwtNS4xIC0xMi4xLC0xMS4xIC0xMy40LC0xOS45IC0wLjIsLTEuNSAtMC42LC0zLjEgLTAuMywtNC41IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjIsLTEzIDYuNCwtMTcuOCAtMi43LDAuNiAtNC4zLDIuNyAtNS43LDQuOCAtMTEuMDk5OTk5NywxNi41IC0wLjIsNDEuMiAxOS40LDQ1LjEgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsMjYuOTcgYyAwLjcsMS4xIDEuMywyLjQgMS43LDMuNiAwLC0xLjEgLTAuMSwtMi4yIC0wLjIsLTMuMyAtMSwtNC4zIC0yLjcsLTguMyAtNi4yLC0xMS4zIDEuNiwzLjcgMy4yLDcuNCA0LjcsMTEgeiBtIC01NTEuNTk5OTk3LDYuOSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS40IDEuMSwtMiAtMC40LC02LjUgMS44LC0xMi4zIDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IG0gMzEuMywxMTUuNiBIIDQwOS43ODc2NiBjIDQxLjgsMCA4My41LDAuMSAxMjUuMywtMC4xIDE0LjUsLTAuMSAyNi4xLC01LjUgMzIsLTE5LjkgNSwtMTIuMiAyLC0yNS4zIC03LjcsLTMxLjQgNS4xLDQuNyA2LjksMTAuNyA2LjQsMTcuNCAtMC4yLDEuNCAtMC41LDIuOCAtMC45LDQuMiAwLjUsNi43IC0yLjUsMTIuMyAtNy4yLDE3LjMgLTEuOSwyIC00LjEsMy43IC02LjEsNS41IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjU4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtMiwtMS4yIC00LjUsLTEuNyAtNS42LC00LjIgLTguMSwtNC4yIC0xMS44OTk5OTk3LC0xNi4yIC04LjgsLTI1LjQgMCwtMS4xIDAsLTIuMyAwLjEsLTMuNCAwLjUsLTQuNyAyLjksLTguMyA2LjQsLTExLjMgLTcuNSw0LjcgLTExLjY5OTk5OTcsMTUuMiAtOS43OTk5OTk3LDI0LjEgMy42OTk5OTk3LDE3LjkgMTUuNDk5OTk5NywyNy4yIDM0LjU5OTk5OTcsMjcuMiB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC4xODc2NiwxMTYuMDcgYyAwLjMsMS4zIDAuNSwyLjUgMC42LDMuNyAwLjQsLTEuNCAwLjcsLTIuNyAwLjksLTQuMiAwLjUsLTYuOCAtMS4zLC0xMi43IC02LjQsLTE3LjQgMy4xLDUuNiA1LjMsMTEuNCA0LjksMTcuOSB6IG0gLTU1MS44OTk5OTcsLTYuNiBjIDAsMS4xIC0wLjEsMi4zIC0wLjEsMy40IDAuNCwtMS4zIDEsLTIuNiAxLjgsLTMuOCAtMC4yLC00LjQgMy4zLC03LjIgNC43LC0xMSAtMy41LDMuMSAtNS45LDYuNyAtNi40LDExLjQgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOS44ODc2NjMsMjI1Ljk3IGMgMS41LDAuNCAzLjIsMC4xIDQuOSwwLjEgSCA1MzMuMzg3NjYgYyA3LjEsMCAxMy44LC0xLjEgMTkuNiwtNS42IDEuMSwtMC44IDEuOSwtMS42IDIuMywtMi43IC0wLjMsMC4yIC0wLjUsMC40IC0wLjgsMC42IC01LjQsNC4xIC0xMS41LDUuNiAtMTguMiw1LjYgSCA0MS45ODc2NjMgYyAtNi43LDAgLTEyLjgsLTEuNSAtMTguMSwtNS41IDMuMyw1LjkgMTAsNi4xIDE2LDcuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQxLjg4NzY2MywyMjMuOTcgSCA1MzYuMTg3NjYgYyA2LjcsMCAxMi44LC0xLjUgMTguMiwtNS42IDAuMywtMC4yIDAuNiwtMC40IDAuOCwtMC42IDAuMiwtMC41IDAuMywtMS4xIDAuMiwtMS44IC03LjIsNC45IC0xNS4xLDYuMSAtMjMuNyw2LjEgLTE2MS44LC0wLjIgLTMyMy42LC0wLjIgLTQ4NS4zOTk5OTcsMCAtOC42LDAgLTE2LjUsLTEuMiAtMjMuNywtNi4xIDAuMywxIDAuNywxLjggMS4yLDIuNiA1LjQsNCAxMS40LDUuNCAxOC4xLDUuNCB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1NS45ODc2NiwyMTcuMTcgYyAwLjIsMC43IDAuMiwxLjMgMCwxLjkgMi43LC0yLjYgNC42LC01LjYgNiwtOS4xIC0xLjUsMi43IC0zLjQsNS4xIC02LDcuMiB6IG0gLTUzMy45OTk5OTcsMCBjIC0yLjQsLTEuOSAtNC4yLC00LjIgLTUuNywtNi43IDEuNCwzLjIgMy4zLDYgNS42LDguNCAtMC4xLC0wLjQgLTAuMSwtMSAwLjEsLTEuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDIxNy4xNyBjIDAuMSwtMC40IDAuMywtMC44IDAuNiwtMS4yIC00LC00LjMgLTYuNywtOS40IC04LjYsLTE1IDAuMywzLjQgMS4xLDYuNiAyLjMsOS41IDEuNSwyLjYgMy40LDQuOCA1LjcsNi43IHogbSA1MzkuOTk5OTk3LC03LjMgYyAxLC0yLjcgMS43LC01LjcgMiwtOC45IC0xLjksNS41IC00LjUsMTAuNiAtOC42LDE1IDAuMywwLjQgMC41LDAuOSAwLjYsMS4yIDIuNiwtMi4xIDQuNSwtNC41IDYsLTcuMyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDIxOS4wNyBjIC0wLjQsMS4yIC0xLjcsMi4xIC0zLDMgLTUuMSwzLjYgLTEwLjcsNS4zIC0xNi45LDUuNCBIIDQ0LjU4NzY2MyBjIC03LjEsMCAtMTMuOCwtMS4yIC0xOS43LC01LjQgLTEuMywtMC45IC0yLjYsLTEuOSAtMywtMy4xIC0yLjQsLTIuNCAtNC4yLC01LjIgLTUuNiwtOC40IC0xLjUsLTIuNSAtMi41LC01LjIgLTMuNCwtOC4xIC0wLjQsMS4xIC0wLjEsMi40IDAuMiwzLjcgMy4xLDE0LjUgMTMuNywyMi44IDI5LjYsMjIuOCAxNjQuMTk5OTk3LDAgMzI4LjI5OTk5NywwIDQ5Mi40OTk5OTcsMC4xIDUuMywwIDEwLjEsLTEuMyAxNC44LC0zLjEgNy4xLC0yLjggMTUuNiwtMTMuMSAxNC41LC0yMiAtMC43LDIuMiAtMS42LDQuMiAtMi42LDYuMSAtMS4yLDMuNCAtMy4yLDYuNCAtNS44LDkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAxOSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAtMC41LDAuNCAtMC45LDAuOSAtMS4xLDEuNCAwLjgsMi45IDEuOSw1LjYgMy40LDguMSAtMS4zLC0yLjggLTIuMSwtNiAtMi4zLC05LjUgeiBtIDU0Ny44OTk5OTcsOC45IGMgMS4xLC0xLjkgMS45LC00IDIuNiwtNi4xIC0wLjEsLTAuOSAtMC4zLC0xLjkgLTAuNiwtMi44IC0wLjMsMy4zIC0xLDYuMiAtMiw4LjkgeiBtIC02LDcuMyBjIC0wLjIsMC4yIC0wLjUsMC40IC0wLjgsMC42IC0wLjQsMS4xIC0xLjIsMS45IC0yLjMsMi43IC01LjgsNC41IC0xMi41LDUuNiAtMTkuNiw1LjYgSCA0NC42ODc2NjMgYyAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjksLTEuNCAtMTIuNywtMS42IC0xNi4xLC03LjQgMCwwIC0wLjEsMCAtMC4xLC0wLjEgLTAuNiwtMC40IC0xLjEsLTAuOCAtMS43LC0xLjMgLTAuMiwwLjcgLTAuMiwxLjIgLTAuMSwxLjcgNC42LDQuNiAxMC44LDcuNSAxOCw3LjkgMi4zLDAuMSA0LjYsMC4xIDcsMC4xIEggNTMwLjk4NzY2IGMgNS4xLDAgMTAuMSwwIDE1LjEsLTEuOCA0LC0xLjUgNy4zLC0zLjUgOS45LC02IDAuMiwtMC42IDAuMywtMS4yIDAsLTEuOSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDIxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNjg3NjYzLDIxOC40NyBjIC0wLjMsLTAuNyAtMC43LC0xLjUgLTEuMSwtMi41IC0wLjMsMC40IC0wLjUsMC45IC0wLjYsMS4yIDAuNiwwLjUgMS4xLDAuOSAxLjcsMS4zIHogbSA1MzEuNTk5OTk3LC0wLjcgYyAwLjMsLTAuMiAwLjUsLTAuNCAwLjgsLTAuNiAtMC4xLC0wLjQgLTAuMywtMC44IC0wLjYsLTEuMiAwLDAuNyAtMC4xLDEuMyAtMC4yLDEuOCB6IG0gLTI0LjIsOS4xIEggNDYuODg3NjYzIGMgLTIuMywwIC00LjYsMC4xIC03LC0wLjEgLTcuMiwtMC40IC0xMy41LC0zLjMgLTE4LC03LjkgMC40LDEuMyAxLjcsMi4yIDMsMy4xIDUuOSw0LjIgMTIuNSw1LjQgMTkuNyw1LjQgMTU0LjU5OTk5NywtMC4xIDMwOS4xOTk5OTcsMCA0NjMuNzk5OTk3LDAgaCAyNy44IGMgNi4yLDAgMTEuOCwtMS44IDE2LjksLTUuNCAxLjMsLTAuOSAyLjYsLTEuOCAzLC0zIC0yLjYsMi41IC01LjksNC41IC05LjksNiAtNSwxLjkgLTEwLDEuOSAtMTUuMSwxLjkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDM4LjQ4NzY2MywxNDIuMzcgYyAyLjQsMC42IDUuMSwwLjEgNy42LDAuMSBIIDUzNC41ODc2NiBjIDUuMywwIDEwLjYsMCAxNS4zLC0yLjkgMC43LC0xIDEuNCwtMi4xIDIuMSwtMy4xIC01LjUsMyAtMTEuNCwzLjkgLTE3LjYsMy45IC0xNjMuOCwtMC4xIC0zMjcuNSwtMC4xIC00OTEuMjk5OTk3LDAgLTcuMSwwIC0xMy41LC0xLjUgLTE5LjYsLTUuMSAzLjMsNS41IDkuNiw1LjggMTUsNy4xIHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDI1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuMjg3NjYzLDE0MC40NyBjIDE2My43OTk5OTcsLTAuMSAzMjcuNDk5OTk3LC0wLjEgNDkxLjI5OTk5NywwIDYuMiwwIDEyLjEsLTAuOCAxNy42LC0zLjkgMC43LC0wLjkgMS4zLC0xLjkgMiwtMi44IC02LjYsMy44IC0xMy44LDQuNyAtMjEuNCw0LjcgLTE2Mi42LC0wLjEgLTMyNS4yLC0wLjEgLTQ4Ny43OTk5OTcsMCAtOC4yLDAgLTE1LjYsLTEuMyAtMjIuNCwtNS44IDAuMywxLjEgMC43LDIgMS4yLDIuOCA1LjksMy42IDEyLjQsNSAxOS41LDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwMjciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NDguOTg3NjYsMTQxLjc3IGMgLTAuNCwwLjMgLTAuOCwwLjUgLTEuMiwwLjggMC4xLC0wLjEgMC4yLC0wLjEgMC40LC0wLjIgMi45LC0xLjggNS41LC0zLjggNy43LC02LjEgLTAuOCwwLjYgLTEuNiwxLjIgLTIuNSwxLjcgLTEuMiwxLjUgLTMuMSwyLjUgLTQuNCwzLjggeiBtIDExLjcsLTEyLjkgYyAtMC4zLDEuMSAtMC43LDIuMiAtMS4yLDMuMSAxLjUsLTIuMiAyLjcsLTQuNiAzLjUsLTcuMiAtMC4yLDAuNSAtMC40LDEgLTAuNiwxLjQgLTAuNiwxIC0xLjIsMS44IC0xLjcsMi43IHogbSAtMTU1LjksMTUuNiBIIDQ1Ljc4NzY2MyBjIC02LjgsMCAtMTMuNSwtMC41IC0xOS40LC00LjMgLTIuNCwtMS41IC01LC0zIC00LjQsLTYuMSAtNCwtMy40IC02LjUsLTcuOCAtOC4yLC0xMi42IC0wLjIsMy45IDEuMSw3LjMgMywxMC41IDEuMywxLjkgMi45LDMuNyA0LjksNS40IDIuNSwxLjggNSwzLjUgNy43LDQuOCA0LjEsMiA4LjQsMi41IDEyLjgsMi41IEggNTM1Ljg4NzY2IGMgMi4xLDAgNC4xLC0wLjEgNi4xLC0wLjUgLTEuOSwwLjIgLTMuOSwwLjIgLTUuOCwwLjIgLTQzLjcsMC4xIC04Ny42LDAuMSAtMTMxLjQsMC4xIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsMTM0LjE3IGMgMC4xLC0wLjUgMC4yLC0xIDAuNSwtMS41IC0zLjksLTQgLTYuMywtOC45IC04LjMsLTEzLjkgLTAuMiwxIC0wLjMsMS45IC0wLjQsMi44IDEuNyw0LjggNC4yLDkuMSA4LjIsMTIuNiB6IG0gNTQwLjI5OTk5NywtNy45IGMgMC4yLC0wLjUgMC40LC0xIDAuNiwtMS40IDAuOCwtMi43IDEuMywtNS41IDEuMiwtOC43IC0xLDMuMiAtMiw2LjQgLTMsOS43IC0wLjEsMS4xIC0wLjMsMi4xIC0wLjUsMy4xIDAuNiwtMSAxLjIsLTEuOCAxLjcsLTIuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU5LjQ4NzY2LDEzMS45NyBjIC0wLjksMS43IC0yLjEsMy4xIC0zLjYsNC40IC0yLjIsMi4yIC00LjgsNC4yIC03LjcsNi4xIC0wLjEsMC4xIC0wLjIsMC4xIC0wLjQsMC4yIC0xLjgsMS4xIC0zLjcsMS41IC01LjcsMS44IC0yLDAuMyAtNCwwLjUgLTYuMSwwLjUgSCA0Mi4yODc2NjMgYyAtNC41LDAgLTguOCwtMC41IC0xMi44LC0yLjUgLTIuNywtMS40IC01LjMsLTMgLTcuNywtNC44IC0yLC0xLjcgLTMuNiwtMy41IC00LjksLTUuNCAxLjMsMi4yIDIuOCw0LjIgNC4zLDYuMyAxLDIuNSAzLjYsMyA1LjYsNC4yIDEyLjQsMy43IDI1LjIsMi44IDM3LjksMi44IEggNTE0LjQ4NzY2IGMgMTIuNCwwIDI1LDAuOSAzNy4yLC0yLjggMi4xLC0xLjggNC4zLC0zLjUgNi4xLC01LjUgNC43LC01IDcuNywtMTAuNiA3LjIsLTE3LjMgLTAuNSwxLjcgLTEuMSwzLjQgLTEuOCw1IC0xLjEsMi40IC0yLjMsNC44IC0zLjcsNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTYyLjg4NzY2LDEyNC43NyBjIDAuNywtMS42IDEuMywtMy4zIDEuOCwtNSAtMC4xLC0xLjIgLTAuMywtMi40IC0wLjYsLTMuNyAwLjEsMy4yIC0wLjQsNi4xIC0xLjIsOC43IHogbSAtOS41LDEzLjMgYyAtMSwwLjYgLTIuMiwxLjIgLTMuNCwxLjcgLTQuOCwyLjggLTEwLDIuOSAtMTUuMywyLjkgLTE2Mi44LC0wLjEgLTMyNS43LDAgLTQ4OC40OTk5OTcsMCAtMi42LDAgLTUuMiwwLjUgLTcuNiwtMC4xIC01LjUsLTEuMyAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4yLC0wLjEgLTAuMywtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjYsMy4xIDIuMSw0LjYgNC40LDYuMSA1LjksMy44IDEyLjUsNC4zIDE5LjQsNC4zIDExOS42OTk5OTcsLTAuMSAyMzkuMjk5OTk3LDAgMzU4Ljk5OTk5NywwIGggMTMxLjUgYyAxLjksMCAzLjksMCA1LjgsLTAuMiAxLjksLTAuMyAzLjgsLTAuOSA1LjcsLTEuOCAwLjQsLTAuMiAwLjgsLTAuNSAxLjIsLTAuOCAxLjIsLTEuMyAzLjEsLTIuMyA0LjMsLTMuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMzg3NjYzLDEzNS4yNyBjIDAuMSwwLjEgMC4yLDAuMSAwLjMsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjIsMC41IC0wLjQsMSAtMC41LDEuNSAwLjUsMC4zIDAuOSwwLjcgMS40LDEuMSB6IG0gNTI0LjM5OTk5Nyw3LjMgYyAtMS44LDAuOSAtMy43LDEuNCAtNS43LDEuOCAyLC0wLjMgMy45LC0wLjggNS43LC0xLjggeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjc4NzY2MywxMTguNTcgYyAwLC0wLjIgLTAuMSwtMC40IC0wLjEsLTAuNSAwLDEuNiAwLjEsMy4xIDAuMyw0LjcgMC4xLC0wLjcgMC4yLC0xLjQgMC41LC0yLjEgLTAuMywtMC43IC0wLjUsLTEuNCAtMC43LC0yLjEgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwMzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi43ODc2NjMsMTE4LjU3IGMgMC4yLDAuNyAwLjQsMS40IDAuNiwyIDAuMiwtMC42IDAuNCwtMS4yIDAuNywtMS45IDAsLTMuMiAtMC4xLC02LjQgLTAuMSwtOS42IC0wLjgsMy4xIC0xLjMsNiAtMS4zLDguOSAwLDAuMiAwLjEsMC40IDAuMSwwLjYgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwNDEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi45ODc2NjMsMTIyLjY3IGMgLTAuMiwtMS41IC0wLjMsLTMuMSAtMC4zLC00LjcgLTAuNCwtMS43IC0wLjUsLTMuNCAtMC41LC01LjEgLTMuMDk5OTk5Nyw5LjIgMC43LDIxLjIgOC44LDI1LjQgLTQuNCwtNC41IC04LjksLTkuMSAtOCwtMTUuNiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA0MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjk4NzY2MywxMDkuMTcgYyAtMC43LDEuMiAtMS4zLDIuNSAtMS44LDMuOCAwLDEuNyAwLjEsMy40IDAuNSw1LjEgMC4xLC0yLjkgMC41LC01LjkgMS4zLC04LjkgeiBtIC0wLjIsMTIuMyAtMC4zLC0wLjkgYyAtMC4yLDAuNyAtMC40LDEuNCAtMC41LDIuMSAwLjUsMy4zIDEuNyw2LjQgMy44LDkuMyAtMS45LC0zLjEgLTMuMiwtNi41IC0zLC0xMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTMuNzg3NjYzLDEyMS40NyBjIDAsLTAuOSAwLjIsLTEuOCAwLjQsLTIuOCAtMC4zLDAuNiAtMC41LDEuMyAtMC43LDEuOSB6IG0gMywxMC42IGMgLTIsLTIuOSAtMy4yLC02IC0zLjgsLTkuMyAtMC45LDYuNSAzLjYsMTEuMSA4LDE1LjcgLTEuNSwtMi4yIC0zLC00LjMgLTQuMiwtNi40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIC0wLjgsMC43IC0xLjYsMS4zIC0yLjQsMS45IDAsMC4zIDAsMC42IC0wLjEsMC44IDAuOCwtMC44IDEuNywtMS43IDIuNSwtMi43IHoiCiAgICAgY2xhc3M9InN0NjMiCiAgICAgaWQ9InBhdGg0MDQ5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NkY2RjZSIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIDEuOCwtMi4zIDMuMywtNC44IDQuNCwtNy42IC0yLjMsMi43IC00LjcsNS40IC03LDguMSAwLjEsMC42IDAuMiwxIDAuMiwxLjUgMC44LC0wLjcgMS42LC0xLjMgMi40LC0yIHogbSAtMi42LDIuOCBjIDAsLTAuMyAwLjEsLTAuNSAwLjEsLTAuOCAtMC42LDAuNCAtMS4xLDAuNyAtMS43LDEuMSAtMC4xLDAuMSAtMC4zLDAuMSAtMC40LDAuMiAtMC43LDEgLTEuNCwyLjEgLTIuMSwzLjEgMS40LC0xLjEgMi44LC0yLjMgNC4xLC0zLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTIuMTg3NjYsMTM2LjY3IGMgMC4xLC0wLjEgMC4zLC0wLjEgMC40LC0wLjIgMC42LC0wLjMgMS4yLC0wLjcgMS43LC0xLjEgMCwtMC41IC0wLjEsLTEgLTAuMiwtMS41IC0wLjYsMC45IC0xLjMsMS44IC0xLjksMi44IHogbSA0LjYsLTMuMyBjIC0wLjgsMSAtMS42LDEuOSAtMi41LDIuOCAtMC4xLDAuNyAtMC40LDEuMyAtMC45LDEuOSAwLjksLTAuNSAxLjcsLTEuMSAyLjUsLTEuNyAxLjQsLTEuNCAyLjYsLTIuOCAzLjYsLTQuNCAwLjUsLTAuOSAwLjksLTIgMS4yLC0zLjEgLTEuMiwxLjYgLTIuNSwzLjIgLTMuOSw0LjUgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjAuNjg3NjYsMTI4Ljg3IGMgMC4zLC0xIDAuNCwtMiAwLjUsLTMuMSAtMS4xLDIuOCAtMi42LDUuNCAtNC40LDcuNiAxLjQsLTEuMyAyLjcsLTIuOSAzLjksLTQuNSB6IG0gLTEuMiwzLjEgYyAtMS4xLDEuNSAtMi4zLDMgLTMuNiw0LjQgMS40LC0xLjMgMi42LC0yLjcgMy42LC00LjQgeiBtIC05LjUsNy43IGMgMS4yLC0wLjUgMi4zLC0xLjEgMy40LC0xLjcgMC40LC0wLjUgMC43LC0xLjIgMC45LC0xLjkgLTEuNCwxLjQgLTIuOCwyLjYgLTQuMywzLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyOC4yODc2NjMsMzg3Ljg3IGMgMiwxLjEgNC4yLDEuOSA2LjUsMi41IEggNTQwLjI4NzY2IGMgNSwtMS45IDExLjIsLTIgMTQuMSwtNy4yIC02LjIsMy44IC0xMi45LDUuMSAtMjAuMiw1LjEgLTE2My41LC0wLjEgLTMyNy4xLC0wLjEgLTQ5MC41OTk5OTcsMCAtNi40LDAgLTEyLjUsLTAuNiAtMTguMSwtNCAtMC4xLC0wLjEgLTAuMiwtMC4xIC0wLjMsLTAuMiAxLDEuMSAyLjIsMiAyLjcsMy40IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjUuNTg3NjYzLDM4NC4yNyBjIDUuNiwzLjQgMTEuNyw0IDE4LjEsNCAxNjMuNDk5OTk3LC0wLjEgMzI3LjA5OTk5NywtMC4xIDQ5MC41OTk5OTcsMCA3LjMsMCAxNCwtMS40IDIwLjIsLTUuMSAwLjUsLTAuOCAwLjgsLTEuNyAxLjEsLTIuOCAtNi41LDQuNiAtMTMuNyw1LjkgLTIxLjYsNS45IC0xNjMuMSwtMC4xIC0zMjYuMiwtMC4xIC00ODkuMTk5OTk3LDAgLTcuNCwwIC0xNC4zLC0wLjkgLTIwLjYsLTQuNyAwLjEsMS4xIDAuNywxLjggMS4zLDIuNiAtMC4xLDAgMCwwLjEgMC4xLDAuMSB6IG0gOS4yLDYuMSBjIC0yLjMsLTAuNiAtNC41LC0xLjQgLTYuNSwtMi41IDEuOCwyIDQuMSwyLjQgNi41LDIuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgYyAwLjcsMi4xIDEuNyw0LjEgMi45LDUuOSAtMC42LC0xLjEgLTEuMSwtMi4zIC0xLjUsLTMuNSAtMC41LC0wLjggLTAuOSwtMS42IC0xLjQsLTIuNCB6IG0gNTQxLjA5OTk5Nyw5LjEgYyAwLjEsMC41IDAuMiwxIDAuMSwxLjQgMi41LC0yLjUgNC41LC01LjQgNS44LC04LjcgLTEuNSwyLjYgLTMuNCw1LjEgLTUuOSw3LjMgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgMS41LDIuNCBjIC0wLjQsLTEuNCAtMC43LC0yLjkgLTAuOSwtNC41IC0xLjksLTEuOSAtMC41LC00LjcgLTEuNiwtNi44IC0wLjQsMy4xIDAsNiAxLDguOSB6IG0gNTQ2Ljk5OTk5NywxLjcgYyAxLjMsLTMuMiAyLjEsLTYuOCAyLjEsLTEwLjYgLTEuOCw2IC00LjEsMTEuOCAtOC42LDE2LjUgMC4zLDAuNSAwLjUsMSAwLjYsMS41IDIuNSwtMi4yIDQuNCwtNC43IDUuOSwtNy40IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTYuMTg3NjYsMzgzLjI3IGMgLTAuMywxLjkgLTIuMywzLjEgLTQsNC4xIC00LjIsMi41IC04LjcsNCAtMTMuNyw0LjMgaCAtMC42IGMgLTEuNCwwLjMgLTIuOCwwLjEgLTQuMiwwIEggNDQuMDg3NjYzIGMgLTEuMywwLjEgLTIuNywwLjMgLTQsMCBoIC0wLjYgYyAtNC4xLC0wLjMgLTguMiwtMC4zIC0xMS44LC0yLjcgLTEsLTEuMiAtMi41LC0yLjIgLTMuNCwtMy40IC0yLjgsLTEuOCAtNSwtNC4xIC02LjUsLTYuOSAtMS4zLC0xLjkgLTIuMiwtMy45IC0yLjksLTUuOSAtMC4zLC0wLjUgLTAuNiwtMC45IC0wLjgsLTEuNCAtMC43LC0xLjEgLTEuMiwtMi4zIC0xLjUsLTMuNSAwLjEsMC45IDAuMywxLjcgMC41LDIuNiAzLjUsMTQuOSAxMy4yLDIyLjYgMjguOSwyMi42IDE2NC42OTk5OTcsMCAzMjkuMzk5OTk3LDAgNDk0LjA5OTk5NywwLjEgNCwwIDcuOSwtMC44IDExLjYsLTEuOSAxMC4yLC0zLjEgMTcuNiwtMTQuMSAxNy4xLC0yMy43IC0wLjcsMi40IC0xLjYsNC43IC0yLjcsNi45IC0xLjQsMy4zIC0zLjQsNi4zIC01LjksOC44IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjEuOTg3NjYsMzc0LjQ3IGMgMS4yLC0yLjEgMiwtNC41IDIuNywtNi45IC0wLjEsLTEuMyAtMC4zLC0yLjUgLTAuNiwtMy43IDAsMy44IC0wLjgsNy40IC0yLjEsMTAuNiB6IG0gLTU0Ni45OTk5OTcsLTEuNyBjIC0wLjksLTIuOCAtMS40LC01LjggLTEuMSwtOC45IC0xLjEsMS4yIC0xLjMsMi42IC0xLjIsMy45IDAuMywxLjIgMC43LDIuNCAxLjUsMy41IDAuMiwwLjUgMC41LDEgMC44LDEuNSB6IG0gMTEsMTMuOCBjIDAuOCwwLjUgMS41LDAuOSAyLjMsMS40IGwgLTAuMywtMC4zIGMgLTAuNywtMC40IC0xLjQsLTAuOCAtMiwtMS4xIHogbSA1MzAuMDk5OTk3LC00LjcgYyAtMC40LDAuNCAtMC45LDAuOCAtMS40LDEuMiAtMC4xLDAuMSAtMC4yLDAuMSAtMC4zLDAuMiAtMi45LDUuMiAtOS4xLDUuMyAtMTQuMSw3LjIgbCAtMC42LDAuNiBjIDEuNCwtMC4xIDIuOCwtMC40IDQuMiwtMC43IDQuOSwtMS4zIDkuMSwtMy43IDEyLjQsLTcgMCwtMC42IC0wLjEsLTEgLTAuMiwtMS41IHogbSAtNTIxLjI5OTk5Nyw4LjUgYyAxLjIsMC4zIDIuNCwwLjUgMy42LDAuNiAtMC4yLC0wLjIgLTAuNSwtMC40IC0wLjcsLTAuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0Ljc4NzY2LDM4Mi45NyBjIDAuNSwtMC40IDAuOSwtMC44IDEuNCwtMS4yIC0wLjEsLTAuNSAtMC4zLC0wLjkgLTAuNiwtMS41IC0wLjMsMS4xIC0wLjYsMiAtMS4xLDIuOCAwLDAgMC4xLDAgMC4zLC0wLjEgeiBtIC01MDkuNzk5OTk3LDguNyBoIC0wLjggNDg5LjU5OTk5NyAtMC42IGMgLTE2Mi44LDAuMSAtMzI1LjUsMC4xIC00ODguMTk5OTk3LDAgeiBtIDQ5NC42OTk5OTcsLTAuOCBjIC0wLjUsMC40IC0xLjEsMC43IC0xLjcsMC44IGggMC42IGMgNC45LC0wLjMgOS41LC0xLjggMTMuNywtNC4zIDEuOCwtMS4xIDMuOCwtMi4yIDQsLTQuMSAtMy4zLDMuMyAtNy41LDUuNyAtMTIuNCw3IC0xLjUsMC4zIC0yLjksMC41IC00LjIsMC42IHogbSAtNTA0Ljg5OTk5NywtMC41IGMgLTIuNCwtMC4xIC00LjcsLTAuNSAtNi41LC0yLjUgLTAuOCwtMC40IC0xLjYsLTAuOSAtMi4zLC0xLjQgbCAtMS41LC0wLjkgYyAwLjksMS4yIDIuNCwyLjIgMy40LDMuNCAzLjYsMi40IDcuNywyLjQgMTEuOCwyLjcgaCAwLjYgYyAtMC42LC0wLjEgLTEuMiwtMC40IC0xLjcsLTAuOCAtMS40LDAgLTIuNiwtMC4zIC0zLjgsLTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIC0wLjgsLTAuNSAtMS41LC0xLjEgLTIuMSwtMS43IDAuNywwLjggMS40LDEuNiAyLjIsMi4zIC0wLjEsLTAuMSAtMC4xLC0wLjMgLTAuMSwtMC42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIDAsLTAuNSAwLjEsLTEgMC40LC0xLjYgLTMuNCwtMy4xIC02LC02LjkgLTguNSwtMTAuOSAxLjMsNC4xIDMuMyw3LjYgNiwxMC43IDAuNywwLjcgMS40LDEuMyAyLjEsMS44IHogbSA0LjQsNC41IGMgLTAuNSwtMS40IC0xLjcsLTIuMyAtMi43LC0zLjQgLTAuNiwtMC4zIC0xLjEsLTAuNiAtMS42LC0xIHYgMC42IGMgMS4zLDEuMyAyLjgsMi42IDQuMywzLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNS4yODc2NjMsMzg0LjA3IGMgLTAuNiwtMC43IC0xLjIsLTEuNSAtMS4zLC0yLjYgLTAuMiwwLjYgLTAuMywxLjEgLTAuNCwxLjYgMC42LDAuNCAxLjEsMC43IDEuNywxIHogbSAtMSwxLjMgYyAtMC4zLC0wLjUgLTAuNSwtMSAtMC42LC0xLjYgLTAuOCwtMC44IC0xLjUsLTEuNSAtMi4yLC0yLjMgLTIsLTEuOCAtMy42LC0zLjkgLTUuMSwtNi4yIDAuNCwxLjMgMC45LDIuNCAxLjUsMy41IDEuNywyLjQgMy45LDQuNyA2LjQsNi42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDc1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuNDg3NjYzLDM4MS4zNyBjIC0yLjYsLTMuMSAtNC43LC02LjYgLTYsLTEwLjcgMC4yLDEuNiAwLjUsMy4xIDAuOSw0LjUgMS41LDIuMyAzLjEsNC40IDUuMSw2LjIgeiBtIC0zLjYsLTIuNyBjIDEuNSwyLjggMy43LDUuMSA2LjUsNi45IC0wLjEsLTAuMSAtMC4xLC0wLjIgLTAuMiwtMC4zIC0yLjQsLTEuOCAtNC42LC00LjEgLTYuMywtNi42IHogbSA1LjgsNS4xIGMgMC4xLDAuNiAwLjMsMS4xIDAuNiwxLjYgMC42LDAuNCAxLjEsMC44IDEuNywxLjIgMC43LDAuNCAxLjMsMC43IDIsMSAtMS41LC0xLjIgLTMsLTIuNSAtNC4zLC0zLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNC4yODc2NjMsMzg1LjM3IGMgMC4xLDAuMSAwLjEsMC4yIDAuMiwwLjMgbCAxLjUsMC45IGMgLTAuNiwtMC40IC0xLjIsLTAuOCAtMS43LC0xLjIgeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOC40ODc2NjMsNjAuMjcgYyAxLjUsMC40IDMuMiwwLjEgNC45LDAuMSAxNjMuNzk5OTk3LDAgMzI3LjQ5OTk5NywwIDQ5MS4yOTk5OTcsMC4xIDYsMCAxMS40LC0xLjMgMTYuNiwtNC4yIDEuNiwtMC45IDMuMSwtMS45IDMuOCwtMy41IC0wLjEsMC4xIC0wLjMsMC4yIC0wLjQsMC4zIC02LjMsMy45IC0xMy4xLDUuMyAtMjAuNSw1LjMgLTE2My40LC0wLjEgLTMyNi45LC0wLjEgLTQ5MC4yOTk5OTcsMCAtNy4zLDAgLTE0LC0xLjMgLTIwLjEsLTUuMSAzLDUuMyA5LjMsNS42IDE0LjcsNyB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA4MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQzLjc4NzY2Myw1OC4zNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjYgMC41LC0xLjQgMC41LC0yLjIgLTYuOCw0LjYgLTE0LjIsNS44IC0yMi40LDUuOCAtMTYyLjgsLTAuMSAtMzI1LjUsLTAuMSAtNDg4LjI5OTk5NywwIC04LjIsMCAtMTUuNiwtMS4zIC0yMi40LC01LjggMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuMywzLjcgMTMsNSAyMC4yLDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwODMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsNTEuODcgYyAtMi45LC0yLjUgLTUuMSwtNS41IC02LjYsLTguOCAxLjQsNC4yIDMuNyw3LjggNi45LDExIC0wLjQsLTAuNiAtMC41LC0xLjMgLTAuMywtMi4yIHogbSA1MTAuMTk5OTk3LDEwLjUgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjI5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzUuNzg3NjYgYyA0LjUsMCA4LjgsLTAuNSAxMi44LC0yLjUgMS40LC0wLjcgMi43LC0xLjcgNCwtMi43IC0zLjksMi45IC04LjUsNC40IC0xMy40LDQuOCAtMi40LDAuMiAtNC43LDAuMSAtNywwLjEgeiBtIDMyLjEsLTIzIGMgLTEuNyw0LjggLTQuMiw5LjIgLTguMiwxMi42IDAuNCwxLjkgLTAuNiwzLjIgLTEuOSw0LjMgMC42LC0wLjUgMS4zLC0wLjkgMiwtMS4zIDIuNCwtMS43IDQuMywtMy44IDUuOCwtNi4yIDEuNSwtMi45IDIuNCwtNiAyLjMsLTkuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDg1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDUxLjg3IGMgMC4xLC0wLjQgMC4zLC0wLjkgMC41LC0xLjQgLTQuNSwtNC43IC03LjIsLTEwLjMgLTguNiwtMTYuNSAwLDMuMyAwLjUsNi40IDEuNCw5LjIgMS42LDMuMyAzLjgsNi4yIDYuNyw4LjcgeiBNIDU2NC4yODc2NiwzOS4zNyBjIDAsLTAuOSAtMC4yLC0xLjggLTAuNCwtMi44IC0yLjEsNS4xIC00LjQsMTAgLTguMywxMy45IDAuMywwLjUgMC41LDEgMC42LDEuNCAzLjksLTMuNCA2LjMsLTcuNyA4LjEsLTEyLjUgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1Ni4xODc2Niw1NC44NyBjIC0wLjcsMC40IC0xLjMsMC44IC0yLDEuMyAtMC41LDAuNCAtMSwwLjggLTEuNSwxLjEgbCAtMC4xLDAuMSBjIC0xLjMsMSAtMi41LDEuOSAtNCwyLjcgLTQsMiAtOC4zLDIuNSAtMTIuOCwyLjUgSCA0MS45ODc2NjMgYyAtNC4yLDAgLTguMywtMC41IC0xMi4yLC0yLjQgLTAuOSwtMC42IC0xLjcsLTEuMSAtMi41LC0xLjcgLTAuNiwtMC40IC0xLjMsLTAuOCAtMS45LC0xLjIgLTEuMywtMC45IC0yLjYsLTEuOSAtMy4zLC0zLjEgLTMuMSwtMy4yIC01LjUsLTYuOCAtNi45LC0xMSAtMS4xLC0yLjIgLTEuOSwtNC42IC0yLjUsLTcuMiAtMC4zLDEuNCAwLjEsMyAwLjMsNC41IDEuMyw4LjggNi42LDE0LjkgMTMuNCwxOS45IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjM4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjgsLTEuNCAzLjcsLTIuOCA1LjUsLTQuMiAxLjgsLTIuNCAzLjYsLTQuOSA1LC03LjUgLTEuMywyLjQgLTMuMiw0LjUgLTUuNiw2LjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIC0wLjYsMC42IC0wLjksMS4zIC0xLjEsMiAwLjYsMi41IDEuNCw0LjkgMi41LDcuMiAtMC45LC0yLjggLTEuNCwtNS45IC0xLjQsLTkuMiB6IG0gNTQyLjE5OTk5NywxNy45IGMgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy41LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjUsLTEuNCAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC45IC0wLjEsMS42IDAuMiwyLjIgMS41LDEuNiAzLjMsMyA1LjEsNC40IDUuNiwzLjQgMTIsMy45IDE4LjYsMy45IDE2Mi4wOTk5OTcsLTAuMSAzMjQuMTk5OTk3LC0wLjEgNDg2LjI5OTk5NywtMC4xIDIuMywwIDQuNiwwLjEgNywtMC4xIDQuOSwtMC40IDkuNSwtMS45IDEzLjQsLTQuOCAwLjUsLTAuNCAxLjEsLTAuOCAxLjYsLTEuMiAxLjQsLTEgMi40LC0yLjMgMiwtNC4yIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwOTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMy4yODc2NjMsNTMuMDcgYyAwLjEsMC4xIDAuMywwLjEgMC40LDAuMiAtMC41LC0wLjggLTAuOSwtMS43IC0xLjIsLTIuOCAtMC4zLDAuNSAtMC40LDEgLTAuNSwxLjQgMC40LDAuNCAwLjgsMC44IDEuMywxLjIgeiBtIDUzMi43OTk5OTcsLTEuMiBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjUsMi4yIDAuNSwtMC4yIDAuOCwtMC41IDEuMSwtMC44IHogbSAtMy40LDUuNSBjIDAuNSwtMC40IDEsLTAuNyAxLjUsLTEuMSAtMC42LDAuNCAtMS4xLDAuOCAtMS42LDEuMiAwLC0wLjEgMCwtMC4xIDAuMSwtMC4xIHogTSAyNS4zODc2NjMsNTcuMjcgYyAwLjYsMC41IDEuMiwwLjkgMS45LDEuMiAtMS45LC0xLjQgLTMuNiwtMi44IC01LjEsLTQuNCAwLjYsMS4zIDIsMi4zIDMuMiwzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC41ODc2NiwzOC40NyBjIDAuMiwwLjYgMC4zLDEuMiAwLjQsMS44IDAuMiwtMS40IDAuMywtMi45IDAuMywtNC40IDAsMC4yIDAsMC4zIC0wLjEsMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDk1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDM4LjQ3IGMgMC4yLC0wLjcgMC41LC0xLjQgMC43LC0yLjEgMCwtMC4yIDAsLTAuMyAwLjEsLTAuNSAwLC0yLjggLTAuNCwtNS44IC0xLjMsLTguOSAwLDMuMiAtMC4xLDYuNCAtMC4xLDkuNiAwLjIsMC43IDAuNCwxLjMgMC42LDEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAsMS41IC0wLjEsMyAtMC4zLDQuNCAxLjEsNi42IC0zLjUsMTEuMyAtOCwxNS45IDguMiwtNC4yIDEyLC0xNi4zIDguOCwtMjUuNiAwLDEuOCAtMC4xLDMuNiAtMC41LDUuMyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAuNCwtMS44IDAuNSwtMy41IDAuNCwtNS4zIC0wLjQsLTEuMyAtMSwtMi41IC0xLjcsLTMuNiAwLjksMy4xIDEuMyw2LjEgMS4zLDguOSB6IG0gLTEsMy41IGMgMC4yLDMuNSAtMC44LDYuNSAtMi4zLDkuNCAxLjUsLTIuNSAyLjYsLTUuMyAzLC04LjQgLTAuMSwtMC42IC0wLjIsLTEuMiAtMC40LC0xLjggLTAuMSwwLjIgLTAuMiwwLjUgLTAuMywwLjggeiBtIC0wLjQsLTIuOCBjIDAuMiwwLjkgMC4zLDEuOSAwLjQsMi44IGwgMC4zLC0wLjkgYyAtMC4yLC0wLjYgLTAuNCwtMS4yIC0wLjcsLTEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEwMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC45ODc2Niw0MC4yNyBjIC0wLjUsMy4xIC0xLjUsNS45IC0zLDguNCAtMS40LDIuNiAtMy4yLDUgLTUsNy41IDQuNSwtNC42IDksLTkuMyA4LC0xNS45IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTAzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDMwOC4wNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTQsLTEuMyAtMjAuMSwtNS4xIDMsNS4zIDkuMyw1LjYgMTQuNyw3IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MTA1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuODg3NjYzLDMwNi4xNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjcgMC41LC0xLjQgMC40LC0yLjMgLTYuNiw0LjQgLTEzLjcsNS45IC0yMS43LDUuOSAtMTYzLjIsLTAuMSAtMzI2LjUsLTAuMSAtNDg5LjY5OTk5NywwIC04LDAgLTE1LjEsLTEuNSAtMjEuNywtNS45IDAuMywxLjEgMC43LDIgMS4yLDIuOCA2LjMsMy44IDEzLDUuMSAyMC4zLDUuMSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDEwNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDUzMi4xODc2NiwzMTAuMTcgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjM5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzYuMDg3NjYgYyA0LjMsMCA4LjMsLTAuNiAxMi4xLC0yLjQgMS42LC0wLjggMywtMS44IDQuMywtMi45IC00LDIuOSAtOC42LDQuNSAtMTMuNSw0LjkgLTIuMSwwLjIgLTQuNSwwLjEgLTYuOCwwLjEgeiBtIDIzLjksLTEwLjUgYyAwLjQsMS42IC0wLjMsMi43IC0xLjMsMy43IDEuMywtMS4xIDIuNiwtMi4zIDQsLTMuNSAxLjUsLTEuNCAyLjcsLTIuOSAzLjcsLTQuNSAxLjEsLTIuNiAxLjksLTUuMyAxLjgsLTguMiAtMS44LDQuOCAtNC4yLDkuMiAtOC4yLDEyLjUgeiBtIC01MzQuMTk5OTk3LDAgYyAtMi45LC0yLjUgLTUsLTUuNSAtNi42LC04LjggMS40LDQuMiAzLjcsNy44IDYuOCwxMSAtMC4yLC0wLjYgLTAuMywtMS4zIC0wLjIsLTIuMiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTA5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjE4NzY2LDI4Ny4yNyBjIDAsLTAuOSAtMC4xLC0xLjkgLTAuNCwtMi45IC0yLDUuMSAtNC41LDkuOSAtOC4zLDEzLjkgMC4zLDAuNSAwLjUsMSAwLjYsMS40IDQsLTMuMyA2LjQsLTcuNyA4LjEsLTEyLjQgeiBtIC01NDIuMjk5OTk3LDEyLjQgYyAwLjEsLTAuNCAwLjMsLTAuOSAwLjYsLTEuNCAtNC40LC00LjcgLTcuMywtMTAuMiAtOC42LC0xNi41IDAsMy4zIDAuNSw2LjQgMS40LDkuMiAxLjYsMy4yIDMuNyw2LjIgNi42LDguNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTExIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU4Ljc4NzY2LDI5OS45NyBjIC0xLjMsMS4yIC0yLjYsMi4zIC00LDMuNSAtMC41LDAuNSAtMS4xLDEgLTEuNywxLjQgLTAuMSwwLjEgLTAuMiwwLjIgLTAuNCwwLjMgLTEuNCwxLjEgLTIuOCwyLjEgLTQuMywyLjkgLTMuOCwxLjggLTcuOSwyLjQgLTEyLjEsMi40IEggNDIuMDg3NjYzIGMgLTQuMiwwIC04LjMsLTAuNSAtMTIuMiwtMi40IC0wLjksLTAuNiAtMS43LC0xLjEgLTIuNSwtMS43IC0wLjYsLTAuNCAtMS4zLC0wLjggLTEuOSwtMS4zIC0xLjIsLTAuOSAtMi42LC0xLjkgLTMuMiwtMy4xIC0zLjEsLTMuMiAtNS41LC02LjggLTYuOCwtMTEgLTEuMSwtMi4zIC0xLjksLTQuNiAtMi41LC03LjIgLTAuMywxLjQgMC4xLDMgMC4zLDQuNSAxLjMsOC44IDYuNiwxNC45IDEzLjQsMTkuOSAxMi4yLDMuNyAyNC43LDIuOCAzNy4yLDIuOCBIIDUxMy42ODc2NiBjIDEyLjcsMCAyNS40LDAuOSAzNy45LC0yLjggMi44LC0yLjMgNS41LC00LjYgOC4zLC03IDAuOSwtMS45IDEuOSwtMy44IDIuNywtNS44IC0xLjEsMS43IC0yLjMsMy4yIC0zLjgsNC42IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsMjgxLjc3IGMgLTAuNiwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNiwyLjUgMS40LDQuOSAyLjUsNy4yIC0wLjksLTIuOCAtMS40LC01LjkgLTEuNCwtOS4yIHogbSA1NDIuMTk5OTk3LDE3LjkgYyAtMC4zLDAuMyAtMC43LDAuNiAtMSwwLjggLTAuNywxLjYgLTIuMiwyLjYgLTMuOCwzLjUgLTUuMiwyLjkgLTEwLjYsNC4yIC0xNi42LDQuMiAtMTYzLjgsLTAuMSAtMzI3LjYsLTAuMSAtNDkxLjI5OTk5NywtMC4xIC0xLjYsMCAtMy4zLDAuMyAtNC45LC0wLjEgLTUuNCwtMS41IC0xMS43LC0xLjcgLTE0LjgsLTcgLTAuMSwtMC4xIC0wLjMsLTAuMSAtMC40LC0wLjIgLTAuNSwtMC40IC0wLjksLTAuOCAtMS40LC0xLjIgLTAuMiwwLjggLTAuMSwxLjYgMC4yLDIuMiAxLjUsMS42IDMuMywzIDUuMSw0LjQgNS42LDMuNCAxMiwzLjkgMTguNiwzLjkgMTYyLjA5OTk5NywtMC4xIDMyNC4xOTk5OTcsLTAuMSA0ODYuMzk5OTk3LC0wLjEgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNiwtMiAxMy41LC00LjkgMC4xLC0wLjEgMC4yLC0wLjIgMC40LC0wLjMgMC42LC0wLjUgMS4xLC0wLjkgMS43LC0xLjQgMSwtMC44IDEuNywtMiAxLjMsLTMuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDI5OS42NyBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjQsMi4zIDAuMywtMC4zIDAuNywtMC42IDEsLTAuOSB6IG0gLTUzMi43OTk5OTcsMS4yIGMgMC4xLDAuMSAwLjMsMC4xIDAuNCwwLjIgLTAuNSwtMC44IC0wLjksLTEuOCAtMS4yLC0yLjggLTAuMywwLjUgLTAuNSwxIC0wLjYsMS40IDAuNSwwLjQgMC45LDAuOCAxLjQsMS4yIHogbSAyLjEsNC4yIGMgMC42LDAuNSAxLjMsMC45IDEuOSwxLjMgLTEuOSwtMS40IC0zLjYsLTIuOCAtNS4xLC00LjQgMC42LDEuMiAyLDIuMSAzLjIsMy4xIHogbSA1MjkuMzk5OTk3LC0xLjYgYyAtMC42LDAuNSAtMS4xLDAuOSAtMS43LDEuNCAwLjYsLTAuNSAxLjIsLTAuOSAxLjcsLTEuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDI4Ni4wNyBjIDAuMiwwLjYgMC40LDEuMiAwLjUsMS44IDAuMiwtMS40IDAuMiwtMi44IDAuMiwtNC4yIDAsMC4yIC0wLjEsMC40IC0wLjEsMC42IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTE5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjE4NzY2LDI4NC4yNyBjIDAuMSwtMC4yIDAuMSwtMC40IDAuMSwtMC42IC0wLjEsLTIuNCAtMC41LC00LjkgLTEuMiwtNy40IGwgLTAuMyw4LjEgYyAwLjMsMC42IDAuNiwxLjEgMC44LDEuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4xODc2NiwyODcuODcgYyAwLjksNS4xIC0yLjQsOS4yIC01LjQsMTMuNCA2LjUsLTUuNSA4LjksLTE1LjIgNiwtMjIuMiAwLDEuNSAtMC4xLDMuMSAtMC40LDQuNiAwLDEuNCAtMC4xLDIuOCAtMC4yLDQuMiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwyODMuNTcgYyAwLjMsLTEuNSAwLjQsLTMuMSAwLjQsLTQuNiAtMC40LC0xIC0xLC0yIC0xLjYsLTIuOCAwLjcsMi42IDEuMSw1IDEuMiw3LjQgeiBtIC0xLjEsMy43IGMgMC4xLDIuOSAtMC43LDUuNiAtMS44LDguMiAxLjUsLTIuNCAyLjMsLTUgMi43LC03LjYgLTAuMSwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuMSwwLjQgLTAuMiwwLjggLTAuNCwxLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxMjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjQuNTg3NjYsMjg2LjA3IGMgLTAuMiwtMC42IC0wLjQsLTEuMSAtMC44LC0xLjcgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAuMiwtMC40IDAuMywtMC44IDAuNCwtMS4yIHogbSAwLjYsMS44IGMgLTAuNCwyLjcgLTEuMiw1LjIgLTIuNyw3LjYgLTAuOCwxLjkgLTEuOCwzLjggLTIuNyw1LjggMi45LC00LjIgNi4zLC04LjMgNS40LC0xMy40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTI3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDQ3Mi4zNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTMuOSwtMS4zIC0yMC4xLC01LjEgMyw1LjMgOS4zLDUuNSAxNC43LDcgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA0My43ODc2NjMsNDcwLjQ3IGMgMTYzLjM5OTk5NywtMC4xIDMyNi44OTk5OTcsLTAuMSA0OTAuMjk5OTk3LDAgNy40LDAgMTQuMiwtMS40IDIwLjUsLTUuMyAwLjEsLTAuMSAwLjMsLTAuMiAwLjQsLTAuMyAwLjMsLTAuNyAwLjUsLTEuNCAwLjQsLTIuMyAtNi42LDQuNCAtMTMuNyw1LjkgLTIxLjcsNS45IC0xNjMuMiwtMC4xIC0zMjYuNSwtMC4xIC00ODkuNjk5OTk3LDAgLTgsMCAtMTUuMSwtMS41IC0yMS43LC01LjkgMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuNCwzLjcgMTMuMSw1LjEgMjAuMyw1LjEgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMzEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS44ODc2NjMsNDYzLjk3IGMgLTMuMSwtMi43IC01LjQsLTYgLTcsLTkuNiAxLjQsNC41IDMuOSw4LjMgNy4yLDExLjcgLTAuMiwtMC42IC0wLjMsLTEuMyAtMC4yLC0yLjEgeiBtIDU0Mi4yOTk5OTcsLTEyLjUgYyAtMS43LDQuOCAtNC4yLDkuMSAtOC4xLDEyLjUgMC42LDIuNSAtMS41LDQgLTMuMyw1LjQgLTQsMi45IC04LjYsNC41IC0xMy42LDQuOSAtMi4zLDAuMiAtNC42LDAuMSAtNywwLjEgLTE2Mi4xLDAgLTMyNC4zLDAgLTQ4Ni4zOTk5OTcsMC4xIC03LDAgLTEzLjcsLTAuNiAtMTkuNSwtNC41IDEuMSwwLjkgMi4yLDEuOCAzLjQsMi43IDQuMiwxLjcgOC41LDIuMSAxMywyLjEgSCA1MzUuMjg3NjYgYyA0LjcsMCA5LjIsLTAuNSAxMy42LC0yLjMgMS45LC0xLjQgMy43LC0yLjkgNS44LC00IDIuNywtMS42IDQuOSwtMy44IDYuNiwtNi41IDEuOSwtMy4yIDMuMSwtNi42IDIuOSwtMTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuODg3NjYzLDQ2My45NyBjIDAuMSwtMC40IDAuMywtMC45IDAuNiwtMS40IC00LjQsLTQuNyAtNy4zLC0xMC4yIC04LjYsLTE2LjUgLTAuMSwzLjEgMC4zLDUuOCAxLjEsOC40IDEuNiwzLjYgMy44LDYuOCA2LjksOS41IHogbSA1NDIuMjk5OTk3LC0xMi41IGMgMCwtMC45IC0wLjIsLTEuOSAtMC40LC0yLjkgLTIsNS4xIC00LjUsOS45IC04LjMsMTMuOSAwLjMsMC41IDAuNSwxIDAuNiwxLjQgNCwtMy4zIDYuNCwtNy42IDguMSwtMTIuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0LjY4NzY2LDQ2OC40NyBjIC0yLjEsMS4xIC0zLjksMi42IC01LjgsNCAtNC4zLDEuOCAtOC45LDIuMyAtMTMuNiwyLjMgSCA0Mi42ODc2NjMgYyAtNC41LDAgLTguOCwtMC40IC0xMywtMi4xIC0xLjIsLTAuOSAtMi4zLC0xLjcgLTMuNCwtMi43IC0wLjMsLTAuMiAtMC42LC0wLjQgLTAuOSwtMC43IC0xLjMsLTEgLTIuNywtMS45IC0zLjMsLTMuMiAtMy4zLC0zLjQgLTUuOCwtNy4yIC03LjIsLTExLjcgLTAuOSwtMiAtMS42LC00LjIgLTIuMSwtNi40IC0wLjYsMS45IC0wLjEsMy45IDAuNCw1LjkgMS44LDguMSA3LDEzLjggMTMuNCwxOC42IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjU4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjQsLTAuOSAyLjgsLTEuOSA0LjEsLTIuOCAyLC0yLjUgNC4xLC01IDUuNywtNy43IC0xLjcsMi42IC0zLjksNC44IC02LjYsNi41IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsNDQ2LjA3IGMgLTAuNSwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNSwyLjIgMS4yLDQuNCAyLjEsNi40IC0wLjcsLTIuNiAtMS4xLC01LjQgLTEsLTguNCB6IG0gNTE4LjM5OTk5NywyOC40IGMgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNSwtMiAxMy42LC00LjkgMS45LC0xLjQgMy45LC0yLjkgMy4zLC01LjQgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy42LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjQsLTEuNSAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC44IC0wLjEsMS41IDAuMiwyLjEgMS4zLDEuNCAyLjcsMi42IDQuMiwzLjkgNS45LDMuOSAxMi41LDQuNSAxOS41LDQuNSAxNjIuMDk5OTk3LC0wLjEgMzI0LjE5OTk5NywwIDQ4Ni4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMjg3NjYzLDQ2NS4xNyBjIDAuMSwwLjEgMC4zLDAuMSAwLjQsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjMsMC41IC0wLjUsMSAtMC42LDEuNCAwLjUsMC40IDAuOSwwLjggMS40LDEuMiB6IG0gNTMyLjc5OTk5NywtMS4yIGMgLTAuMSwtMC40IC0wLjMsLTAuOSAtMC42LC0xLjQgMCwwLjkgLTAuMiwxLjYgLTAuNCwyLjMgMC4zLC0wLjMgMC43LC0wLjYgMSwtMC45IHogbSAtNTMwLjY5OTk5Nyw1LjMgYyAwLjMsMC4yIDAuNiwwLjQgMC45LDAuNyAtMS41LC0xLjIgLTIuOSwtMi41IC00LjIsLTMuOSAwLjYsMS4zIDIsMi4zIDMuMywzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDE0MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgYyAwLjIsMC44IDAuMywxLjUgMC40LDIuMyAwLjQsLTEuOCAwLjUsLTMuNiAwLjUsLTUuNSAtMC4xLDAuMyAtMC4xLDAuNiAtMC4yLDEgLTAuMiwwLjYgLTAuNCwxLjQgLTAuNywyLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuMTg3NjYsNDQ4LjQ3IGMgMC4xLC0wLjMgMC4xLC0wLjYgMC4yLC0xIDAsLTIuOCAtMC41LC01LjcgLTEuNCwtOC40IC0wLjEsMy4yIC0wLjEsNi40IC0wLjIsOS41IDAuMywwLjcgMC41LDEuNCAwLjYsMi4xIDAuNCwtMC43IDAuNiwtMS41IDAuOCwtMi4yIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjM4NzY2LDQ0Ny40NyBjIDAsMS45IC0wLjIsMy43IC0wLjUsNS41IDAuNSw1LjggLTIuNiwxMS4yIC05LjMsMTYuNyA3LjksLTMuNCAxMC40LC0xMC41IDExLC0xOCAwLjMsLTMuNiAxLjksLTcuOSAtMC45LC0xMS4yIDAuMSwyLjMgMC4xLDQuNyAtMC4zLDcgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsNDM5LjA3IGMgMC45LDIuOCAxLjMsNS42IDEuNCw4LjQgMC40LC0yLjMgMC40LC00LjcgMC4yLC03LjEgLTAuNCwtMC40IC0wLjksLTAuOSAtMS42LC0xLjMgeiBtIDAuMiwxMi40IGMgMC4yLDQgLTEuMSw3LjMgLTMsMTAuNSAxLjcsLTIuNiAyLjksLTUuNyAzLjYsLTguOSAtMC4xLC0wLjggLTAuMiwtMS41IC0wLjQsLTIuMyAwLDAuMiAtMC4xLDAuNCAtMC4yLDAuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE0OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgLTAuNiwtMi4xIGMgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAsLTAuNCAwLjEsLTAuNiAwLjIsLTAuOCB6IG0gMC40LDIuMiBjIC0wLjYsMy4yIC0xLjksNi4zIC0zLjYsOC45IC0xLjYsMi43IC0zLjcsNS4yIC01LjcsNy43IDYuNywtNS40IDkuNywtMTAuOCA5LjMsLTE2LjYgeiBtIC01MjIuMTk5OTk3LDIzIGMgLTUuNywwIC0xMSwtMS4xIC0xNi4xLC0zLjUgMy44LDQuMyA4LjksNC4yIDE0LDQuMiBIIDUzNi43ODc2NiBjIDUuMywwIDEwLjYsMC4yIDE0LjcsLTQuMiAtNS4xLDIuNCAtMTAuNSwzLjUgLTE2LjEsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTEzLjU4NzY2LDQ3NS4yNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuMSwyLjQgMTAuNCwzLjUgMTYuMSwzLjUgSCA1MzUuMjg3NjYgYyA1LjcsMCAxMSwtMS4xIDE2LjEsLTMuNSAtMTIuNCwzLjcgLTI1LjEsMi44IC0zNy44LDIuOCB6IG0gMTkuNiwtMTYzLjUgYyAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIC02LjQsMCAtMTIuNCwtMSAtMTguMiwtMy41IDMuNywzLjMgOC4xLDQuMiAxMi44LDQuMiBIIDUzOC41ODc2NiBjIDQuNywwIDkuMiwtMC45IDEyLjgsLTQuMiAtNS44LDIuNSAtMTEuOCwzLjUgLTE4LjIsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTMzLjE4NzY2LDMxMS43NyBjIDYuNCwwIDEyLjQsLTEgMTguMiwtMy41IC0xMi40LDMuNyAtMjUuMiwyLjggLTM3LjksMi44IEggNjMuNjg3NjYzIGMgLTEyLjQsMCAtMjUsMC45IC0zNy4yLC0yLjggNS44LDIuNiAxMS44LDMuNSAxOC4yLDMuNSAxNjIuODk5OTk3LC0wLjEgMzI1LjY5OTk5NywtMC4xIDQ4OC40OTk5OTcsMCB6IE0gNDQuNzg3NjYzLDYzLjk3IGMgLTYuNCwwIC0xMi40LC0xIC0xOC4yLC0zLjUgMy43LDMuMyA4LjEsNC4yIDEyLjgsNC4yIEggNTM4LjU4NzY2IGMgNC43LDAgOS4yLC0wLjkgMTIuOCwtNC4yIC01LjgsMi42IC0xMS44LDMuNSAtMTguMiwzLjUgLTE2Mi44LC0wLjEgLTMyNS42LC0wLjEgLTQ4OC4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJNIDUxMy41ODc2Niw2My4xNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuOCwyLjYgMTEuOCwzLjUgMTguMiwzLjUgMTYyLjc5OTk5NywtMC4xIDMyNS41OTk5OTcsLTAuMSA0ODguMzk5OTk3LDAgNi40LDAgMTIuNCwtMSAxOC4yLC0zLjUgLTEyLjQsMy43IC0yNS4xLDIuOCAtMzcuOCwyLjggeiBtIC00NjguNzk5OTk3LDgyLjkgYyAtNi40LDAgLTEyLjQsLTEgLTE4LjIsLTMuNSAzLjcsMy4zIDguMSw0LjIgMTIuOCw0LjIgSCA1MzguNTg3NjYgYyA0LjcsMCA5LjIsLTAuOSAxMi44LC00LjIgLTUuOCwyLjUgLTExLjgsMy41IC0xOC4yLDMuNSAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTE0LjI4NzY2LDE0NS4yNyBIIDY0LjQ4NzY2MyBjIC0xMi43LDAgLTI1LjQsMC45IC0zNy45LC0yLjggNS44LDIuNSAxMS44LDMuNSAxOC4yLDMuNSAxNjIuNzk5OTk3LC0wLjEgMzI1LjU5OTk5NywtMC4xIDQ4OC4zOTk5OTcsMCA2LjQsMCAxMi40LC0xIDE4LjIsLTMuNSAtMTIuMSwzLjggLTI0LjcsMi44IC0zNy4xLDIuOCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQwLjI4NzY2MywzOTEuMDcgaCAxLjYgYyAxLjEsMCAyLjIsLTAuMiAzLjMsLTAuMiBIIDUzMi43ODc2NiBjIDAuOCwwIDEuNiwwLjEgMi40LDAuMSAxLjEsMCAyLjIsLTAuMSAzLjMsLTAuMSAwLjYsLTAuMSAxLjIsLTAuMyAxLjgsLTAuNyBIIDM3LjY4NzY2MyBjIDAuOSwwLjYgMS44LDAuOSAyLjYsMC45IHogbSA0OTguMTk5OTk3LC0wLjEgYyAtMS4xLDAuMSAtMi4yLDAuMSAtMy4zLDAuMSAxLjEsMC4xIDIuMiwwLjIgMy4zLC0wLjEgeiBtIC00OTQuMzk5OTk3LDAuNyBoIC00IGMgMS4zLDAuMyAyLjcsMC4xIDQsMCB6IG0gNDkzLjc5OTk5NywwIGggLTQuMiBjIDEuNCwwLjEgMi45LDAuMyA0LjIsMCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQ1LjE4NzY2MywzOTAuOTcgYyAtMS4xLDAgLTIuMiwwLjEgLTMuMywwLjIgSCA1MzUuMDg3NjYgYyAtMC44LDAgLTEuNiwtMC4xIC0yLjQsLTAuMSAtMTYyLjQsMCAtMzI0LjksMCAtNDg3LjQ5OTk5NywtMC4xIHogbSA0OTQuNDk5OTk3LC0wLjEgYyAwLjIsLTAuMiAwLjQsLTAuMyAwLjYsLTAuNiAtMC42LDAuMyAtMS4yLDAuNSAtMS44LDAuNyAwLjQsMCAwLjgsMCAxLjIsLTAuMSB6IG0gLTUwMS45OTk5OTcsLTAuNSBjIDAuMiwwLjMgMC41LDAuNSAwLjcsMC42IDAuNCwwIDAuNywwLjEgMS4xLDAuMSBoIDAuOCBjIC0wLjgsMCAtMS43LC0wLjMgLTIuNiwtMC43IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MTYzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTM4LjQ4NzY2LDM5MC45NyBjIC0xLjEsMC4yIC0yLjIsMC4yIC0zLjMsMC4xIEggMzkuNTg3NjYzIGMgLTAuNCwwIC0wLjcsLTAuMSAtMS4xLC0wLjEgMC41LDAuNCAxLjEsMC42IDEuNywwLjggSCA1MzcuODg3NjYgYyAwLjYsLTAuMSAxLjIsLTAuNCAxLjcsLTAuOCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+Cjwvc3ZnPgo= - mediatype: image/svg+xml - install: - spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.3.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: - - rules: - - apiGroups: - - "" - resources: - - pods - - services - - services/finalizers - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - - replicationcontrollers - - podtemplates - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - apiGroups: - - apps - resources: - - replicasets - - deployments - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - '*' - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - serviceAccountName: nexus-operator - strategy: deployment - installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - nexus - - sonatype - - maven - - docker - - ci - - continuous integration - - continuous delivery - - repository - - repository manager - - dev tools - labels: - name: nexus-operator - links: - - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/main/README.md - - name: Nexus Operator source code repository - url: https://github.com/m88i/nexus-operator - maintainers: - - email: nexus-operator@googlegroups.com - name: m88i Labs - maturity: alpha - minKubeVersion: 1.11.0 - provider: - name: m88i Labs - replaces: nexus-operator.v0.2.1 - version: 0.3.0 diff --git a/deploy/olm-catalog/nexus-operator/0.4.0/apps.m88i.io_nexus_crd.yaml b/deploy/olm-catalog/nexus-operator/0.4.0/apps.m88i.io_nexus_crd.yaml deleted file mode 100644 index 4c20fb6f..00000000 --- a/deploy/olm-catalog/nexus-operator/0.4.0/apps.m88i.io_nexus_crd.yaml +++ /dev/null @@ -1,392 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: nexus.apps.m88i.io -spec: - group: apps.m88i.io - names: - kind: Nexus - listKind: NexusList - plural: nexus - singular: nexus - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NexusSpec defines the desired state of Nexus - properties: - automaticUpdate: - description: Automatic updates configuration - properties: - disabled: - description: Whether or not the Operator should perform automatic - updates. Defaults to `false` (auto updates are enabled). Is set - to `false` if `spec.image` is not empty and is different from - the default community image. - type: boolean - minorVersion: - description: The Nexus image minor version the deployment should - stay in. If left blank and automatic updates are enabled the latest - minor is set. - minimum: 0 - type: integer - type: object - generateRandomAdminPassword: - description: 'GenerateRandomAdminPassword enables the random password - generation. Defaults to `false`: the default password for a newly - created instance is ''admin123'', which should be changed in the first - login. If set to `true`, you must use the automatically generated - ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. - The operator uses the default credentials to create a user for itself - to create default repositories. If set to `true`, the repositories - won''t be created since the operator won''t fetch for the random password.' - type: boolean - image: - description: 'Full image tag name for this specific deployment. Will - be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' - type: string - imagePullPolicy: - description: 'The image pull policy for the Nexus image. If left blank - behavior will be determined by the image tag (`Always` if "latest" - and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` - or `Never`.' - enum: - - Always - - IfNotPresent - - Never - type: string - livenessProbe: - description: LivenessProbe describes how the Nexus container liveness - probe should work - properties: - failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. - format: int32 - minimum: 1 - type: integer - initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. - format: int32 - minimum: 0 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - type: object - networking: - description: Networking definition - properties: - expose: - description: Set to `true` to expose the Nexus application. Defaults - to `false`. - type: boolean - exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Defaults to Route on OpenShift and Ingress on Kubernetes. Routes - are only available on Openshift and Ingresses are only available - on Kubernetes.' - enum: - - NodePort - - Route - - Ingress - type: string - host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. - type: string - nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. - format: int32 - type: integer - tls: - description: TLS/SSL-related configuration - properties: - mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to `false`. - type: boolean - secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. - type: string - type: object - type: object - persistence: - description: Persistence definition - properties: - persistent: - description: Flag to indicate if this instance will be persistent - or not - type: boolean - storageClass: - description: StorageClass used by the managed PVC. - type: string - volumeSize: - description: 'If persistent, the size of the Volume. Defaults: 10Gi' - type: string - required: - - persistent - type: object - readinessProbe: - description: ReadinessProbe describes how the Nexus container readiness - probe should work - properties: - failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. - format: int32 - minimum: 1 - type: integer - initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. - format: int32 - minimum: 0 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - type: object - replicas: - description: Number of pod replicas desired. Defaults to 0. - format: int32 - maximum: 100 - minimum: 0 - type: integer - resources: - description: Defined Resources for the Nexus instance - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - serverOperations: - description: ServerOperations describes the options for the operations - performed on the deployed server instance - properties: - disableOperatorUserCreation: - description: DisableOperatorUserCreation disables the auto-creation - of the `nexus-operator` user on the deployed server. This user - performs all the operations on the server (such as creating the - community repos). If disabled, the Operator will use the default - `admin` user. Defaults to `false` (always create the user). Setting - this to `true` is not recommended as it grants the Operator more - privileges than it needs and it would not be possible to tell - apart operations performed by the `admin` and the Operator. - type: boolean - disableRepositoryCreation: - description: DisableRepositoryCreation disables the auto-creation - of Apache, JBoss and Red Hat repositories and their addition to - the Maven Public group in this Nexus instance. Defaults to `false` - (always try to create the repos). Set this to `true` to not create - them. Only works if `spec.generateRandomAdminPassword` is `false`. - type: boolean - type: object - serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR (`metadata.name`). - type: string - useRedHatImage: - description: If you have access to Red Hat Container Catalog, set this - to `true` to use the certified image provided by Sonatype Defaults - to `false` - type: boolean - required: - - persistence - - replicas - - useRedHatImage - type: object - status: - description: NexusStatus defines the observed state of Nexus - properties: - deploymentStatus: - description: Condition status for the Nexus deployment - properties: - availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. - format: int32 - type: integer - collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. - format: int32 - type: integer - conditions: - description: Represents the latest available observations of a deployment's - current state. - items: - description: DeploymentCondition describes the state of a deployment - at a certain point. - properties: - lastTransitionTime: - description: Last time the condition transitioned from one - status to another. - format: date-time - type: string - lastUpdateTime: - description: The last time this condition was updated. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of deployment condition. - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: The generation observed by the deployment controller. - format: int64 - type: integer - readyReplicas: - description: Total number of ready pods targeted by this deployment. - format: int32 - type: integer - replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). - format: int32 - type: integer - unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. - format: int32 - type: integer - updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. - format: int32 - type: integer - type: object - nexusRoute: - description: Route for external service access - type: string - nexusStatus: - description: Will be "OK" when this Nexus instance is up - type: string - reason: - description: Gives more information about a failure status - type: string - serverOperationsStatus: - description: ServerOperationsStatus describes the general status for - the operations performed in the Nexus server instance - properties: - communityRepositoriesCreated: - type: boolean - mavenCentralUpdated: - type: boolean - operatorUserCreated: - type: boolean - reason: - type: string - serverReady: - type: boolean - type: object - updateConditions: - description: Conditions reached during an update - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml deleted file mode 100644 index 420b0f86..00000000 --- a/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml +++ /dev/null @@ -1,322 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "apps.m88i.io/v1alpha1", - "kind": "Nexus", - "metadata": { - "name": "nexus3" - }, - "spec": { - "networking": { - "expose": false - }, - "persistence": { - "persistent": false - }, - "replicas": 1, - "resources": { - "limits": { - "cpu": "2", - "memory": "2Gi" - }, - "requests": { - "cpu": "1", - "memory": "2Gi" - } - }, - "useRedHatImage": false - } - } - ] - capabilities: Seamless Upgrades - categories: Developer Tools - certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.4.0 - createdAt: "2019-11-16T13:12:22Z" - description: Nexus Operator to deploy and manage Nexus 3.x servers - repository: https://github.com/m88i/nexus-operator - support: m88i Labs - tectonic-visibility: ocs - name: nexus-operator.v0.4.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Nexus custom resource to deploy the Nexus Server - displayName: Nexus - kind: Nexus - name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: A Kubernetes Deployment - version: v1 - - kind: PersistentVolumeClaim - name: A Kubernetes PersistentVolumeClaim - version: v1 - - kind: Service - name: A Kubernetes Service - version: v1 - specDescriptors: - - description: Automatic updates configuration - displayName: Automatic Update - path: automaticUpdate - - description: 'GenerateRandomAdminPassword enables the random password generation. - Defaults to `false`: the default password for a newly created instance is - ''admin123'', which should be changed in the first login. If set to `true`, - you must use the automatically generated ''admin'' password, stored in the - container''s file system at `/nexus-data/admin.password`. The operator uses - the default credentials to create a user for itself to create default repositories. - If set to `true`, the repositories won''t be created since the operator - won''t fetch for the random password.' - displayName: Generate Random Admin Password - path: generateRandomAdminPassword - - description: 'Full image tag name for this specific deployment. Will be ignored - if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: 'The image pull policy for the Nexus image. If left blank behavior - will be determined by the image tag (`Always` if "latest" and `IfNotPresent` - otherwise). Possible values: `Always`, `IfNotPresent` or `Never`.' - displayName: Image Pull Policy - path: imagePullPolicy - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:imagePullPolicy - - description: Number of pod replicas desired. Defaults to 0. - displayName: Replicas - path: replicas - - description: Defined Resources for the Nexus instance - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: ServerOperations describes the options for the operations performed - on the deployed server instance - displayName: Server Operations - path: serverOperations - - description: ServiceAccountName is the name of the ServiceAccount used to - run the Pods. If left blank, a default ServiceAccount is created with the - same name as the Nexus CR (`metadata.name`). - displayName: Service Account - path: serviceAccountName - - description: If you have access to Red Hat Container Catalog, set this to - `true` to use the certified image provided by Sonatype Defaults to `false` - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - statusDescriptors: - - description: Condition status for the Nexus deployment - displayName: appsv1.DeploymentStatus - path: deploymentStatus - - description: Route for external service access - displayName: Nexus Route - path: nexusRoute - - description: Will be "OK" when this Nexus instance is up - displayName: Nexus Status - path: nexusStatus - - description: Gives more information about a failure status - displayName: Reason - path: reason - x-descriptors: - - urn:alm:descriptor:io.kubernetes.phase:reason - - description: Conditions reached during an update - displayName: Update Conditions - path: updateConditions - version: v1alpha1 - description: |- - Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: - - * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world - * On OpenShift, creates a Route to expose the service outside the cluster - * Automatically creates Apache, Red Hat and JBoss Maven repositories - * Automatically updates Nexus within the same minor version - - [See our documentation](https://github.com/m88i/nexus-operator/blob/main/README.md) for more installation and usage scenarios. - - If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues) or send an email to our maillist: [nexus-operator@googlegroups.com](mailto:nexus-operator@googlegroups.com) - - *Please note that the operator is an individual work and it's not provided nor supported by Sonatype.* - displayName: Nexus Operator - icon: - - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgcm9sZT0iaW1nIgogICB2aWV3Qm94PSI4LjM3IDUuODcgNTYxLjI0MTYzIDQ3My40NDQ0NSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnNDE2NyIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic29uYXR5cGUtbmV4dXMtY3JvcC5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTIuNCAodW5rbm93bikiCiAgIHdpZHRoPSI1NjEuMjQxNjQiCiAgIGhlaWdodD0iNDczLjQ0NDQ2Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE0MTczIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT5Tb25hdHlwZSBOZXh1cyBsb2dvPC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczQxNzEiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijk5MCIKICAgICBpZD0ibmFtZWR2aWV3NDE2OSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMS4wNTE1OCIKICAgICBpbmtzY2FwZTpjeD0iMjgwLjQ2NzY3IgogICAgIGlua3NjYXBlOmN5PSIxMDcuOTk0NDQiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc0MTY3IiAvPgogIDx0aXRsZQogICAgIGlkPSJ0aXRsZTM5NjMiPlNvbmF0eXBlIE5leHVzIGxvZ288L3RpdGxlPgogIDxzdHlsZQogICAgIGlkPSJzdHlsZTM5NjUiPnN2ZyB7ZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2MDAgNzY0fTwvc3R5bGU+CiAgPHN0eWxlCiAgICAgaWQ9InN0eWxlMzk2NyI+LnN0NXtmaWxsOiNkNGQ0ZDR9LnN0NTR7ZmlsbDojMzI2Nzk4fS5zdDU1e2ZpbGw6I2ViZWJlYn0uc3Q1NntmaWxsOiMwMjAyMDJ9LnN0NTd7ZmlsbDojZWNlY2VjfS5zdDU4e2ZpbGw6IzAxMDEwMX0uc3Q2MHtmaWxsOiMwNDA0MDR9LnN0NjF7ZmlsbDojYmRiZGJkfS5zdDYye2ZpbGw6I2U4ZThlOH0uc3Q2M3tmaWxsOiNjZGNkY2V9LnN0NjR7ZmlsbDojY2ZjZmNmfTwvc3R5bGU+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAxLjksNS41IDQuNSwxMC42IDguNiwxNSA3LjIsNC45IDE1LjEsNi4xIDIzLjcsNi4xIDE2MS43OTk5OTcsLTAuMiAzMjMuNTk5OTk3LC0wLjIgNDg1LjM5OTk5NywwIDguNiwwIDE2LjUsLTEuMiAyMy43LC02LjEgNCwtNC4zIDYuNywtOS40IDguNiwtMTUgMC42LC02LjMgLTAuNywtMTIuMiAtMy4xLC0xOCAtNi42LC05LjMgLTE1LjUsLTEyLjggLTI2LjksLTEyLjggLTE2My4zLDAuMiAtMzI2LjYsMC4yIC00ODkuODk5OTk3LDAgLTExLjQsMCAtMjAuMywzLjUgLTI2LjksMTIuOCAtMi41LDUuOCAtMy44LDExLjggLTMuMiwxOCB6IG0gMC4xLC04Mi4zIGMgMi4xLDUuMSA0LjQsMTAgOC4zLDEzLjkgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNTk5OTk3LC0wLjEgMzI1LjE5OTk5NywtMC4xIDQ4Ny43OTk5OTcsMCA3LjYsMCAxNC43LC0wLjggMjEuNCwtNC43IDIuMywtMi43IDQuNywtNS40IDcsLTguMSAxLC0zLjIgMiwtNi40IDMsLTkuNyAwLjQsLTYuNSAtMS44LC0xMi4zIC00LjgsLTE3LjkgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTEuNCwzLjcgLTQuOSw2LjUgLTQuNywxMSAwLjIsMy41IDAuMiw2LjcgMC4zLDkuOCB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk2OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzNjMuODcgYyAxLjEsMi4xIC0wLjMsNC45IDEuNiw2LjggMi40LDMuOSA1LDcuNyA4LjUsMTAuOSA2LjQsMy44IDEzLjMsNC43IDIwLjYsNC43IDE2My4wOTk5OTcsLTAuMSAzMjYuMTk5OTk3LC0wLjEgNDg5LjE5OTk5NywwIDgsMCAxNS4xLC0xLjQgMjEuNiwtNS45IDQuNSwtNC42IDYuOCwtMTAuNCA4LjYsLTE2LjUgMC4yLC02IC0xLjQsLTExLjUgLTQuMSwtMTYuNyAtNi4zLC04LjEgLTE0LjUsLTExLjIgLTI0LjgsLTExLjIgLTE2NC4yLDAuMSAtMzI4LjMsMC4xIC00OTIuNDk5OTk3LDAgLTEwLjMsMCAtMTguNSwzLjEgLTI0LjgsMTEuMiAtMi41LDUuMiAtNC4xLDEwLjggLTMuOSwxNi43IHoiCiAgICAgaWQ9InBhdGgzOTcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIDEuNCw2LjMgNC4xLDExLjkgOC42LDE2LjUgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNzk5OTk3LC0wLjEgMzI1LjQ5OTk5NywtMC4xIDQ4OC4yOTk5OTcsMCA4LjIsMCAxNS42LC0xLjMgMjIuNCwtNS44IDMuOSwtNCA2LjMsLTguOSA4LjMsLTEzLjkgMCwtMy4yIDAuMSwtNi40IDAuMSwtOS42IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTEgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTIuOSw1LjcgLTUuMSwxMS42IC00LjcsMTguMSB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk3MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywyODEuNzcgYyAxLjMsNi4zIDQuMiwxMS44IDguNiwxNi41IDYuNiw0LjQgMTMuNyw1LjkgMjEuNyw1LjkgMTYzLjE5OTk5NywtMC4xIDMyNi40OTk5OTcsLTAuMSA0ODkuNjk5OTk3LDAgOCwwIDE1LjEsLTEuNSAyMS43LC01LjkgMy44LC00IDYuNCwtOC44IDguMywtMTMuOSBsIDAuMywtOC4xIC00LjgsLTEyLjMgYyAtNi40LC03LjIgLTE0LjMsLTEwLjEgLTI0LC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC0xMC4zLDAgLTE4LjUsMy4xIC0yNC44LDExLjIgLTIuOCw1LjIgLTQuNCwxMC43IC00LjIsMTYuNyB6IG0gMCwxNjQuMyBjIDEuMyw2LjMgNC4yLDExLjggOC42LDE2LjUgNi42LDQuNCAxMy43LDUuOSAyMS43LDUuOSAxNjMuMTk5OTk3LC0wLjEgMzI2LjQ5OTk5NywtMC4xIDQ4OS42OTk5OTcsMCA4LDAgMTUuMSwtMS41IDIxLjcsLTUuOSAzLjgsLTQgNi40LC04LjggOC4zLC0xMy45IDAuMSwtMy4yIDAuMSwtNi40IDAuMiwtOS41IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTAuOSAtNi42LC03LjYgLTE0LjgsLTEwLjIgLTI0LjgsLTEwLjIgLTE2My43LDAuMiAtMzI3LjUsMC4yIC00OTEuMTk5OTk3LDAgLTkuOSwwIC0xOC4xLDIuNiAtMjQuNywxMC4xIC0zLjEsNS41IC01LjIsMTEuNCAtNC44LDE3LjkgeiIKICAgICBpZD0icGF0aDM5NzUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNDMuNjg3NjYzLDIzMi45NyBIIDQyMi4yODc2NiBjIDM3LjYsMCA3NS4yLDAuMiAxMTIuOCwtMC4xIDE0LjIsLTAuMSAyNS41LC02IDMxLjcsLTE5LjUgNS4zLC0xMS42IDIuOCwtMjQuNSAtNS45LC0zMC40IDUsNC45IDUuNSwxMS4xIDQuNywxNy41IC0wLjMsMS4xIC0wLjYsMi4xIC0wLjksMy4yIDEsOC45IC03LjUsMTkuMiAtMTQuNSwyMiAtNC43LDEuOSAtOS41LDMuMSAtMTQuOCwzLjEgLTE2NC4yLC0wLjEgLTMyOC4zLC0wLjEgLTQ5Mi40OTk5OTcsLTAuMSAtMTUuOSwwIC0yNi42LC04LjMgLTI5LjYsLTIyLjggLTAuMywtMS4zIC0wLjYsLTIuNSAtMC4yLC0zLjcgLTAuMiwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuOCwtNi41IC0wLjQsLTEyLjcgNC43LC0xNy42IC02LjIsNC4zIC05Ljk5OTk5OTcsMTQuNCAtOC4yOTk5OTk3LDIyLjUgMy4zOTk5OTk3LDE3LjYgMTYuMTk5OTk5NywyNy43IDM0LjY5OTk5OTcsMjcuNyB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk3NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjQ4NzY2MywyMDAuNjcgYyAwLjIsMC42IDAuMywxLjIgMC41LDEuOCAwLjIsLTAuNSAwLjUsLTEgMS4xLC0xLjQgLTAuNiwtNi4zIDAuNywtMTIuMiAzLjEsLTE4IC01LjEsNC45IC01LjUsMTEuMSAtNC43LDE3LjYgeiBtIDU1MS40OTk5OTcsMC4zIGMgMC4zLDAuOSAwLjUsMS44IDAuNiwyLjggMC4zLC0xIDAuNywtMi4xIDAuOSwtMy4yIDAuOCwtNi41IDAuNCwtMTIuNiAtNC43LC0xNy41IDIuNSw1LjcgMy44LDExLjcgMy4yLDE3LjkgeiBNIDQ0LjI4NzY2MywzOTcuMjcgSCA0NzEuODg3NjYgYyAyMS4xLDAgNDIuMiwwLjEgNjMuMywwIDE4LjMsLTAuMSAzMC4zLC05LjkgMzQsLTI3LjQgMS44LC04LjcgLTIuMywtMTkuMSAtOS4xLC0yMi43IDUsNC41IDYsMTAuNCA1LjYsMTYuNyAtMC4zLDEuMyAtMC42LDIuNSAtMC45LDMuOCAwLjUsOS43IC02LjksMjAuNiAtMTcuMSwyMy43IC0zLjcsMS4xIC03LjUsMS45IC0xMS42LDEuOSAtMTY0LjcsLTAuMSAtMzI5LjQsLTAuMSAtNDk0LjA5OTk5NywtMC4xIC0xNS43LDAgLTI1LjQsLTcuNyAtMjguOCwtMjIuNyAtMC4yLC0wLjkgLTAuNCwtMS44IC0wLjUsLTIuNiAtMC4zLC0xLjMgLTAuNSwtMi43IC0wLjUsLTQuMSAtMC4xLC02LjIgMC43LC0xMi4xIDUuNywtMTYuNSAtNi43LDMuNiAtMTAuODk5OTk5NywxNC4xIC05LjA5OTk5OTcsMjIuNyAzLjc5OTk5OTcsMTcuOSAxNS45OTk5OTk3LDI3LjMgMzUuNDk5OTk5NywyNy4zIHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTc5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjA4NzY2LDM2My44NyBjIDAuNCwxLjIgMC41LDIuNSAwLjYsMy43IDAuMywtMS4yIDAuNywtMi41IDAuOSwtMy44IDAuNCwtNi4zIC0wLjYsLTEyLjIgLTUuNiwtMTYuNyAyLjgsNS4zIDQuNCwxMC44IDQuMSwxNi44IHogbSAtNTUxLjg5OTk5NywtMC4yIGMgMCwxLjQgMC4yLDIuOCAwLjUsNC4xIC0wLjEsLTEuNCAwLC0yLjcgMS4yLC0zLjkgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LjEsNC40IC01LjksMTAuMyAtNS44LDE2LjUgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5ODEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTkuMjg3NjYsNDI4LjA3IGMgMy41LDMgNS4xLDcgNi4yLDExLjMgMCwwLjMgMC4xLDAuNyAwLjEsMSAyLjgsMy4zIDEuMiw3LjYgMC45LDExLjIgLTAuNiw3LjYgLTMuMSwxNC42IC0xMSwxOCAtMS40LDAuOSAtMi44LDEuOSAtNC4xLDIuOCAtNCw0LjQgLTkuNCw0LjIgLTE0LjcsNC4yIEggNDAuNDg3NjYzIGMgLTUsMCAtMTAuMiwwLjEgLTE0LC00LjIgLTYuNCwtNC44IC0xMS41LC0xMC41IC0xMy40LC0xOC42IC0wLjQsLTIgLTEsLTQgLTAuNCwtNS45IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjEsLTEzIDYuNCwtMTcuOCAtNy42LDMuOSAtOS42OTk5OTk3LDExIC0xMC4wOTk5OTk3LDE4LjUgLTEsMTguMiAxMy41OTk5OTk3LDMyLjggMzIuNTk5OTk5NywzMi44IDQ5LjksMC4xIDk5LjY5OTk5NywwIDE0OS41OTk5OTcsMCBoIDM0NC41IGMgMTAuNCwwIDE5LjUsLTMuMSAyNi42LC0xMS4yIDExLjMsLTEyLjUgMTAuMSwtMzIgLTIuNSwtNDAgeiIKICAgICBjbGFzcz0ic3Q1NyIKICAgICBpZD0icGF0aDM5ODUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWNlY2VjIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuNTg3NjYsNDQwLjQ3IGMgMCwtMC4zIC0wLjEsLTAuNyAtMC4xLC0xIC0xLjEsLTQuMyAtMi43LC04LjMgLTYuMiwtMTEuMyAxLjYsMy42IDMuMSw3LjMgNC43LDEwLjkgMC43LDAuNCAxLjIsMC45IDEuNiwxLjQgeiBtIC01NTMuMTk5OTk3LDUuNSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS4zIDEuMSwtMiAtMC40LC02LjUgMS43LC0xMi40IDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IgogICAgIGNsYXNzPSJzdDU3IgogICAgIGlkPSJwYXRoMzk4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlY2VjZWMiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQ0LjE4NzY2MywzMTUuMTcgSCA0MzguMzg3NjYgYyAzMi4yLDAgNjQuNCwwLjIgOTYuNiwtMC4xIDE0LjUsLTAuMSAyNiwtNS41IDMxLjksLTE5LjkgNSwtMTIuMiAyLC0yNS4yIC03LjcsLTMxLjMgMy44LDMuMyA1LjUsNy43IDYuMywxMi41IDAuMSwwLjkgMC4xLDEuOCAwLjEsMi43IDIuOSw3IDAuNSwxNi44IC02LDIyLjIgLTIuOCwyLjMgLTUuNSw0LjYgLTguMyw3IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjI4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtNi44LC01LjEgLTEyLjEsLTExLjEgLTEzLjQsLTE5LjkgLTAuMiwtMS41IC0wLjYsLTMuMSAtMC4zLC00LjUgLTAuMiwtMC43IC0wLjMsLTEuMyAtMC40LC0yIC0wLjQsLTYuMyAwLjYsLTEyLjIgNS42LC0xNi44IC02LjcsMy42IC0xMC44OTk5OTk3LDE0LjEgLTkuMDk5OTk5NywyMi43IDMuNzk5OTk5NywxOCAxNS42OTk5OTk3LDI3LjQgMzUuMjk5OTk5NywyNy40IHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTg5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTIuMzg3NjYzLDI4MS43NyBjIDAuMSwwLjcgMC4zLDEuMyAwLjQsMiAwLjIsLTAuNyAwLjUsLTEuNCAxLjEsLTIgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LDQuNSAtNi4xLDEwLjQgLTUuNiwxNi43IHogbSA1NTMuMzk5OTk3LC0yLjggYyAwLC0wLjkgMCwtMS44IC0wLjEsLTIuNyAtMC44LC00LjggLTIuNSwtOS4yIC02LjMsLTEyLjUgbCA0LjgsMTIuMyBjIDAuNiwxIDEuMSwxLjkgMS42LDIuOSB6IE0gMzIuNTg3NjYzLDY2LjA3IGMgOC41LDEuNyAxNywxLjMgMjUuNiwxLjMgSCA1MzMuMDg3NjYgYyAxMSwwIDIxLC0yLjUgMjguOCwtMTEuMSAxMS4yLC0xMi40IDkuMiwtMzQuOCAtMi41LC00MC4yIDMuNSwzIDUuMSw3IDYuMiwxMS4zIDAuMSwxLjEgMC4yLDIuMiAwLjIsMy4zIDMuMiw5LjMgLTAuNiwyMS40IC04LjgsMjUuNiAtMS44LDEuNCAtMy43LDIuOCAtNS41LDQuMiAtMy43LDMuMyAtOC4xLDQuMiAtMTIuOCw0LjIgSCAzOS40ODc2NjMgYyAtNC43LDAgLTkuMiwtMC45IC0xMi44LC00LjIgLTYuOCwtNS4xIC0xMi4xLC0xMS4xIC0xMy40LC0xOS45IC0wLjIsLTEuNSAtMC42LC0zLjEgLTAuMywtNC41IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjIsLTEzIDYuNCwtMTcuOCAtMi43LDAuNiAtNC4zLDIuNyAtNS43LDQuOCAtMTEuMDk5OTk5NywxNi41IC0wLjIsNDEuMiAxOS40LDQ1LjEgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsMjYuOTcgYyAwLjcsMS4xIDEuMywyLjQgMS43LDMuNiAwLC0xLjEgLTAuMSwtMi4yIC0wLjIsLTMuMyAtMSwtNC4zIC0yLjcsLTguMyAtNi4yLC0xMS4zIDEuNiwzLjcgMy4yLDcuNCA0LjcsMTEgeiBtIC01NTEuNTk5OTk3LDYuOSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS40IDEuMSwtMiAtMC40LC02LjUgMS44LC0xMi4zIDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IG0gMzEuMywxMTUuNiBIIDQwOS43ODc2NiBjIDQxLjgsMCA4My41LDAuMSAxMjUuMywtMC4xIDE0LjUsLTAuMSAyNi4xLC01LjUgMzIsLTE5LjkgNSwtMTIuMiAyLC0yNS4zIC03LjcsLTMxLjQgNS4xLDQuNyA2LjksMTAuNyA2LjQsMTcuNCAtMC4yLDEuNCAtMC41LDIuOCAtMC45LDQuMiAwLjUsNi43IC0yLjUsMTIuMyAtNy4yLDE3LjMgLTEuOSwyIC00LjEsMy43IC02LjEsNS41IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjU4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtMiwtMS4yIC00LjUsLTEuNyAtNS42LC00LjIgLTguMSwtNC4yIC0xMS44OTk5OTk3LC0xNi4yIC04LjgsLTI1LjQgMCwtMS4xIDAsLTIuMyAwLjEsLTMuNCAwLjUsLTQuNyAyLjksLTguMyA2LjQsLTExLjMgLTcuNSw0LjcgLTExLjY5OTk5OTcsMTUuMiAtOS43OTk5OTk3LDI0LjEgMy42OTk5OTk3LDE3LjkgMTUuNDk5OTk5NywyNy4yIDM0LjU5OTk5OTcsMjcuMiB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC4xODc2NiwxMTYuMDcgYyAwLjMsMS4zIDAuNSwyLjUgMC42LDMuNyAwLjQsLTEuNCAwLjcsLTIuNyAwLjksLTQuMiAwLjUsLTYuOCAtMS4zLC0xMi43IC02LjQsLTE3LjQgMy4xLDUuNiA1LjMsMTEuNCA0LjksMTcuOSB6IG0gLTU1MS44OTk5OTcsLTYuNiBjIDAsMS4xIC0wLjEsMi4zIC0wLjEsMy40IDAuNCwtMS4zIDEsLTIuNiAxLjgsLTMuOCAtMC4yLC00LjQgMy4zLC03LjIgNC43LC0xMSAtMy41LDMuMSAtNS45LDYuNyAtNi40LDExLjQgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOS44ODc2NjMsMjI1Ljk3IGMgMS41LDAuNCAzLjIsMC4xIDQuOSwwLjEgSCA1MzMuMzg3NjYgYyA3LjEsMCAxMy44LC0xLjEgMTkuNiwtNS42IDEuMSwtMC44IDEuOSwtMS42IDIuMywtMi43IC0wLjMsMC4yIC0wLjUsMC40IC0wLjgsMC42IC01LjQsNC4xIC0xMS41LDUuNiAtMTguMiw1LjYgSCA0MS45ODc2NjMgYyAtNi43LDAgLTEyLjgsLTEuNSAtMTguMSwtNS41IDMuMyw1LjkgMTAsNi4xIDE2LDcuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQxLjg4NzY2MywyMjMuOTcgSCA1MzYuMTg3NjYgYyA2LjcsMCAxMi44LC0xLjUgMTguMiwtNS42IDAuMywtMC4yIDAuNiwtMC40IDAuOCwtMC42IDAuMiwtMC41IDAuMywtMS4xIDAuMiwtMS44IC03LjIsNC45IC0xNS4xLDYuMSAtMjMuNyw2LjEgLTE2MS44LC0wLjIgLTMyMy42LC0wLjIgLTQ4NS4zOTk5OTcsMCAtOC42LDAgLTE2LjUsLTEuMiAtMjMuNywtNi4xIDAuMywxIDAuNywxLjggMS4yLDIuNiA1LjQsNCAxMS40LDUuNCAxOC4xLDUuNCB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1NS45ODc2NiwyMTcuMTcgYyAwLjIsMC43IDAuMiwxLjMgMCwxLjkgMi43LC0yLjYgNC42LC01LjYgNiwtOS4xIC0xLjUsMi43IC0zLjQsNS4xIC02LDcuMiB6IG0gLTUzMy45OTk5OTcsMCBjIC0yLjQsLTEuOSAtNC4yLC00LjIgLTUuNywtNi43IDEuNCwzLjIgMy4zLDYgNS42LDguNCAtMC4xLC0wLjQgLTAuMSwtMSAwLjEsLTEuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDIxNy4xNyBjIDAuMSwtMC40IDAuMywtMC44IDAuNiwtMS4yIC00LC00LjMgLTYuNywtOS40IC04LjYsLTE1IDAuMywzLjQgMS4xLDYuNiAyLjMsOS41IDEuNSwyLjYgMy40LDQuOCA1LjcsNi43IHogbSA1MzkuOTk5OTk3LC03LjMgYyAxLC0yLjcgMS43LC01LjcgMiwtOC45IC0xLjksNS41IC00LjUsMTAuNiAtOC42LDE1IDAuMywwLjQgMC41LDAuOSAwLjYsMS4yIDIuNiwtMi4xIDQuNSwtNC41IDYsLTcuMyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDIxOS4wNyBjIC0wLjQsMS4yIC0xLjcsMi4xIC0zLDMgLTUuMSwzLjYgLTEwLjcsNS4zIC0xNi45LDUuNCBIIDQ0LjU4NzY2MyBjIC03LjEsMCAtMTMuOCwtMS4yIC0xOS43LC01LjQgLTEuMywtMC45IC0yLjYsLTEuOSAtMywtMy4xIC0yLjQsLTIuNCAtNC4yLC01LjIgLTUuNiwtOC40IC0xLjUsLTIuNSAtMi41LC01LjIgLTMuNCwtOC4xIC0wLjQsMS4xIC0wLjEsMi40IDAuMiwzLjcgMy4xLDE0LjUgMTMuNywyMi44IDI5LjYsMjIuOCAxNjQuMTk5OTk3LDAgMzI4LjI5OTk5NywwIDQ5Mi40OTk5OTcsMC4xIDUuMywwIDEwLjEsLTEuMyAxNC44LC0zLjEgNy4xLC0yLjggMTUuNiwtMTMuMSAxNC41LC0yMiAtMC43LDIuMiAtMS42LDQuMiAtMi42LDYuMSAtMS4yLDMuNCAtMy4yLDYuNCAtNS44LDkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAxOSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAtMC41LDAuNCAtMC45LDAuOSAtMS4xLDEuNCAwLjgsMi45IDEuOSw1LjYgMy40LDguMSAtMS4zLC0yLjggLTIuMSwtNiAtMi4zLC05LjUgeiBtIDU0Ny44OTk5OTcsOC45IGMgMS4xLC0xLjkgMS45LC00IDIuNiwtNi4xIC0wLjEsLTAuOSAtMC4zLC0xLjkgLTAuNiwtMi44IC0wLjMsMy4zIC0xLDYuMiAtMiw4LjkgeiBtIC02LDcuMyBjIC0wLjIsMC4yIC0wLjUsMC40IC0wLjgsMC42IC0wLjQsMS4xIC0xLjIsMS45IC0yLjMsMi43IC01LjgsNC41IC0xMi41LDUuNiAtMTkuNiw1LjYgSCA0NC42ODc2NjMgYyAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjksLTEuNCAtMTIuNywtMS42IC0xNi4xLC03LjQgMCwwIC0wLjEsMCAtMC4xLC0wLjEgLTAuNiwtMC40IC0xLjEsLTAuOCAtMS43LC0xLjMgLTAuMiwwLjcgLTAuMiwxLjIgLTAuMSwxLjcgNC42LDQuNiAxMC44LDcuNSAxOCw3LjkgMi4zLDAuMSA0LjYsMC4xIDcsMC4xIEggNTMwLjk4NzY2IGMgNS4xLDAgMTAuMSwwIDE1LjEsLTEuOCA0LC0xLjUgNy4zLC0zLjUgOS45LC02IDAuMiwtMC42IDAuMywtMS4yIDAsLTEuOSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDIxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNjg3NjYzLDIxOC40NyBjIC0wLjMsLTAuNyAtMC43LC0xLjUgLTEuMSwtMi41IC0wLjMsMC40IC0wLjUsMC45IC0wLjYsMS4yIDAuNiwwLjUgMS4xLDAuOSAxLjcsMS4zIHogbSA1MzEuNTk5OTk3LC0wLjcgYyAwLjMsLTAuMiAwLjUsLTAuNCAwLjgsLTAuNiAtMC4xLC0wLjQgLTAuMywtMC44IC0wLjYsLTEuMiAwLDAuNyAtMC4xLDEuMyAtMC4yLDEuOCB6IG0gLTI0LjIsOS4xIEggNDYuODg3NjYzIGMgLTIuMywwIC00LjYsMC4xIC03LC0wLjEgLTcuMiwtMC40IC0xMy41LC0zLjMgLTE4LC03LjkgMC40LDEuMyAxLjcsMi4yIDMsMy4xIDUuOSw0LjIgMTIuNSw1LjQgMTkuNyw1LjQgMTU0LjU5OTk5NywtMC4xIDMwOS4xOTk5OTcsMCA0NjMuNzk5OTk3LDAgaCAyNy44IGMgNi4yLDAgMTEuOCwtMS44IDE2LjksLTUuNCAxLjMsLTAuOSAyLjYsLTEuOCAzLC0zIC0yLjYsMi41IC01LjksNC41IC05LjksNiAtNSwxLjkgLTEwLDEuOSAtMTUuMSwxLjkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDM4LjQ4NzY2MywxNDIuMzcgYyAyLjQsMC42IDUuMSwwLjEgNy42LDAuMSBIIDUzNC41ODc2NiBjIDUuMywwIDEwLjYsMCAxNS4zLC0yLjkgMC43LC0xIDEuNCwtMi4xIDIuMSwtMy4xIC01LjUsMyAtMTEuNCwzLjkgLTE3LjYsMy45IC0xNjMuOCwtMC4xIC0zMjcuNSwtMC4xIC00OTEuMjk5OTk3LDAgLTcuMSwwIC0xMy41LC0xLjUgLTE5LjYsLTUuMSAzLjMsNS41IDkuNiw1LjggMTUsNy4xIHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDI1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuMjg3NjYzLDE0MC40NyBjIDE2My43OTk5OTcsLTAuMSAzMjcuNDk5OTk3LC0wLjEgNDkxLjI5OTk5NywwIDYuMiwwIDEyLjEsLTAuOCAxNy42LC0zLjkgMC43LC0wLjkgMS4zLC0xLjkgMiwtMi44IC02LjYsMy44IC0xMy44LDQuNyAtMjEuNCw0LjcgLTE2Mi42LC0wLjEgLTMyNS4yLC0wLjEgLTQ4Ny43OTk5OTcsMCAtOC4yLDAgLTE1LjYsLTEuMyAtMjIuNCwtNS44IDAuMywxLjEgMC43LDIgMS4yLDIuOCA1LjksMy42IDEyLjQsNSAxOS41LDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwMjciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NDguOTg3NjYsMTQxLjc3IGMgLTAuNCwwLjMgLTAuOCwwLjUgLTEuMiwwLjggMC4xLC0wLjEgMC4yLC0wLjEgMC40LC0wLjIgMi45LC0xLjggNS41LC0zLjggNy43LC02LjEgLTAuOCwwLjYgLTEuNiwxLjIgLTIuNSwxLjcgLTEuMiwxLjUgLTMuMSwyLjUgLTQuNCwzLjggeiBtIDExLjcsLTEyLjkgYyAtMC4zLDEuMSAtMC43LDIuMiAtMS4yLDMuMSAxLjUsLTIuMiAyLjcsLTQuNiAzLjUsLTcuMiAtMC4yLDAuNSAtMC40LDEgLTAuNiwxLjQgLTAuNiwxIC0xLjIsMS44IC0xLjcsMi43IHogbSAtMTU1LjksMTUuNiBIIDQ1Ljc4NzY2MyBjIC02LjgsMCAtMTMuNSwtMC41IC0xOS40LC00LjMgLTIuNCwtMS41IC01LC0zIC00LjQsLTYuMSAtNCwtMy40IC02LjUsLTcuOCAtOC4yLC0xMi42IC0wLjIsMy45IDEuMSw3LjMgMywxMC41IDEuMywxLjkgMi45LDMuNyA0LjksNS40IDIuNSwxLjggNSwzLjUgNy43LDQuOCA0LjEsMiA4LjQsMi41IDEyLjgsMi41IEggNTM1Ljg4NzY2IGMgMi4xLDAgNC4xLC0wLjEgNi4xLC0wLjUgLTEuOSwwLjIgLTMuOSwwLjIgLTUuOCwwLjIgLTQzLjcsMC4xIC04Ny42LDAuMSAtMTMxLjQsMC4xIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsMTM0LjE3IGMgMC4xLC0wLjUgMC4yLC0xIDAuNSwtMS41IC0zLjksLTQgLTYuMywtOC45IC04LjMsLTEzLjkgLTAuMiwxIC0wLjMsMS45IC0wLjQsMi44IDEuNyw0LjggNC4yLDkuMSA4LjIsMTIuNiB6IG0gNTQwLjI5OTk5NywtNy45IGMgMC4yLC0wLjUgMC40LC0xIDAuNiwtMS40IDAuOCwtMi43IDEuMywtNS41IDEuMiwtOC43IC0xLDMuMiAtMiw2LjQgLTMsOS43IC0wLjEsMS4xIC0wLjMsMi4xIC0wLjUsMy4xIDAuNiwtMSAxLjIsLTEuOCAxLjcsLTIuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU5LjQ4NzY2LDEzMS45NyBjIC0wLjksMS43IC0yLjEsMy4xIC0zLjYsNC40IC0yLjIsMi4yIC00LjgsNC4yIC03LjcsNi4xIC0wLjEsMC4xIC0wLjIsMC4xIC0wLjQsMC4yIC0xLjgsMS4xIC0zLjcsMS41IC01LjcsMS44IC0yLDAuMyAtNCwwLjUgLTYuMSwwLjUgSCA0Mi4yODc2NjMgYyAtNC41LDAgLTguOCwtMC41IC0xMi44LC0yLjUgLTIuNywtMS40IC01LjMsLTMgLTcuNywtNC44IC0yLC0xLjcgLTMuNiwtMy41IC00LjksLTUuNCAxLjMsMi4yIDIuOCw0LjIgNC4zLDYuMyAxLDIuNSAzLjYsMyA1LjYsNC4yIDEyLjQsMy43IDI1LjIsMi44IDM3LjksMi44IEggNTE0LjQ4NzY2IGMgMTIuNCwwIDI1LDAuOSAzNy4yLC0yLjggMi4xLC0xLjggNC4zLC0zLjUgNi4xLC01LjUgNC43LC01IDcuNywtMTAuNiA3LjIsLTE3LjMgLTAuNSwxLjcgLTEuMSwzLjQgLTEuOCw1IC0xLjEsMi40IC0yLjMsNC44IC0zLjcsNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTYyLjg4NzY2LDEyNC43NyBjIDAuNywtMS42IDEuMywtMy4zIDEuOCwtNSAtMC4xLC0xLjIgLTAuMywtMi40IC0wLjYsLTMuNyAwLjEsMy4yIC0wLjQsNi4xIC0xLjIsOC43IHogbSAtOS41LDEzLjMgYyAtMSwwLjYgLTIuMiwxLjIgLTMuNCwxLjcgLTQuOCwyLjggLTEwLDIuOSAtMTUuMywyLjkgLTE2Mi44LC0wLjEgLTMyNS43LDAgLTQ4OC40OTk5OTcsMCAtMi42LDAgLTUuMiwwLjUgLTcuNiwtMC4xIC01LjUsLTEuMyAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4yLC0wLjEgLTAuMywtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjYsMy4xIDIuMSw0LjYgNC40LDYuMSA1LjksMy44IDEyLjUsNC4zIDE5LjQsNC4zIDExOS42OTk5OTcsLTAuMSAyMzkuMjk5OTk3LDAgMzU4Ljk5OTk5NywwIGggMTMxLjUgYyAxLjksMCAzLjksMCA1LjgsLTAuMiAxLjksLTAuMyAzLjgsLTAuOSA1LjcsLTEuOCAwLjQsLTAuMiAwLjgsLTAuNSAxLjIsLTAuOCAxLjIsLTEuMyAzLjEsLTIuMyA0LjMsLTMuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMzg3NjYzLDEzNS4yNyBjIDAuMSwwLjEgMC4yLDAuMSAwLjMsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjIsMC41IC0wLjQsMSAtMC41LDEuNSAwLjUsMC4zIDAuOSwwLjcgMS40LDEuMSB6IG0gNTI0LjM5OTk5Nyw3LjMgYyAtMS44LDAuOSAtMy43LDEuNCAtNS43LDEuOCAyLC0wLjMgMy45LC0wLjggNS43LC0xLjggeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjc4NzY2MywxMTguNTcgYyAwLC0wLjIgLTAuMSwtMC40IC0wLjEsLTAuNSAwLDEuNiAwLjEsMy4xIDAuMyw0LjcgMC4xLC0wLjcgMC4yLC0xLjQgMC41LC0yLjEgLTAuMywtMC43IC0wLjUsLTEuNCAtMC43LC0yLjEgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwMzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi43ODc2NjMsMTE4LjU3IGMgMC4yLDAuNyAwLjQsMS40IDAuNiwyIDAuMiwtMC42IDAuNCwtMS4yIDAuNywtMS45IDAsLTMuMiAtMC4xLC02LjQgLTAuMSwtOS42IC0wLjgsMy4xIC0xLjMsNiAtMS4zLDguOSAwLDAuMiAwLjEsMC40IDAuMSwwLjYgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwNDEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi45ODc2NjMsMTIyLjY3IGMgLTAuMiwtMS41IC0wLjMsLTMuMSAtMC4zLC00LjcgLTAuNCwtMS43IC0wLjUsLTMuNCAtMC41LC01LjEgLTMuMDk5OTk5Nyw5LjIgMC43LDIxLjIgOC44LDI1LjQgLTQuNCwtNC41IC04LjksLTkuMSAtOCwtMTUuNiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA0MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjk4NzY2MywxMDkuMTcgYyAtMC43LDEuMiAtMS4zLDIuNSAtMS44LDMuOCAwLDEuNyAwLjEsMy40IDAuNSw1LjEgMC4xLC0yLjkgMC41LC01LjkgMS4zLC04LjkgeiBtIC0wLjIsMTIuMyAtMC4zLC0wLjkgYyAtMC4yLDAuNyAtMC40LDEuNCAtMC41LDIuMSAwLjUsMy4zIDEuNyw2LjQgMy44LDkuMyAtMS45LC0zLjEgLTMuMiwtNi41IC0zLC0xMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTMuNzg3NjYzLDEyMS40NyBjIDAsLTAuOSAwLjIsLTEuOCAwLjQsLTIuOCAtMC4zLDAuNiAtMC41LDEuMyAtMC43LDEuOSB6IG0gMywxMC42IGMgLTIsLTIuOSAtMy4yLC02IC0zLjgsLTkuMyAtMC45LDYuNSAzLjYsMTEuMSA4LDE1LjcgLTEuNSwtMi4yIC0zLC00LjMgLTQuMiwtNi40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIC0wLjgsMC43IC0xLjYsMS4zIC0yLjQsMS45IDAsMC4zIDAsMC42IC0wLjEsMC44IDAuOCwtMC44IDEuNywtMS43IDIuNSwtMi43IHoiCiAgICAgY2xhc3M9InN0NjMiCiAgICAgaWQ9InBhdGg0MDQ5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NkY2RjZSIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIDEuOCwtMi4zIDMuMywtNC44IDQuNCwtNy42IC0yLjMsMi43IC00LjcsNS40IC03LDguMSAwLjEsMC42IDAuMiwxIDAuMiwxLjUgMC44LC0wLjcgMS42LC0xLjMgMi40LC0yIHogbSAtMi42LDIuOCBjIDAsLTAuMyAwLjEsLTAuNSAwLjEsLTAuOCAtMC42LDAuNCAtMS4xLDAuNyAtMS43LDEuMSAtMC4xLDAuMSAtMC4zLDAuMSAtMC40LDAuMiAtMC43LDEgLTEuNCwyLjEgLTIuMSwzLjEgMS40LC0xLjEgMi44LC0yLjMgNC4xLC0zLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTIuMTg3NjYsMTM2LjY3IGMgMC4xLC0wLjEgMC4zLC0wLjEgMC40LC0wLjIgMC42LC0wLjMgMS4yLC0wLjcgMS43LC0xLjEgMCwtMC41IC0wLjEsLTEgLTAuMiwtMS41IC0wLjYsMC45IC0xLjMsMS44IC0xLjksMi44IHogbSA0LjYsLTMuMyBjIC0wLjgsMSAtMS42LDEuOSAtMi41LDIuOCAtMC4xLDAuNyAtMC40LDEuMyAtMC45LDEuOSAwLjksLTAuNSAxLjcsLTEuMSAyLjUsLTEuNyAxLjQsLTEuNCAyLjYsLTIuOCAzLjYsLTQuNCAwLjUsLTAuOSAwLjksLTIgMS4yLC0zLjEgLTEuMiwxLjYgLTIuNSwzLjIgLTMuOSw0LjUgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjAuNjg3NjYsMTI4Ljg3IGMgMC4zLC0xIDAuNCwtMiAwLjUsLTMuMSAtMS4xLDIuOCAtMi42LDUuNCAtNC40LDcuNiAxLjQsLTEuMyAyLjcsLTIuOSAzLjksLTQuNSB6IG0gLTEuMiwzLjEgYyAtMS4xLDEuNSAtMi4zLDMgLTMuNiw0LjQgMS40LC0xLjMgMi42LC0yLjcgMy42LC00LjQgeiBtIC05LjUsNy43IGMgMS4yLC0wLjUgMi4zLC0xLjEgMy40LC0xLjcgMC40LC0wLjUgMC43LC0xLjIgMC45LC0xLjkgLTEuNCwxLjQgLTIuOCwyLjYgLTQuMywzLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyOC4yODc2NjMsMzg3Ljg3IGMgMiwxLjEgNC4yLDEuOSA2LjUsMi41IEggNTQwLjI4NzY2IGMgNSwtMS45IDExLjIsLTIgMTQuMSwtNy4yIC02LjIsMy44IC0xMi45LDUuMSAtMjAuMiw1LjEgLTE2My41LC0wLjEgLTMyNy4xLC0wLjEgLTQ5MC41OTk5OTcsMCAtNi40LDAgLTEyLjUsLTAuNiAtMTguMSwtNCAtMC4xLC0wLjEgLTAuMiwtMC4xIC0wLjMsLTAuMiAxLDEuMSAyLjIsMiAyLjcsMy40IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjUuNTg3NjYzLDM4NC4yNyBjIDUuNiwzLjQgMTEuNyw0IDE4LjEsNCAxNjMuNDk5OTk3LC0wLjEgMzI3LjA5OTk5NywtMC4xIDQ5MC41OTk5OTcsMCA3LjMsMCAxNCwtMS40IDIwLjIsLTUuMSAwLjUsLTAuOCAwLjgsLTEuNyAxLjEsLTIuOCAtNi41LDQuNiAtMTMuNyw1LjkgLTIxLjYsNS45IC0xNjMuMSwtMC4xIC0zMjYuMiwtMC4xIC00ODkuMTk5OTk3LDAgLTcuNCwwIC0xNC4zLC0wLjkgLTIwLjYsLTQuNyAwLjEsMS4xIDAuNywxLjggMS4zLDIuNiAtMC4xLDAgMCwwLjEgMC4xLDAuMSB6IG0gOS4yLDYuMSBjIC0yLjMsLTAuNiAtNC41LC0xLjQgLTYuNSwtMi41IDEuOCwyIDQuMSwyLjQgNi41LDIuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgYyAwLjcsMi4xIDEuNyw0LjEgMi45LDUuOSAtMC42LC0xLjEgLTEuMSwtMi4zIC0xLjUsLTMuNSAtMC41LC0wLjggLTAuOSwtMS42IC0xLjQsLTIuNCB6IG0gNTQxLjA5OTk5Nyw5LjEgYyAwLjEsMC41IDAuMiwxIDAuMSwxLjQgMi41LC0yLjUgNC41LC01LjQgNS44LC04LjcgLTEuNSwyLjYgLTMuNCw1LjEgLTUuOSw3LjMgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgMS41LDIuNCBjIC0wLjQsLTEuNCAtMC43LC0yLjkgLTAuOSwtNC41IC0xLjksLTEuOSAtMC41LC00LjcgLTEuNiwtNi44IC0wLjQsMy4xIDAsNiAxLDguOSB6IG0gNTQ2Ljk5OTk5NywxLjcgYyAxLjMsLTMuMiAyLjEsLTYuOCAyLjEsLTEwLjYgLTEuOCw2IC00LjEsMTEuOCAtOC42LDE2LjUgMC4zLDAuNSAwLjUsMSAwLjYsMS41IDIuNSwtMi4yIDQuNCwtNC43IDUuOSwtNy40IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTYuMTg3NjYsMzgzLjI3IGMgLTAuMywxLjkgLTIuMywzLjEgLTQsNC4xIC00LjIsMi41IC04LjcsNCAtMTMuNyw0LjMgaCAtMC42IGMgLTEuNCwwLjMgLTIuOCwwLjEgLTQuMiwwIEggNDQuMDg3NjYzIGMgLTEuMywwLjEgLTIuNywwLjMgLTQsMCBoIC0wLjYgYyAtNC4xLC0wLjMgLTguMiwtMC4zIC0xMS44LC0yLjcgLTEsLTEuMiAtMi41LC0yLjIgLTMuNCwtMy40IC0yLjgsLTEuOCAtNSwtNC4xIC02LjUsLTYuOSAtMS4zLC0xLjkgLTIuMiwtMy45IC0yLjksLTUuOSAtMC4zLC0wLjUgLTAuNiwtMC45IC0wLjgsLTEuNCAtMC43LC0xLjEgLTEuMiwtMi4zIC0xLjUsLTMuNSAwLjEsMC45IDAuMywxLjcgMC41LDIuNiAzLjUsMTQuOSAxMy4yLDIyLjYgMjguOSwyMi42IDE2NC42OTk5OTcsMCAzMjkuMzk5OTk3LDAgNDk0LjA5OTk5NywwLjEgNCwwIDcuOSwtMC44IDExLjYsLTEuOSAxMC4yLC0zLjEgMTcuNiwtMTQuMSAxNy4xLC0yMy43IC0wLjcsMi40IC0xLjYsNC43IC0yLjcsNi45IC0xLjQsMy4zIC0zLjQsNi4zIC01LjksOC44IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjEuOTg3NjYsMzc0LjQ3IGMgMS4yLC0yLjEgMiwtNC41IDIuNywtNi45IC0wLjEsLTEuMyAtMC4zLC0yLjUgLTAuNiwtMy43IDAsMy44IC0wLjgsNy40IC0yLjEsMTAuNiB6IG0gLTU0Ni45OTk5OTcsLTEuNyBjIC0wLjksLTIuOCAtMS40LC01LjggLTEuMSwtOC45IC0xLjEsMS4yIC0xLjMsMi42IC0xLjIsMy45IDAuMywxLjIgMC43LDIuNCAxLjUsMy41IDAuMiwwLjUgMC41LDEgMC44LDEuNSB6IG0gMTEsMTMuOCBjIDAuOCwwLjUgMS41LDAuOSAyLjMsMS40IGwgLTAuMywtMC4zIGMgLTAuNywtMC40IC0xLjQsLTAuOCAtMiwtMS4xIHogbSA1MzAuMDk5OTk3LC00LjcgYyAtMC40LDAuNCAtMC45LDAuOCAtMS40LDEuMiAtMC4xLDAuMSAtMC4yLDAuMSAtMC4zLDAuMiAtMi45LDUuMiAtOS4xLDUuMyAtMTQuMSw3LjIgbCAtMC42LDAuNiBjIDEuNCwtMC4xIDIuOCwtMC40IDQuMiwtMC43IDQuOSwtMS4zIDkuMSwtMy43IDEyLjQsLTcgMCwtMC42IC0wLjEsLTEgLTAuMiwtMS41IHogbSAtNTIxLjI5OTk5Nyw4LjUgYyAxLjIsMC4zIDIuNCwwLjUgMy42LDAuNiAtMC4yLC0wLjIgLTAuNSwtMC40IC0wLjcsLTAuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0Ljc4NzY2LDM4Mi45NyBjIDAuNSwtMC40IDAuOSwtMC44IDEuNCwtMS4yIC0wLjEsLTAuNSAtMC4zLC0wLjkgLTAuNiwtMS41IC0wLjMsMS4xIC0wLjYsMiAtMS4xLDIuOCAwLDAgMC4xLDAgMC4zLC0wLjEgeiBtIC01MDkuNzk5OTk3LDguNyBoIC0wLjggNDg5LjU5OTk5NyAtMC42IGMgLTE2Mi44LDAuMSAtMzI1LjUsMC4xIC00ODguMTk5OTk3LDAgeiBtIDQ5NC42OTk5OTcsLTAuOCBjIC0wLjUsMC40IC0xLjEsMC43IC0xLjcsMC44IGggMC42IGMgNC45LC0wLjMgOS41LC0xLjggMTMuNywtNC4zIDEuOCwtMS4xIDMuOCwtMi4yIDQsLTQuMSAtMy4zLDMuMyAtNy41LDUuNyAtMTIuNCw3IC0xLjUsMC4zIC0yLjksMC41IC00LjIsMC42IHogbSAtNTA0Ljg5OTk5NywtMC41IGMgLTIuNCwtMC4xIC00LjcsLTAuNSAtNi41LC0yLjUgLTAuOCwtMC40IC0xLjYsLTAuOSAtMi4zLC0xLjQgbCAtMS41LC0wLjkgYyAwLjksMS4yIDIuNCwyLjIgMy40LDMuNCAzLjYsMi40IDcuNywyLjQgMTEuOCwyLjcgaCAwLjYgYyAtMC42LC0wLjEgLTEuMiwtMC40IC0xLjcsLTAuOCAtMS40LDAgLTIuNiwtMC4zIC0zLjgsLTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIC0wLjgsLTAuNSAtMS41LC0xLjEgLTIuMSwtMS43IDAuNywwLjggMS40LDEuNiAyLjIsMi4zIC0wLjEsLTAuMSAtMC4xLC0wLjMgLTAuMSwtMC42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIDAsLTAuNSAwLjEsLTEgMC40LC0xLjYgLTMuNCwtMy4xIC02LC02LjkgLTguNSwtMTAuOSAxLjMsNC4xIDMuMyw3LjYgNiwxMC43IDAuNywwLjcgMS40LDEuMyAyLjEsMS44IHogbSA0LjQsNC41IGMgLTAuNSwtMS40IC0xLjcsLTIuMyAtMi43LC0zLjQgLTAuNiwtMC4zIC0xLjEsLTAuNiAtMS42LC0xIHYgMC42IGMgMS4zLDEuMyAyLjgsMi42IDQuMywzLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNS4yODc2NjMsMzg0LjA3IGMgLTAuNiwtMC43IC0xLjIsLTEuNSAtMS4zLC0yLjYgLTAuMiwwLjYgLTAuMywxLjEgLTAuNCwxLjYgMC42LDAuNCAxLjEsMC43IDEuNywxIHogbSAtMSwxLjMgYyAtMC4zLC0wLjUgLTAuNSwtMSAtMC42LC0xLjYgLTAuOCwtMC44IC0xLjUsLTEuNSAtMi4yLC0yLjMgLTIsLTEuOCAtMy42LC0zLjkgLTUuMSwtNi4yIDAuNCwxLjMgMC45LDIuNCAxLjUsMy41IDEuNywyLjQgMy45LDQuNyA2LjQsNi42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDc1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuNDg3NjYzLDM4MS4zNyBjIC0yLjYsLTMuMSAtNC43LC02LjYgLTYsLTEwLjcgMC4yLDEuNiAwLjUsMy4xIDAuOSw0LjUgMS41LDIuMyAzLjEsNC40IDUuMSw2LjIgeiBtIC0zLjYsLTIuNyBjIDEuNSwyLjggMy43LDUuMSA2LjUsNi45IC0wLjEsLTAuMSAtMC4xLC0wLjIgLTAuMiwtMC4zIC0yLjQsLTEuOCAtNC42LC00LjEgLTYuMywtNi42IHogbSA1LjgsNS4xIGMgMC4xLDAuNiAwLjMsMS4xIDAuNiwxLjYgMC42LDAuNCAxLjEsMC44IDEuNywxLjIgMC43LDAuNCAxLjMsMC43IDIsMSAtMS41LC0xLjIgLTMsLTIuNSAtNC4zLC0zLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNC4yODc2NjMsMzg1LjM3IGMgMC4xLDAuMSAwLjEsMC4yIDAuMiwwLjMgbCAxLjUsMC45IGMgLTAuNiwtMC40IC0xLjIsLTAuOCAtMS43LC0xLjIgeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOC40ODc2NjMsNjAuMjcgYyAxLjUsMC40IDMuMiwwLjEgNC45LDAuMSAxNjMuNzk5OTk3LDAgMzI3LjQ5OTk5NywwIDQ5MS4yOTk5OTcsMC4xIDYsMCAxMS40LC0xLjMgMTYuNiwtNC4yIDEuNiwtMC45IDMuMSwtMS45IDMuOCwtMy41IC0wLjEsMC4xIC0wLjMsMC4yIC0wLjQsMC4zIC02LjMsMy45IC0xMy4xLDUuMyAtMjAuNSw1LjMgLTE2My40LC0wLjEgLTMyNi45LC0wLjEgLTQ5MC4yOTk5OTcsMCAtNy4zLDAgLTE0LC0xLjMgLTIwLjEsLTUuMSAzLDUuMyA5LjMsNS42IDE0LjcsNyB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA4MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQzLjc4NzY2Myw1OC4zNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjYgMC41LC0xLjQgMC41LC0yLjIgLTYuOCw0LjYgLTE0LjIsNS44IC0yMi40LDUuOCAtMTYyLjgsLTAuMSAtMzI1LjUsLTAuMSAtNDg4LjI5OTk5NywwIC04LjIsMCAtMTUuNiwtMS4zIC0yMi40LC01LjggMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuMywzLjcgMTMsNSAyMC4yLDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwODMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsNTEuODcgYyAtMi45LC0yLjUgLTUuMSwtNS41IC02LjYsLTguOCAxLjQsNC4yIDMuNyw3LjggNi45LDExIC0wLjQsLTAuNiAtMC41LC0xLjMgLTAuMywtMi4yIHogbSA1MTAuMTk5OTk3LDEwLjUgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjI5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzUuNzg3NjYgYyA0LjUsMCA4LjgsLTAuNSAxMi44LC0yLjUgMS40LC0wLjcgMi43LC0xLjcgNCwtMi43IC0zLjksMi45IC04LjUsNC40IC0xMy40LDQuOCAtMi40LDAuMiAtNC43LDAuMSAtNywwLjEgeiBtIDMyLjEsLTIzIGMgLTEuNyw0LjggLTQuMiw5LjIgLTguMiwxMi42IDAuNCwxLjkgLTAuNiwzLjIgLTEuOSw0LjMgMC42LC0wLjUgMS4zLC0wLjkgMiwtMS4zIDIuNCwtMS43IDQuMywtMy44IDUuOCwtNi4yIDEuNSwtMi45IDIuNCwtNiAyLjMsLTkuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDg1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDUxLjg3IGMgMC4xLC0wLjQgMC4zLC0wLjkgMC41LC0xLjQgLTQuNSwtNC43IC03LjIsLTEwLjMgLTguNiwtMTYuNSAwLDMuMyAwLjUsNi40IDEuNCw5LjIgMS42LDMuMyAzLjgsNi4yIDYuNyw4LjcgeiBNIDU2NC4yODc2NiwzOS4zNyBjIDAsLTAuOSAtMC4yLC0xLjggLTAuNCwtMi44IC0yLjEsNS4xIC00LjQsMTAgLTguMywxMy45IDAuMywwLjUgMC41LDEgMC42LDEuNCAzLjksLTMuNCA2LjMsLTcuNyA4LjEsLTEyLjUgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1Ni4xODc2Niw1NC44NyBjIC0wLjcsMC40IC0xLjMsMC44IC0yLDEuMyAtMC41LDAuNCAtMSwwLjggLTEuNSwxLjEgbCAtMC4xLDAuMSBjIC0xLjMsMSAtMi41LDEuOSAtNCwyLjcgLTQsMiAtOC4zLDIuNSAtMTIuOCwyLjUgSCA0MS45ODc2NjMgYyAtNC4yLDAgLTguMywtMC41IC0xMi4yLC0yLjQgLTAuOSwtMC42IC0xLjcsLTEuMSAtMi41LC0xLjcgLTAuNiwtMC40IC0xLjMsLTAuOCAtMS45LC0xLjIgLTEuMywtMC45IC0yLjYsLTEuOSAtMy4zLC0zLjEgLTMuMSwtMy4yIC01LjUsLTYuOCAtNi45LC0xMSAtMS4xLC0yLjIgLTEuOSwtNC42IC0yLjUsLTcuMiAtMC4zLDEuNCAwLjEsMyAwLjMsNC41IDEuMyw4LjggNi42LDE0LjkgMTMuNCwxOS45IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjM4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjgsLTEuNCAzLjcsLTIuOCA1LjUsLTQuMiAxLjgsLTIuNCAzLjYsLTQuOSA1LC03LjUgLTEuMywyLjQgLTMuMiw0LjUgLTUuNiw2LjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIC0wLjYsMC42IC0wLjksMS4zIC0xLjEsMiAwLjYsMi41IDEuNCw0LjkgMi41LDcuMiAtMC45LC0yLjggLTEuNCwtNS45IC0xLjQsLTkuMiB6IG0gNTQyLjE5OTk5NywxNy45IGMgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy41LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjUsLTEuNCAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC45IC0wLjEsMS42IDAuMiwyLjIgMS41LDEuNiAzLjMsMyA1LjEsNC40IDUuNiwzLjQgMTIsMy45IDE4LjYsMy45IDE2Mi4wOTk5OTcsLTAuMSAzMjQuMTk5OTk3LC0wLjEgNDg2LjI5OTk5NywtMC4xIDIuMywwIDQuNiwwLjEgNywtMC4xIDQuOSwtMC40IDkuNSwtMS45IDEzLjQsLTQuOCAwLjUsLTAuNCAxLjEsLTAuOCAxLjYsLTEuMiAxLjQsLTEgMi40LC0yLjMgMiwtNC4yIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwOTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMy4yODc2NjMsNTMuMDcgYyAwLjEsMC4xIDAuMywwLjEgMC40LDAuMiAtMC41LC0wLjggLTAuOSwtMS43IC0xLjIsLTIuOCAtMC4zLDAuNSAtMC40LDEgLTAuNSwxLjQgMC40LDAuNCAwLjgsMC44IDEuMywxLjIgeiBtIDUzMi43OTk5OTcsLTEuMiBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjUsMi4yIDAuNSwtMC4yIDAuOCwtMC41IDEuMSwtMC44IHogbSAtMy40LDUuNSBjIDAuNSwtMC40IDEsLTAuNyAxLjUsLTEuMSAtMC42LDAuNCAtMS4xLDAuOCAtMS42LDEuMiAwLC0wLjEgMCwtMC4xIDAuMSwtMC4xIHogTSAyNS4zODc2NjMsNTcuMjcgYyAwLjYsMC41IDEuMiwwLjkgMS45LDEuMiAtMS45LC0xLjQgLTMuNiwtMi44IC01LjEsLTQuNCAwLjYsMS4zIDIsMi4zIDMuMiwzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC41ODc2NiwzOC40NyBjIDAuMiwwLjYgMC4zLDEuMiAwLjQsMS44IDAuMiwtMS40IDAuMywtMi45IDAuMywtNC40IDAsMC4yIDAsMC4zIC0wLjEsMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDk1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDM4LjQ3IGMgMC4yLC0wLjcgMC41LC0xLjQgMC43LC0yLjEgMCwtMC4yIDAsLTAuMyAwLjEsLTAuNSAwLC0yLjggLTAuNCwtNS44IC0xLjMsLTguOSAwLDMuMiAtMC4xLDYuNCAtMC4xLDkuNiAwLjIsMC43IDAuNCwxLjMgMC42LDEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAsMS41IC0wLjEsMyAtMC4zLDQuNCAxLjEsNi42IC0zLjUsMTEuMyAtOCwxNS45IDguMiwtNC4yIDEyLC0xNi4zIDguOCwtMjUuNiAwLDEuOCAtMC4xLDMuNiAtMC41LDUuMyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAuNCwtMS44IDAuNSwtMy41IDAuNCwtNS4zIC0wLjQsLTEuMyAtMSwtMi41IC0xLjcsLTMuNiAwLjksMy4xIDEuMyw2LjEgMS4zLDguOSB6IG0gLTEsMy41IGMgMC4yLDMuNSAtMC44LDYuNSAtMi4zLDkuNCAxLjUsLTIuNSAyLjYsLTUuMyAzLC04LjQgLTAuMSwtMC42IC0wLjIsLTEuMiAtMC40LC0xLjggLTAuMSwwLjIgLTAuMiwwLjUgLTAuMywwLjggeiBtIC0wLjQsLTIuOCBjIDAuMiwwLjkgMC4zLDEuOSAwLjQsMi44IGwgMC4zLC0wLjkgYyAtMC4yLC0wLjYgLTAuNCwtMS4yIC0wLjcsLTEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEwMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC45ODc2Niw0MC4yNyBjIC0wLjUsMy4xIC0xLjUsNS45IC0zLDguNCAtMS40LDIuNiAtMy4yLDUgLTUsNy41IDQuNSwtNC42IDksLTkuMyA4LC0xNS45IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTAzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDMwOC4wNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTQsLTEuMyAtMjAuMSwtNS4xIDMsNS4zIDkuMyw1LjYgMTQuNyw3IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MTA1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuODg3NjYzLDMwNi4xNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjcgMC41LC0xLjQgMC40LC0yLjMgLTYuNiw0LjQgLTEzLjcsNS45IC0yMS43LDUuOSAtMTYzLjIsLTAuMSAtMzI2LjUsLTAuMSAtNDg5LjY5OTk5NywwIC04LDAgLTE1LjEsLTEuNSAtMjEuNywtNS45IDAuMywxLjEgMC43LDIgMS4yLDIuOCA2LjMsMy44IDEzLDUuMSAyMC4zLDUuMSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDEwNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDUzMi4xODc2NiwzMTAuMTcgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjM5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzYuMDg3NjYgYyA0LjMsMCA4LjMsLTAuNiAxMi4xLC0yLjQgMS42LC0wLjggMywtMS44IDQuMywtMi45IC00LDIuOSAtOC42LDQuNSAtMTMuNSw0LjkgLTIuMSwwLjIgLTQuNSwwLjEgLTYuOCwwLjEgeiBtIDIzLjksLTEwLjUgYyAwLjQsMS42IC0wLjMsMi43IC0xLjMsMy43IDEuMywtMS4xIDIuNiwtMi4zIDQsLTMuNSAxLjUsLTEuNCAyLjcsLTIuOSAzLjcsLTQuNSAxLjEsLTIuNiAxLjksLTUuMyAxLjgsLTguMiAtMS44LDQuOCAtNC4yLDkuMiAtOC4yLDEyLjUgeiBtIC01MzQuMTk5OTk3LDAgYyAtMi45LC0yLjUgLTUsLTUuNSAtNi42LC04LjggMS40LDQuMiAzLjcsNy44IDYuOCwxMSAtMC4yLC0wLjYgLTAuMywtMS4zIC0wLjIsLTIuMiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTA5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjE4NzY2LDI4Ny4yNyBjIDAsLTAuOSAtMC4xLC0xLjkgLTAuNCwtMi45IC0yLDUuMSAtNC41LDkuOSAtOC4zLDEzLjkgMC4zLDAuNSAwLjUsMSAwLjYsMS40IDQsLTMuMyA2LjQsLTcuNyA4LjEsLTEyLjQgeiBtIC01NDIuMjk5OTk3LDEyLjQgYyAwLjEsLTAuNCAwLjMsLTAuOSAwLjYsLTEuNCAtNC40LC00LjcgLTcuMywtMTAuMiAtOC42LC0xNi41IDAsMy4zIDAuNSw2LjQgMS40LDkuMiAxLjYsMy4yIDMuNyw2LjIgNi42LDguNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTExIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU4Ljc4NzY2LDI5OS45NyBjIC0xLjMsMS4yIC0yLjYsMi4zIC00LDMuNSAtMC41LDAuNSAtMS4xLDEgLTEuNywxLjQgLTAuMSwwLjEgLTAuMiwwLjIgLTAuNCwwLjMgLTEuNCwxLjEgLTIuOCwyLjEgLTQuMywyLjkgLTMuOCwxLjggLTcuOSwyLjQgLTEyLjEsMi40IEggNDIuMDg3NjYzIGMgLTQuMiwwIC04LjMsLTAuNSAtMTIuMiwtMi40IC0wLjksLTAuNiAtMS43LC0xLjEgLTIuNSwtMS43IC0wLjYsLTAuNCAtMS4zLC0wLjggLTEuOSwtMS4zIC0xLjIsLTAuOSAtMi42LC0xLjkgLTMuMiwtMy4xIC0zLjEsLTMuMiAtNS41LC02LjggLTYuOCwtMTEgLTEuMSwtMi4zIC0xLjksLTQuNiAtMi41LC03LjIgLTAuMywxLjQgMC4xLDMgMC4zLDQuNSAxLjMsOC44IDYuNiwxNC45IDEzLjQsMTkuOSAxMi4yLDMuNyAyNC43LDIuOCAzNy4yLDIuOCBIIDUxMy42ODc2NiBjIDEyLjcsMCAyNS40LDAuOSAzNy45LC0yLjggMi44LC0yLjMgNS41LC00LjYgOC4zLC03IDAuOSwtMS45IDEuOSwtMy44IDIuNywtNS44IC0xLjEsMS43IC0yLjMsMy4yIC0zLjgsNC42IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsMjgxLjc3IGMgLTAuNiwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNiwyLjUgMS40LDQuOSAyLjUsNy4yIC0wLjksLTIuOCAtMS40LC01LjkgLTEuNCwtOS4yIHogbSA1NDIuMTk5OTk3LDE3LjkgYyAtMC4zLDAuMyAtMC43LDAuNiAtMSwwLjggLTAuNywxLjYgLTIuMiwyLjYgLTMuOCwzLjUgLTUuMiwyLjkgLTEwLjYsNC4yIC0xNi42LDQuMiAtMTYzLjgsLTAuMSAtMzI3LjYsLTAuMSAtNDkxLjI5OTk5NywtMC4xIC0xLjYsMCAtMy4zLDAuMyAtNC45LC0wLjEgLTUuNCwtMS41IC0xMS43LC0xLjcgLTE0LjgsLTcgLTAuMSwtMC4xIC0wLjMsLTAuMSAtMC40LC0wLjIgLTAuNSwtMC40IC0wLjksLTAuOCAtMS40LC0xLjIgLTAuMiwwLjggLTAuMSwxLjYgMC4yLDIuMiAxLjUsMS42IDMuMywzIDUuMSw0LjQgNS42LDMuNCAxMiwzLjkgMTguNiwzLjkgMTYyLjA5OTk5NywtMC4xIDMyNC4xOTk5OTcsLTAuMSA0ODYuMzk5OTk3LC0wLjEgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNiwtMiAxMy41LC00LjkgMC4xLC0wLjEgMC4yLC0wLjIgMC40LC0wLjMgMC42LC0wLjUgMS4xLC0wLjkgMS43LC0xLjQgMSwtMC44IDEuNywtMiAxLjMsLTMuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDI5OS42NyBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjQsMi4zIDAuMywtMC4zIDAuNywtMC42IDEsLTAuOSB6IG0gLTUzMi43OTk5OTcsMS4yIGMgMC4xLDAuMSAwLjMsMC4xIDAuNCwwLjIgLTAuNSwtMC44IC0wLjksLTEuOCAtMS4yLC0yLjggLTAuMywwLjUgLTAuNSwxIC0wLjYsMS40IDAuNSwwLjQgMC45LDAuOCAxLjQsMS4yIHogbSAyLjEsNC4yIGMgMC42LDAuNSAxLjMsMC45IDEuOSwxLjMgLTEuOSwtMS40IC0zLjYsLTIuOCAtNS4xLC00LjQgMC42LDEuMiAyLDIuMSAzLjIsMy4xIHogbSA1MjkuMzk5OTk3LC0xLjYgYyAtMC42LDAuNSAtMS4xLDAuOSAtMS43LDEuNCAwLjYsLTAuNSAxLjIsLTAuOSAxLjcsLTEuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDI4Ni4wNyBjIDAuMiwwLjYgMC40LDEuMiAwLjUsMS44IDAuMiwtMS40IDAuMiwtMi44IDAuMiwtNC4yIDAsMC4yIC0wLjEsMC40IC0wLjEsMC42IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTE5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjE4NzY2LDI4NC4yNyBjIDAuMSwtMC4yIDAuMSwtMC40IDAuMSwtMC42IC0wLjEsLTIuNCAtMC41LC00LjkgLTEuMiwtNy40IGwgLTAuMyw4LjEgYyAwLjMsMC42IDAuNiwxLjEgMC44LDEuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4xODc2NiwyODcuODcgYyAwLjksNS4xIC0yLjQsOS4yIC01LjQsMTMuNCA2LjUsLTUuNSA4LjksLTE1LjIgNiwtMjIuMiAwLDEuNSAtMC4xLDMuMSAtMC40LDQuNiAwLDEuNCAtMC4xLDIuOCAtMC4yLDQuMiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwyODMuNTcgYyAwLjMsLTEuNSAwLjQsLTMuMSAwLjQsLTQuNiAtMC40LC0xIC0xLC0yIC0xLjYsLTIuOCAwLjcsMi42IDEuMSw1IDEuMiw3LjQgeiBtIC0xLjEsMy43IGMgMC4xLDIuOSAtMC43LDUuNiAtMS44LDguMiAxLjUsLTIuNCAyLjMsLTUgMi43LC03LjYgLTAuMSwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuMSwwLjQgLTAuMiwwLjggLTAuNCwxLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxMjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjQuNTg3NjYsMjg2LjA3IGMgLTAuMiwtMC42IC0wLjQsLTEuMSAtMC44LC0xLjcgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAuMiwtMC40IDAuMywtMC44IDAuNCwtMS4yIHogbSAwLjYsMS44IGMgLTAuNCwyLjcgLTEuMiw1LjIgLTIuNyw3LjYgLTAuOCwxLjkgLTEuOCwzLjggLTIuNyw1LjggMi45LC00LjIgNi4zLC04LjMgNS40LC0xMy40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTI3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDQ3Mi4zNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTMuOSwtMS4zIC0yMC4xLC01LjEgMyw1LjMgOS4zLDUuNSAxNC43LDcgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA0My43ODc2NjMsNDcwLjQ3IGMgMTYzLjM5OTk5NywtMC4xIDMyNi44OTk5OTcsLTAuMSA0OTAuMjk5OTk3LDAgNy40LDAgMTQuMiwtMS40IDIwLjUsLTUuMyAwLjEsLTAuMSAwLjMsLTAuMiAwLjQsLTAuMyAwLjMsLTAuNyAwLjUsLTEuNCAwLjQsLTIuMyAtNi42LDQuNCAtMTMuNyw1LjkgLTIxLjcsNS45IC0xNjMuMiwtMC4xIC0zMjYuNSwtMC4xIC00ODkuNjk5OTk3LDAgLTgsMCAtMTUuMSwtMS41IC0yMS43LC01LjkgMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuNCwzLjcgMTMuMSw1LjEgMjAuMyw1LjEgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMzEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS44ODc2NjMsNDYzLjk3IGMgLTMuMSwtMi43IC01LjQsLTYgLTcsLTkuNiAxLjQsNC41IDMuOSw4LjMgNy4yLDExLjcgLTAuMiwtMC42IC0wLjMsLTEuMyAtMC4yLC0yLjEgeiBtIDU0Mi4yOTk5OTcsLTEyLjUgYyAtMS43LDQuOCAtNC4yLDkuMSAtOC4xLDEyLjUgMC42LDIuNSAtMS41LDQgLTMuMyw1LjQgLTQsMi45IC04LjYsNC41IC0xMy42LDQuOSAtMi4zLDAuMiAtNC42LDAuMSAtNywwLjEgLTE2Mi4xLDAgLTMyNC4zLDAgLTQ4Ni4zOTk5OTcsMC4xIC03LDAgLTEzLjcsLTAuNiAtMTkuNSwtNC41IDEuMSwwLjkgMi4yLDEuOCAzLjQsMi43IDQuMiwxLjcgOC41LDIuMSAxMywyLjEgSCA1MzUuMjg3NjYgYyA0LjcsMCA5LjIsLTAuNSAxMy42LC0yLjMgMS45LC0xLjQgMy43LC0yLjkgNS44LC00IDIuNywtMS42IDQuOSwtMy44IDYuNiwtNi41IDEuOSwtMy4yIDMuMSwtNi42IDIuOSwtMTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuODg3NjYzLDQ2My45NyBjIDAuMSwtMC40IDAuMywtMC45IDAuNiwtMS40IC00LjQsLTQuNyAtNy4zLC0xMC4yIC04LjYsLTE2LjUgLTAuMSwzLjEgMC4zLDUuOCAxLjEsOC40IDEuNiwzLjYgMy44LDYuOCA2LjksOS41IHogbSA1NDIuMjk5OTk3LC0xMi41IGMgMCwtMC45IC0wLjIsLTEuOSAtMC40LC0yLjkgLTIsNS4xIC00LjUsOS45IC04LjMsMTMuOSAwLjMsMC41IDAuNSwxIDAuNiwxLjQgNCwtMy4zIDYuNCwtNy42IDguMSwtMTIuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0LjY4NzY2LDQ2OC40NyBjIC0yLjEsMS4xIC0zLjksMi42IC01LjgsNCAtNC4zLDEuOCAtOC45LDIuMyAtMTMuNiwyLjMgSCA0Mi42ODc2NjMgYyAtNC41LDAgLTguOCwtMC40IC0xMywtMi4xIC0xLjIsLTAuOSAtMi4zLC0xLjcgLTMuNCwtMi43IC0wLjMsLTAuMiAtMC42LC0wLjQgLTAuOSwtMC43IC0xLjMsLTEgLTIuNywtMS45IC0zLjMsLTMuMiAtMy4zLC0zLjQgLTUuOCwtNy4yIC03LjIsLTExLjcgLTAuOSwtMiAtMS42LC00LjIgLTIuMSwtNi40IC0wLjYsMS45IC0wLjEsMy45IDAuNCw1LjkgMS44LDguMSA3LDEzLjggMTMuNCwxOC42IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjU4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjQsLTAuOSAyLjgsLTEuOSA0LjEsLTIuOCAyLC0yLjUgNC4xLC01IDUuNywtNy43IC0xLjcsMi42IC0zLjksNC44IC02LjYsNi41IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsNDQ2LjA3IGMgLTAuNSwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNSwyLjIgMS4yLDQuNCAyLjEsNi40IC0wLjcsLTIuNiAtMS4xLC01LjQgLTEsLTguNCB6IG0gNTE4LjM5OTk5NywyOC40IGMgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNSwtMiAxMy42LC00LjkgMS45LC0xLjQgMy45LC0yLjkgMy4zLC01LjQgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy42LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjQsLTEuNSAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC44IC0wLjEsMS41IDAuMiwyLjEgMS4zLDEuNCAyLjcsMi42IDQuMiwzLjkgNS45LDMuOSAxMi41LDQuNSAxOS41LDQuNSAxNjIuMDk5OTk3LC0wLjEgMzI0LjE5OTk5NywwIDQ4Ni4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMjg3NjYzLDQ2NS4xNyBjIDAuMSwwLjEgMC4zLDAuMSAwLjQsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjMsMC41IC0wLjUsMSAtMC42LDEuNCAwLjUsMC40IDAuOSwwLjggMS40LDEuMiB6IG0gNTMyLjc5OTk5NywtMS4yIGMgLTAuMSwtMC40IC0wLjMsLTAuOSAtMC42LC0xLjQgMCwwLjkgLTAuMiwxLjYgLTAuNCwyLjMgMC4zLC0wLjMgMC43LC0wLjYgMSwtMC45IHogbSAtNTMwLjY5OTk5Nyw1LjMgYyAwLjMsMC4yIDAuNiwwLjQgMC45LDAuNyAtMS41LC0xLjIgLTIuOSwtMi41IC00LjIsLTMuOSAwLjYsMS4zIDIsMi4zIDMuMywzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDE0MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgYyAwLjIsMC44IDAuMywxLjUgMC40LDIuMyAwLjQsLTEuOCAwLjUsLTMuNiAwLjUsLTUuNSAtMC4xLDAuMyAtMC4xLDAuNiAtMC4yLDEgLTAuMiwwLjYgLTAuNCwxLjQgLTAuNywyLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuMTg3NjYsNDQ4LjQ3IGMgMC4xLC0wLjMgMC4xLC0wLjYgMC4yLC0xIDAsLTIuOCAtMC41LC01LjcgLTEuNCwtOC40IC0wLjEsMy4yIC0wLjEsNi40IC0wLjIsOS41IDAuMywwLjcgMC41LDEuNCAwLjYsMi4xIDAuNCwtMC43IDAuNiwtMS41IDAuOCwtMi4yIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjM4NzY2LDQ0Ny40NyBjIDAsMS45IC0wLjIsMy43IC0wLjUsNS41IDAuNSw1LjggLTIuNiwxMS4yIC05LjMsMTYuNyA3LjksLTMuNCAxMC40LC0xMC41IDExLC0xOCAwLjMsLTMuNiAxLjksLTcuOSAtMC45LC0xMS4yIDAuMSwyLjMgMC4xLDQuNyAtMC4zLDcgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsNDM5LjA3IGMgMC45LDIuOCAxLjMsNS42IDEuNCw4LjQgMC40LC0yLjMgMC40LC00LjcgMC4yLC03LjEgLTAuNCwtMC40IC0wLjksLTAuOSAtMS42LC0xLjMgeiBtIDAuMiwxMi40IGMgMC4yLDQgLTEuMSw3LjMgLTMsMTAuNSAxLjcsLTIuNiAyLjksLTUuNyAzLjYsLTguOSAtMC4xLC0wLjggLTAuMiwtMS41IC0wLjQsLTIuMyAwLDAuMiAtMC4xLDAuNCAtMC4yLDAuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE0OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgLTAuNiwtMi4xIGMgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAsLTAuNCAwLjEsLTAuNiAwLjIsLTAuOCB6IG0gMC40LDIuMiBjIC0wLjYsMy4yIC0xLjksNi4zIC0zLjYsOC45IC0xLjYsMi43IC0zLjcsNS4yIC01LjcsNy43IDYuNywtNS40IDkuNywtMTAuOCA5LjMsLTE2LjYgeiBtIC01MjIuMTk5OTk3LDIzIGMgLTUuNywwIC0xMSwtMS4xIC0xNi4xLC0zLjUgMy44LDQuMyA4LjksNC4yIDE0LDQuMiBIIDUzNi43ODc2NiBjIDUuMywwIDEwLjYsMC4yIDE0LjcsLTQuMiAtNS4xLDIuNCAtMTAuNSwzLjUgLTE2LjEsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTEzLjU4NzY2LDQ3NS4yNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuMSwyLjQgMTAuNCwzLjUgMTYuMSwzLjUgSCA1MzUuMjg3NjYgYyA1LjcsMCAxMSwtMS4xIDE2LjEsLTMuNSAtMTIuNCwzLjcgLTI1LjEsMi44IC0zNy44LDIuOCB6IG0gMTkuNiwtMTYzLjUgYyAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIC02LjQsMCAtMTIuNCwtMSAtMTguMiwtMy41IDMuNywzLjMgOC4xLDQuMiAxMi44LDQuMiBIIDUzOC41ODc2NiBjIDQuNywwIDkuMiwtMC45IDEyLjgsLTQuMiAtNS44LDIuNSAtMTEuOCwzLjUgLTE4LjIsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTMzLjE4NzY2LDMxMS43NyBjIDYuNCwwIDEyLjQsLTEgMTguMiwtMy41IC0xMi40LDMuNyAtMjUuMiwyLjggLTM3LjksMi44IEggNjMuNjg3NjYzIGMgLTEyLjQsMCAtMjUsMC45IC0zNy4yLC0yLjggNS44LDIuNiAxMS44LDMuNSAxOC4yLDMuNSAxNjIuODk5OTk3LC0wLjEgMzI1LjY5OTk5NywtMC4xIDQ4OC40OTk5OTcsMCB6IE0gNDQuNzg3NjYzLDYzLjk3IGMgLTYuNCwwIC0xMi40LC0xIC0xOC4yLC0zLjUgMy43LDMuMyA4LjEsNC4yIDEyLjgsNC4yIEggNTM4LjU4NzY2IGMgNC43LDAgOS4yLC0wLjkgMTIuOCwtNC4yIC01LjgsMi42IC0xMS44LDMuNSAtMTguMiwzLjUgLTE2Mi44LC0wLjEgLTMyNS42LC0wLjEgLTQ4OC4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJNIDUxMy41ODc2Niw2My4xNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuOCwyLjYgMTEuOCwzLjUgMTguMiwzLjUgMTYyLjc5OTk5NywtMC4xIDMyNS41OTk5OTcsLTAuMSA0ODguMzk5OTk3LDAgNi40LDAgMTIuNCwtMSAxOC4yLC0zLjUgLTEyLjQsMy43IC0yNS4xLDIuOCAtMzcuOCwyLjggeiBtIC00NjguNzk5OTk3LDgyLjkgYyAtNi40LDAgLTEyLjQsLTEgLTE4LjIsLTMuNSAzLjcsMy4zIDguMSw0LjIgMTIuOCw0LjIgSCA1MzguNTg3NjYgYyA0LjcsMCA5LjIsLTAuOSAxMi44LC00LjIgLTUuOCwyLjUgLTExLjgsMy41IC0xOC4yLDMuNSAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTE0LjI4NzY2LDE0NS4yNyBIIDY0LjQ4NzY2MyBjIC0xMi43LDAgLTI1LjQsMC45IC0zNy45LC0yLjggNS44LDIuNSAxMS44LDMuNSAxOC4yLDMuNSAxNjIuNzk5OTk3LC0wLjEgMzI1LjU5OTk5NywtMC4xIDQ4OC4zOTk5OTcsMCA2LjQsMCAxMi40LC0xIDE4LjIsLTMuNSAtMTIuMSwzLjggLTI0LjcsMi44IC0zNy4xLDIuOCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQwLjI4NzY2MywzOTEuMDcgaCAxLjYgYyAxLjEsMCAyLjIsLTAuMiAzLjMsLTAuMiBIIDUzMi43ODc2NiBjIDAuOCwwIDEuNiwwLjEgMi40LDAuMSAxLjEsMCAyLjIsLTAuMSAzLjMsLTAuMSAwLjYsLTAuMSAxLjIsLTAuMyAxLjgsLTAuNyBIIDM3LjY4NzY2MyBjIDAuOSwwLjYgMS44LDAuOSAyLjYsMC45IHogbSA0OTguMTk5OTk3LC0wLjEgYyAtMS4xLDAuMSAtMi4yLDAuMSAtMy4zLDAuMSAxLjEsMC4xIDIuMiwwLjIgMy4zLC0wLjEgeiBtIC00OTQuMzk5OTk3LDAuNyBoIC00IGMgMS4zLDAuMyAyLjcsMC4xIDQsMCB6IG0gNDkzLjc5OTk5NywwIGggLTQuMiBjIDEuNCwwLjEgMi45LDAuMyA0LjIsMCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQ1LjE4NzY2MywzOTAuOTcgYyAtMS4xLDAgLTIuMiwwLjEgLTMuMywwLjIgSCA1MzUuMDg3NjYgYyAtMC44LDAgLTEuNiwtMC4xIC0yLjQsLTAuMSAtMTYyLjQsMCAtMzI0LjksMCAtNDg3LjQ5OTk5NywtMC4xIHogbSA0OTQuNDk5OTk3LC0wLjEgYyAwLjIsLTAuMiAwLjQsLTAuMyAwLjYsLTAuNiAtMC42LDAuMyAtMS4yLDAuNSAtMS44LDAuNyAwLjQsMCAwLjgsMCAxLjIsLTAuMSB6IG0gLTUwMS45OTk5OTcsLTAuNSBjIDAuMiwwLjMgMC41LDAuNSAwLjcsMC42IDAuNCwwIDAuNywwLjEgMS4xLDAuMSBoIDAuOCBjIC0wLjgsMCAtMS43LC0wLjMgLTIuNiwtMC43IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MTYzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTM4LjQ4NzY2LDM5MC45NyBjIC0xLjEsMC4yIC0yLjIsMC4yIC0zLjMsMC4xIEggMzkuNTg3NjYzIGMgLTAuNCwwIC0wLjcsLTAuMSAtMS4xLC0wLjEgMC41LDAuNCAxLjEsMC42IDEuNywwLjggSCA1MzcuODg3NjYgYyAwLjYsLTAuMSAxLjIsLTAuNCAxLjcsLTAuOCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+Cjwvc3ZnPgo= - mediatype: image/svg+xml - install: - spec: - clusterPermissions: - - rules: - - apiGroups: - - "" - resources: - - events - - persistentvolumeclaims - - secrets - - services - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - '*' - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - create - - apiGroups: - - apps - resources: - - replicasets - verbs: - - get - serviceAccountName: nexus-operator - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - strategy: deployment - installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: true - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - nexus - - sonatype - - maven - - docker - - ci - - continuous integration - - continuous delivery - - repository - - repository manager - - dev tools - labels: - name: nexus-operator - links: - - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/main/README.md - - name: Nexus Operator source code repository - url: https://github.com/m88i/nexus-operator - maintainers: - - email: nexus-operator@googlegroups.com - name: m88i Labs - maturity: alpha - minKubeVersion: 1.11.0 - provider: - name: m88i Labs - replaces: nexus-operator.v0.3.0 - version: 0.4.0 diff --git a/deploy/olm-catalog/nexus-operator/manifests/apps.m88i.io_nexus_crd.yaml b/deploy/olm-catalog/nexus-operator/manifests/apps.m88i.io_nexus_crd.yaml deleted file mode 100644 index 4c20fb6f..00000000 --- a/deploy/olm-catalog/nexus-operator/manifests/apps.m88i.io_nexus_crd.yaml +++ /dev/null @@ -1,392 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: nexus.apps.m88i.io -spec: - group: apps.m88i.io - names: - kind: Nexus - listKind: NexusList - plural: nexus - singular: nexus - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NexusSpec defines the desired state of Nexus - properties: - automaticUpdate: - description: Automatic updates configuration - properties: - disabled: - description: Whether or not the Operator should perform automatic - updates. Defaults to `false` (auto updates are enabled). Is set - to `false` if `spec.image` is not empty and is different from - the default community image. - type: boolean - minorVersion: - description: The Nexus image minor version the deployment should - stay in. If left blank and automatic updates are enabled the latest - minor is set. - minimum: 0 - type: integer - type: object - generateRandomAdminPassword: - description: 'GenerateRandomAdminPassword enables the random password - generation. Defaults to `false`: the default password for a newly - created instance is ''admin123'', which should be changed in the first - login. If set to `true`, you must use the automatically generated - ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. - The operator uses the default credentials to create a user for itself - to create default repositories. If set to `true`, the repositories - won''t be created since the operator won''t fetch for the random password.' - type: boolean - image: - description: 'Full image tag name for this specific deployment. Will - be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' - type: string - imagePullPolicy: - description: 'The image pull policy for the Nexus image. If left blank - behavior will be determined by the image tag (`Always` if "latest" - and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` - or `Never`.' - enum: - - Always - - IfNotPresent - - Never - type: string - livenessProbe: - description: LivenessProbe describes how the Nexus container liveness - probe should work - properties: - failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. - format: int32 - minimum: 1 - type: integer - initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. - format: int32 - minimum: 0 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - type: object - networking: - description: Networking definition - properties: - expose: - description: Set to `true` to expose the Nexus application. Defaults - to `false`. - type: boolean - exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Defaults to Route on OpenShift and Ingress on Kubernetes. Routes - are only available on Openshift and Ingresses are only available - on Kubernetes.' - enum: - - NodePort - - Route - - Ingress - type: string - host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. - type: string - nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. - format: int32 - type: integer - tls: - description: TLS/SSL-related configuration - properties: - mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to `false`. - type: boolean - secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. - type: string - type: object - type: object - persistence: - description: Persistence definition - properties: - persistent: - description: Flag to indicate if this instance will be persistent - or not - type: boolean - storageClass: - description: StorageClass used by the managed PVC. - type: string - volumeSize: - description: 'If persistent, the size of the Volume. Defaults: 10Gi' - type: string - required: - - persistent - type: object - readinessProbe: - description: ReadinessProbe describes how the Nexus container readiness - probe should work - properties: - failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. - format: int32 - minimum: 1 - type: integer - initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. - format: int32 - minimum: 0 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. - format: int32 - minimum: 1 - type: integer - type: object - replicas: - description: Number of pod replicas desired. Defaults to 0. - format: int32 - maximum: 100 - minimum: 0 - type: integer - resources: - description: Defined Resources for the Nexus instance - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - serverOperations: - description: ServerOperations describes the options for the operations - performed on the deployed server instance - properties: - disableOperatorUserCreation: - description: DisableOperatorUserCreation disables the auto-creation - of the `nexus-operator` user on the deployed server. This user - performs all the operations on the server (such as creating the - community repos). If disabled, the Operator will use the default - `admin` user. Defaults to `false` (always create the user). Setting - this to `true` is not recommended as it grants the Operator more - privileges than it needs and it would not be possible to tell - apart operations performed by the `admin` and the Operator. - type: boolean - disableRepositoryCreation: - description: DisableRepositoryCreation disables the auto-creation - of Apache, JBoss and Red Hat repositories and their addition to - the Maven Public group in this Nexus instance. Defaults to `false` - (always try to create the repos). Set this to `true` to not create - them. Only works if `spec.generateRandomAdminPassword` is `false`. - type: boolean - type: object - serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR (`metadata.name`). - type: string - useRedHatImage: - description: If you have access to Red Hat Container Catalog, set this - to `true` to use the certified image provided by Sonatype Defaults - to `false` - type: boolean - required: - - persistence - - replicas - - useRedHatImage - type: object - status: - description: NexusStatus defines the observed state of Nexus - properties: - deploymentStatus: - description: Condition status for the Nexus deployment - properties: - availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. - format: int32 - type: integer - collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. - format: int32 - type: integer - conditions: - description: Represents the latest available observations of a deployment's - current state. - items: - description: DeploymentCondition describes the state of a deployment - at a certain point. - properties: - lastTransitionTime: - description: Last time the condition transitioned from one - status to another. - format: date-time - type: string - lastUpdateTime: - description: The last time this condition was updated. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of deployment condition. - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: The generation observed by the deployment controller. - format: int64 - type: integer - readyReplicas: - description: Total number of ready pods targeted by this deployment. - format: int32 - type: integer - replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). - format: int32 - type: integer - unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. - format: int32 - type: integer - updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. - format: int32 - type: integer - type: object - nexusRoute: - description: Route for external service access - type: string - nexusStatus: - description: Will be "OK" when this Nexus instance is up - type: string - reason: - description: Gives more information about a failure status - type: string - serverOperationsStatus: - description: ServerOperationsStatus describes the general status for - the operations performed in the Nexus server instance - properties: - communityRepositoriesCreated: - type: boolean - mavenCentralUpdated: - type: boolean - operatorUserCreated: - type: boolean - reason: - type: string - serverReady: - type: boolean - type: object - updateConditions: - description: Conditions reached during an update - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true diff --git a/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml deleted file mode 100644 index 420b0f86..00000000 --- a/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml +++ /dev/null @@ -1,322 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "apps.m88i.io/v1alpha1", - "kind": "Nexus", - "metadata": { - "name": "nexus3" - }, - "spec": { - "networking": { - "expose": false - }, - "persistence": { - "persistent": false - }, - "replicas": 1, - "resources": { - "limits": { - "cpu": "2", - "memory": "2Gi" - }, - "requests": { - "cpu": "1", - "memory": "2Gi" - } - }, - "useRedHatImage": false - } - } - ] - capabilities: Seamless Upgrades - categories: Developer Tools - certified: "false" - containerImage: quay.io/m88i/nexus-operator:0.4.0 - createdAt: "2019-11-16T13:12:22Z" - description: Nexus Operator to deploy and manage Nexus 3.x servers - repository: https://github.com/m88i/nexus-operator - support: m88i Labs - tectonic-visibility: ocs - name: nexus-operator.v0.4.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: Nexus custom resource to deploy the Nexus Server - displayName: Nexus - kind: Nexus - name: nexus.apps.m88i.io - resources: - - kind: Deployment - name: A Kubernetes Deployment - version: v1 - - kind: PersistentVolumeClaim - name: A Kubernetes PersistentVolumeClaim - version: v1 - - kind: Service - name: A Kubernetes Service - version: v1 - specDescriptors: - - description: Automatic updates configuration - displayName: Automatic Update - path: automaticUpdate - - description: 'GenerateRandomAdminPassword enables the random password generation. - Defaults to `false`: the default password for a newly created instance is - ''admin123'', which should be changed in the first login. If set to `true`, - you must use the automatically generated ''admin'' password, stored in the - container''s file system at `/nexus-data/admin.password`. The operator uses - the default credentials to create a user for itself to create default repositories. - If set to `true`, the repositories won''t be created since the operator - won''t fetch for the random password.' - displayName: Generate Random Admin Password - path: generateRandomAdminPassword - - description: 'Full image tag name for this specific deployment. Will be ignored - if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' - displayName: Image - path: image - x-descriptors: - - urn:alm:descriptor:io.kubernetes:image - - description: 'The image pull policy for the Nexus image. If left blank behavior - will be determined by the image tag (`Always` if "latest" and `IfNotPresent` - otherwise). Possible values: `Always`, `IfNotPresent` or `Never`.' - displayName: Image Pull Policy - path: imagePullPolicy - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:imagePullPolicy - - description: Number of pod replicas desired. Defaults to 0. - displayName: Replicas - path: replicas - - description: Defined Resources for the Nexus instance - displayName: Resources - path: resources - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:resourceRequirements - - description: ServerOperations describes the options for the operations performed - on the deployed server instance - displayName: Server Operations - path: serverOperations - - description: ServiceAccountName is the name of the ServiceAccount used to - run the Pods. If left blank, a default ServiceAccount is created with the - same name as the Nexus CR (`metadata.name`). - displayName: Service Account - path: serviceAccountName - - description: If you have access to Red Hat Container Catalog, set this to - `true` to use the certified image provided by Sonatype Defaults to `false` - displayName: Use Red Hat Image - path: useRedHatImage - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - statusDescriptors: - - description: Condition status for the Nexus deployment - displayName: appsv1.DeploymentStatus - path: deploymentStatus - - description: Route for external service access - displayName: Nexus Route - path: nexusRoute - - description: Will be "OK" when this Nexus instance is up - displayName: Nexus Status - path: nexusStatus - - description: Gives more information about a failure status - displayName: Reason - path: reason - x-descriptors: - - urn:alm:descriptor:io.kubernetes.phase:reason - - description: Conditions reached during an update - displayName: Update Conditions - path: updateConditions - version: v1alpha1 - description: |- - Creates a new Nexus 3.x deployment in a Kubernetes cluster. Will help DevOps to have a quick Nexus application exposed to the world that can be used in a CI/CD process: - - * Deploys a new Nexus 3.x server based on either Community or Red Hat images - * Creates an [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) in Kubernetes (1.14+) environments to expose the application to the world - * On OpenShift, creates a Route to expose the service outside the cluster - * Automatically creates Apache, Red Hat and JBoss Maven repositories - * Automatically updates Nexus within the same minor version - - [See our documentation](https://github.com/m88i/nexus-operator/blob/main/README.md) for more installation and usage scenarios. - - If you experience any issues or have any ideas for new features, please [file an issue in our Github repository](https://github.com/m88i/nexus-operator/issues) or send an email to our maillist: [nexus-operator@googlegroups.com](mailto:nexus-operator@googlegroups.com) - - *Please note that the operator is an individual work and it's not provided nor supported by Sonatype.* - displayName: Nexus Operator - icon: - - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgcm9sZT0iaW1nIgogICB2aWV3Qm94PSI4LjM3IDUuODcgNTYxLjI0MTYzIDQ3My40NDQ0NSIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnNDE2NyIKICAgc29kaXBvZGk6ZG9jbmFtZT0ic29uYXR5cGUtbmV4dXMtY3JvcC5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTIuNCAodW5rbm93bikiCiAgIHdpZHRoPSI1NjEuMjQxNjQiCiAgIGhlaWdodD0iNDczLjQ0NDQ2Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE0MTczIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZT5Tb25hdHlwZSBOZXh1cyBsb2dvPC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczQxNzEiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9Ijk5MCIKICAgICBpZD0ibmFtZWR2aWV3NDE2OSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMS4wNTE1OCIKICAgICBpbmtzY2FwZTpjeD0iMjgwLjQ2NzY3IgogICAgIGlua3NjYXBlOmN5PSIxMDcuOTk0NDQiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjAiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc0MTY3IiAvPgogIDx0aXRsZQogICAgIGlkPSJ0aXRsZTM5NjMiPlNvbmF0eXBlIE5leHVzIGxvZ288L3RpdGxlPgogIDxzdHlsZQogICAgIGlkPSJzdHlsZTM5NjUiPnN2ZyB7ZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2MDAgNzY0fTwvc3R5bGU+CiAgPHN0eWxlCiAgICAgaWQ9InN0eWxlMzk2NyI+LnN0NXtmaWxsOiNkNGQ0ZDR9LnN0NTR7ZmlsbDojMzI2Nzk4fS5zdDU1e2ZpbGw6I2ViZWJlYn0uc3Q1NntmaWxsOiMwMjAyMDJ9LnN0NTd7ZmlsbDojZWNlY2VjfS5zdDU4e2ZpbGw6IzAxMDEwMX0uc3Q2MHtmaWxsOiMwNDA0MDR9LnN0NjF7ZmlsbDojYmRiZGJkfS5zdDYye2ZpbGw6I2U4ZThlOH0uc3Q2M3tmaWxsOiNjZGNkY2V9LnN0NjR7ZmlsbDojY2ZjZmNmfTwvc3R5bGU+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAxLjksNS41IDQuNSwxMC42IDguNiwxNSA3LjIsNC45IDE1LjEsNi4xIDIzLjcsNi4xIDE2MS43OTk5OTcsLTAuMiAzMjMuNTk5OTk3LC0wLjIgNDg1LjM5OTk5NywwIDguNiwwIDE2LjUsLTEuMiAyMy43LC02LjEgNCwtNC4zIDYuNywtOS40IDguNiwtMTUgMC42LC02LjMgLTAuNywtMTIuMiAtMy4xLC0xOCAtNi42LC05LjMgLTE1LjUsLTEyLjggLTI2LjksLTEyLjggLTE2My4zLDAuMiAtMzI2LjYsMC4yIC00ODkuODk5OTk3LDAgLTExLjQsMCAtMjAuMywzLjUgLTI2LjksMTIuOCAtMi41LDUuOCAtMy44LDExLjggLTMuMiwxOCB6IG0gMC4xLC04Mi4zIGMgMi4xLDUuMSA0LjQsMTAgOC4zLDEzLjkgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNTk5OTk3LC0wLjEgMzI1LjE5OTk5NywtMC4xIDQ4Ny43OTk5OTcsMCA3LjYsMCAxNC43LC0wLjggMjEuNCwtNC43IDIuMywtMi43IDQuNywtNS40IDcsLTguMSAxLC0zLjIgMiwtNi40IDMsLTkuNyAwLjQsLTYuNSAtMS44LC0xMi4zIC00LjgsLTE3LjkgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTEuNCwzLjcgLTQuOSw2LjUgLTQuNywxMSAwLjIsMy41IDAuMiw2LjcgMC4zLDkuOCB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk2OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzNjMuODcgYyAxLjEsMi4xIC0wLjMsNC45IDEuNiw2LjggMi40LDMuOSA1LDcuNyA4LjUsMTAuOSA2LjQsMy44IDEzLjMsNC43IDIwLjYsNC43IDE2My4wOTk5OTcsLTAuMSAzMjYuMTk5OTk3LC0wLjEgNDg5LjE5OTk5NywwIDgsMCAxNS4xLC0xLjQgMjEuNiwtNS45IDQuNSwtNC42IDYuOCwtMTAuNCA4LjYsLTE2LjUgMC4yLC02IC0xLjQsLTExLjUgLTQuMSwtMTYuNyAtNi4zLC04LjEgLTE0LjUsLTExLjIgLTI0LjgsLTExLjIgLTE2NC4yLDAuMSAtMzI4LjMsMC4xIC00OTIuNDk5OTk3LDAgLTEwLjMsMCAtMTguNSwzLjEgLTI0LjgsMTEuMiAtMi41LDUuMiAtNC4xLDEwLjggLTMuOSwxNi43IHoiCiAgICAgaWQ9InBhdGgzOTcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIDEuNCw2LjMgNC4xLDExLjkgOC42LDE2LjUgNi44LDQuNiAxNC4yLDUuOCAyMi40LDUuOCAxNjIuNzk5OTk3LC0wLjEgMzI1LjQ5OTk5NywtMC4xIDQ4OC4yOTk5OTcsMCA4LjIsMCAxNS42LC0xLjMgMjIuNCwtNS44IDMuOSwtNCA2LjMsLTguOSA4LjMsLTEzLjkgMCwtMy4yIDAuMSwtNi40IDAuMSwtOS42IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTEgLTYuNCwtNy4yIC0xNC4zLC0xMC4xIC0yNC4xLC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC05LjcsMCAtMTcuNiwyLjggLTI0LjEsMTAgLTIuOSw1LjcgLTUuMSwxMS42IC00LjcsMTguMSB6IgogICAgIGNsYXNzPSJzdDU0IgogICAgIGlkPSJwYXRoMzk3MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiMzMjY3OTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywyODEuNzcgYyAxLjMsNi4zIDQuMiwxMS44IDguNiwxNi41IDYuNiw0LjQgMTMuNyw1LjkgMjEuNyw1LjkgMTYzLjE5OTk5NywtMC4xIDMyNi40OTk5OTcsLTAuMSA0ODkuNjk5OTk3LDAgOCwwIDE1LjEsLTEuNSAyMS43LC01LjkgMy44LC00IDYuNCwtOC44IDguMywtMTMuOSBsIDAuMywtOC4xIC00LjgsLTEyLjMgYyAtNi40LC03LjIgLTE0LjMsLTEwLjEgLTI0LC0xMC4xIC0xNjQuMiwwLjEgLTMyOC4zLDAuMSAtNDkyLjQ5OTk5NywwIC0xMC4zLDAgLTE4LjUsMy4xIC0yNC44LDExLjIgLTIuOCw1LjIgLTQuNCwxMC43IC00LjIsMTYuNyB6IG0gMCwxNjQuMyBjIDEuMyw2LjMgNC4yLDExLjggOC42LDE2LjUgNi42LDQuNCAxMy43LDUuOSAyMS43LDUuOSAxNjMuMTk5OTk3LC0wLjEgMzI2LjQ5OTk5NywtMC4xIDQ4OS42OTk5OTcsMCA4LDAgMTUuMSwtMS41IDIxLjcsLTUuOSAzLjgsLTQgNi40LC04LjggOC4zLC0xMy45IDAuMSwtMy4yIDAuMSwtNi40IDAuMiwtOS41IC0xLjYsLTMuNyAtMy4xLC03LjMgLTQuNywtMTAuOSAtNi42LC03LjYgLTE0LjgsLTEwLjIgLTI0LjgsLTEwLjIgLTE2My43LDAuMiAtMzI3LjUsMC4yIC00OTEuMTk5OTk3LDAgLTkuOSwwIC0xOC4xLDIuNiAtMjQuNywxMC4xIC0zLjEsNS41IC01LjIsMTEuNCAtNC44LDE3LjkgeiIKICAgICBpZD0icGF0aDM5NzUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNDMuNjg3NjYzLDIzMi45NyBIIDQyMi4yODc2NiBjIDM3LjYsMCA3NS4yLDAuMiAxMTIuOCwtMC4xIDE0LjIsLTAuMSAyNS41LC02IDMxLjcsLTE5LjUgNS4zLC0xMS42IDIuOCwtMjQuNSAtNS45LC0zMC40IDUsNC45IDUuNSwxMS4xIDQuNywxNy41IC0wLjMsMS4xIC0wLjYsMi4xIC0wLjksMy4yIDEsOC45IC03LjUsMTkuMiAtMTQuNSwyMiAtNC43LDEuOSAtOS41LDMuMSAtMTQuOCwzLjEgLTE2NC4yLC0wLjEgLTMyOC4zLC0wLjEgLTQ5Mi40OTk5OTcsLTAuMSAtMTUuOSwwIC0yNi42LC04LjMgLTI5LjYsLTIyLjggLTAuMywtMS4zIC0wLjYsLTIuNSAtMC4yLC0zLjcgLTAuMiwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuOCwtNi41IC0wLjQsLTEyLjcgNC43LC0xNy42IC02LjIsNC4zIC05Ljk5OTk5OTcsMTQuNCAtOC4yOTk5OTk3LDIyLjUgMy4zOTk5OTk3LDE3LjYgMTYuMTk5OTk5NywyNy43IDM0LjY5OTk5OTcsMjcuNyB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk3NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjQ4NzY2MywyMDAuNjcgYyAwLjIsMC42IDAuMywxLjIgMC41LDEuOCAwLjIsLTAuNSAwLjUsLTEgMS4xLC0xLjQgLTAuNiwtNi4zIDAuNywtMTIuMiAzLjEsLTE4IC01LjEsNC45IC01LjUsMTEuMSAtNC43LDE3LjYgeiBtIDU1MS40OTk5OTcsMC4zIGMgMC4zLDAuOSAwLjUsMS44IDAuNiwyLjggMC4zLC0xIDAuNywtMi4xIDAuOSwtMy4yIDAuOCwtNi41IDAuNCwtMTIuNiAtNC43LC0xNy41IDIuNSw1LjcgMy44LDExLjcgMy4yLDE3LjkgeiBNIDQ0LjI4NzY2MywzOTcuMjcgSCA0NzEuODg3NjYgYyAyMS4xLDAgNDIuMiwwLjEgNjMuMywwIDE4LjMsLTAuMSAzMC4zLC05LjkgMzQsLTI3LjQgMS44LC04LjcgLTIuMywtMTkuMSAtOS4xLC0yMi43IDUsNC41IDYsMTAuNCA1LjYsMTYuNyAtMC4zLDEuMyAtMC42LDIuNSAtMC45LDMuOCAwLjUsOS43IC02LjksMjAuNiAtMTcuMSwyMy43IC0zLjcsMS4xIC03LjUsMS45IC0xMS42LDEuOSAtMTY0LjcsLTAuMSAtMzI5LjQsLTAuMSAtNDk0LjA5OTk5NywtMC4xIC0xNS43LDAgLTI1LjQsLTcuNyAtMjguOCwtMjIuNyAtMC4yLC0wLjkgLTAuNCwtMS44IC0wLjUsLTIuNiAtMC4zLC0xLjMgLTAuNSwtMi43IC0wLjUsLTQuMSAtMC4xLC02LjIgMC43LC0xMi4xIDUuNywtMTYuNSAtNi43LDMuNiAtMTAuODk5OTk5NywxNC4xIC05LjA5OTk5OTcsMjIuNyAzLjc5OTk5OTcsMTcuOSAxNS45OTk5OTk3LDI3LjMgMzUuNDk5OTk5NywyNy4zIHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTc5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjA4NzY2LDM2My44NyBjIDAuNCwxLjIgMC41LDIuNSAwLjYsMy43IDAuMywtMS4yIDAuNywtMi41IDAuOSwtMy44IDAuNCwtNi4zIC0wLjYsLTEyLjIgLTUuNiwtMTYuNyAyLjgsNS4zIDQuNCwxMC44IDQuMSwxNi44IHogbSAtNTUxLjg5OTk5NywtMC4yIGMgMCwxLjQgMC4yLDIuOCAwLjUsNC4xIC0wLjEsLTEuNCAwLC0yLjcgMS4yLC0zLjkgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LjEsNC40IC01LjksMTAuMyAtNS44LDE2LjUgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5ODEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTkuMjg3NjYsNDI4LjA3IGMgMy41LDMgNS4xLDcgNi4yLDExLjMgMCwwLjMgMC4xLDAuNyAwLjEsMSAyLjgsMy4zIDEuMiw3LjYgMC45LDExLjIgLTAuNiw3LjYgLTMuMSwxNC42IC0xMSwxOCAtMS40LDAuOSAtMi44LDEuOSAtNC4xLDIuOCAtNCw0LjQgLTkuNCw0LjIgLTE0LjcsNC4yIEggNDAuNDg3NjYzIGMgLTUsMCAtMTAuMiwwLjEgLTE0LC00LjIgLTYuNCwtNC44IC0xMS41LC0xMC41IC0xMy40LC0xOC42IC0wLjQsLTIgLTEsLTQgLTAuNCwtNS45IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjEsLTEzIDYuNCwtMTcuOCAtNy42LDMuOSAtOS42OTk5OTk3LDExIC0xMC4wOTk5OTk3LDE4LjUgLTEsMTguMiAxMy41OTk5OTk3LDMyLjggMzIuNTk5OTk5NywzMi44IDQ5LjksMC4xIDk5LjY5OTk5NywwIDE0OS41OTk5OTcsMCBoIDM0NC41IGMgMTAuNCwwIDE5LjUsLTMuMSAyNi42LC0xMS4yIDExLjMsLTEyLjUgMTAuMSwtMzIgLTIuNSwtNDAgeiIKICAgICBjbGFzcz0ic3Q1NyIKICAgICBpZD0icGF0aDM5ODUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWNlY2VjIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuNTg3NjYsNDQwLjQ3IGMgMCwtMC4zIC0wLjEsLTAuNyAtMC4xLC0xIC0xLjEsLTQuMyAtMi43LC04LjMgLTYuMiwtMTEuMyAxLjYsMy42IDMuMSw3LjMgNC43LDEwLjkgMC43LDAuNCAxLjIsMC45IDEuNiwxLjQgeiBtIC01NTMuMTk5OTk3LDUuNSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS4zIDEuMSwtMiAtMC40LC02LjUgMS43LC0xMi40IDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IgogICAgIGNsYXNzPSJzdDU3IgogICAgIGlkPSJwYXRoMzk4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlY2VjZWMiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQ0LjE4NzY2MywzMTUuMTcgSCA0MzguMzg3NjYgYyAzMi4yLDAgNjQuNCwwLjIgOTYuNiwtMC4xIDE0LjUsLTAuMSAyNiwtNS41IDMxLjksLTE5LjkgNSwtMTIuMiAyLC0yNS4yIC03LjcsLTMxLjMgMy44LDMuMyA1LjUsNy43IDYuMywxMi41IDAuMSwwLjkgMC4xLDEuOCAwLjEsMi43IDIuOSw3IDAuNSwxNi44IC02LDIyLjIgLTIuOCwyLjMgLTUuNSw0LjYgLTguMyw3IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjI4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtNi44LC01LjEgLTEyLjEsLTExLjEgLTEzLjQsLTE5LjkgLTAuMiwtMS41IC0wLjYsLTMuMSAtMC4zLC00LjUgLTAuMiwtMC43IC0wLjMsLTEuMyAtMC40LC0yIC0wLjQsLTYuMyAwLjYsLTEyLjIgNS42LC0xNi44IC02LjcsMy42IC0xMC44OTk5OTk3LDE0LjEgLTkuMDk5OTk5NywyMi43IDMuNzk5OTk5NywxOCAxNS42OTk5OTk3LDI3LjQgMzUuMjk5OTk5NywyNy40IHoiCiAgICAgY2xhc3M9InN0NTUiCiAgICAgaWQ9InBhdGgzOTg5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2ViZWJlYiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTIuMzg3NjYzLDI4MS43NyBjIDAuMSwwLjcgMC4zLDEuMyAwLjQsMiAwLjIsLTAuNyAwLjUsLTEuNCAxLjEsLTIgLTAuMiwtNiAxLjQsLTExLjUgNC4xLC0xNi43IC01LDQuNSAtNi4xLDEwLjQgLTUuNiwxNi43IHogbSA1NTMuMzk5OTk3LC0yLjggYyAwLC0wLjkgMCwtMS44IC0wLjEsLTIuNyAtMC44LC00LjggLTIuNSwtOS4yIC02LjMsLTEyLjUgbCA0LjgsMTIuMyBjIDAuNiwxIDEuMSwxLjkgMS42LDIuOSB6IE0gMzIuNTg3NjYzLDY2LjA3IGMgOC41LDEuNyAxNywxLjMgMjUuNiwxLjMgSCA1MzMuMDg3NjYgYyAxMSwwIDIxLC0yLjUgMjguOCwtMTEuMSAxMS4yLC0xMi40IDkuMiwtMzQuOCAtMi41LC00MC4yIDMuNSwzIDUuMSw3IDYuMiwxMS4zIDAuMSwxLjEgMC4yLDIuMiAwLjIsMy4zIDMuMiw5LjMgLTAuNiwyMS40IC04LjgsMjUuNiAtMS44LDEuNCAtMy43LDIuOCAtNS41LDQuMiAtMy43LDMuMyAtOC4xLDQuMiAtMTIuOCw0LjIgSCAzOS40ODc2NjMgYyAtNC43LDAgLTkuMiwtMC45IC0xMi44LC00LjIgLTYuOCwtNS4xIC0xMi4xLC0xMS4xIC0xMy40LC0xOS45IC0wLjIsLTEuNSAtMC42LC0zLjEgLTAuMywtNC41IC0wLjIsLTAuNyAtMC4zLC0xLjQgLTAuNSwtMi4xIC0wLjYsLTYuOSAxLjIsLTEzIDYuNCwtMTcuOCAtMi43LDAuNiAtNC4zLDIuNyAtNS43LDQuOCAtMTEuMDk5OTk5NywxNi41IC0wLjIsNDEuMiAxOS40LDQ1LjEgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsMjYuOTcgYyAwLjcsMS4xIDEuMywyLjQgMS43LDMuNiAwLC0xLjEgLTAuMSwtMi4yIC0wLjIsLTMuMyAtMSwtNC4zIC0yLjcsLTguMyAtNi4yLC0xMS4zIDEuNiwzLjcgMy4yLDcuNCA0LjcsMTEgeiBtIC01NTEuNTk5OTk3LDYuOSBjIDAuMSwwLjcgMC4zLDEuNCAwLjUsMi4xIDAuMiwtMC43IDAuNSwtMS40IDEuMSwtMiAtMC40LC02LjUgMS44LC0xMi4zIDQuOCwtMTcuOSAtNS4zLDQuOCAtNywxMC45IC02LjQsMTcuOCB6IG0gMzEuMywxMTUuNiBIIDQwOS43ODc2NiBjIDQxLjgsMCA4My41LDAuMSAxMjUuMywtMC4xIDE0LjUsLTAuMSAyNi4xLC01LjUgMzIsLTE5LjkgNSwtMTIuMiAyLC0yNS4zIC03LjcsLTMxLjQgNS4xLDQuNyA2LjksMTAuNyA2LjQsMTcuNCAtMC4yLDEuNCAtMC41LDIuOCAtMC45LDQuMiAwLjUsNi43IC0yLjUsMTIuMyAtNy4yLDE3LjMgLTEuOSwyIC00LjEsMy43IC02LjEsNS41IC0zLjcsMy4zIC04LjEsNC4yIC0xMi44LDQuMiBIIDM5LjU4NzY2MyBjIC00LjcsMCAtOS4yLC0wLjkgLTEyLjgsLTQuMiAtMiwtMS4yIC00LjUsLTEuNyAtNS42LC00LjIgLTguMSwtNC4yIC0xMS44OTk5OTk3LC0xNi4yIC04LjgsLTI1LjQgMCwtMS4xIDAsLTIuMyAwLjEsLTMuNCAwLjUsLTQuNyAyLjksLTguMyA2LjQsLTExLjMgLTcuNSw0LjcgLTExLjY5OTk5OTcsMTUuMiAtOS43OTk5OTk3LDI0LjEgMy42OTk5OTk3LDE3LjkgMTUuNDk5OTk5NywyNy4yIDM0LjU5OTk5OTcsMjcuMiB6IgogICAgIGNsYXNzPSJzdDU1IgogICAgIGlkPSJwYXRoMzk5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlYmViZWIiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC4xODc2NiwxMTYuMDcgYyAwLjMsMS4zIDAuNSwyLjUgMC42LDMuNyAwLjQsLTEuNCAwLjcsLTIuNyAwLjksLTQuMiAwLjUsLTYuOCAtMS4zLC0xMi43IC02LjQsLTE3LjQgMy4xLDUuNiA1LjMsMTEuNCA0LjksMTcuOSB6IG0gLTU1MS44OTk5OTcsLTYuNiBjIDAsMS4xIC0wLjEsMi4zIC0wLjEsMy40IDAuNCwtMS4zIDEsLTIuNiAxLjgsLTMuOCAtMC4yLC00LjQgMy4zLC03LjIgNC43LC0xMSAtMy41LDMuMSAtNS45LDYuNyAtNi40LDExLjQgeiIKICAgICBjbGFzcz0ic3Q1NSIKICAgICBpZD0icGF0aDM5OTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZWJlYmViIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOS44ODc2NjMsMjI1Ljk3IGMgMS41LDAuNCAzLjIsMC4xIDQuOSwwLjEgSCA1MzMuMzg3NjYgYyA3LjEsMCAxMy44LC0xLjEgMTkuNiwtNS42IDEuMSwtMC44IDEuOSwtMS42IDIuMywtMi43IC0wLjMsMC4yIC0wLjUsMC40IC0wLjgsMC42IC01LjQsNC4xIC0xMS41LDUuNiAtMTguMiw1LjYgSCA0MS45ODc2NjMgYyAtNi43LDAgLTEyLjgsLTEuNSAtMTguMSwtNS41IDMuMyw1LjkgMTAsNi4xIDE2LDcuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJNIDQxLjg4NzY2MywyMjMuOTcgSCA1MzYuMTg3NjYgYyA2LjcsMCAxMi44LC0xLjUgMTguMiwtNS42IDAuMywtMC4yIDAuNiwtMC40IDAuOCwtMC42IDAuMiwtMC41IDAuMywtMS4xIDAuMiwtMS44IC03LjIsNC45IC0xNS4xLDYuMSAtMjMuNyw2LjEgLTE2MS44LC0wLjIgLTMyMy42LC0wLjIgLTQ4NS4zOTk5OTcsMCAtOC42LDAgLTE2LjUsLTEuMiAtMjMuNywtNi4xIDAuMywxIDAuNywxLjggMS4yLDIuNiA1LjQsNCAxMS40LDUuNCAxOC4xLDUuNCB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDAxMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1NS45ODc2NiwyMTcuMTcgYyAwLjIsMC43IDAuMiwxLjMgMCwxLjkgMi43LC0yLjYgNC42LC01LjYgNiwtOS4xIC0xLjUsMi43IC0zLjQsNS4xIC02LDcuMiB6IG0gLTUzMy45OTk5OTcsMCBjIC0yLjQsLTEuOSAtNC4yLC00LjIgLTUuNywtNi43IDEuNCwzLjIgMy4zLDYgNS42LDguNCAtMC4xLC0wLjQgLTAuMSwtMSAwLjEsLTEuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDIxNy4xNyBjIDAuMSwtMC40IDAuMywtMC44IDAuNiwtMS4yIC00LC00LjMgLTYuNywtOS40IC04LjYsLTE1IDAuMywzLjQgMS4xLDYuNiAyLjMsOS41IDEuNSwyLjYgMy40LDQuOCA1LjcsNi43IHogbSA1MzkuOTk5OTk3LC03LjMgYyAxLC0yLjcgMS43LC01LjcgMiwtOC45IC0xLjksNS41IC00LjUsMTAuNiAtOC42LDE1IDAuMywwLjQgMC41LDAuOSAwLjYsMS4yIDIuNiwtMi4xIDQuNSwtNC41IDYsLTcuMyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDIxOS4wNyBjIC0wLjQsMS4yIC0xLjcsMi4xIC0zLDMgLTUuMSwzLjYgLTEwLjcsNS4zIC0xNi45LDUuNCBIIDQ0LjU4NzY2MyBjIC03LjEsMCAtMTMuOCwtMS4yIC0xOS43LC01LjQgLTEuMywtMC45IC0yLjYsLTEuOSAtMywtMy4xIC0yLjQsLTIuNCAtNC4yLC01LjIgLTUuNiwtOC40IC0xLjUsLTIuNSAtMi41LC01LjIgLTMuNCwtOC4xIC0wLjQsMS4xIC0wLjEsMi40IDAuMiwzLjcgMy4xLDE0LjUgMTMuNywyMi44IDI5LjYsMjIuOCAxNjQuMTk5OTk3LDAgMzI4LjI5OTk5NywwIDQ5Mi40OTk5OTcsMC4xIDUuMywwIDEwLjEsLTEuMyAxNC44LC0zLjEgNy4xLC0yLjggMTUuNiwtMTMuMSAxNC41LC0yMiAtMC43LDIuMiAtMS42LDQuMiAtMi42LDYuMSAtMS4yLDMuNCAtMy4yLDYuNCAtNS44LDkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAxOSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0LjA4NzY2MywyMDAuOTcgYyAtMC41LDAuNCAtMC45LDAuOSAtMS4xLDEuNCAwLjgsMi45IDEuOSw1LjYgMy40LDguMSAtMS4zLC0yLjggLTIuMSwtNiAtMi4zLC05LjUgeiBtIDU0Ny44OTk5OTcsOC45IGMgMS4xLC0xLjkgMS45LC00IDIuNiwtNi4xIC0wLjEsLTAuOSAtMC4zLC0xLjkgLTAuNiwtMi44IC0wLjMsMy4zIC0xLDYuMiAtMiw4LjkgeiBtIC02LDcuMyBjIC0wLjIsMC4yIC0wLjUsMC40IC0wLjgsMC42IC0wLjQsMS4xIC0xLjIsMS45IC0yLjMsMi43IC01LjgsNC41IC0xMi41LDUuNiAtMTkuNiw1LjYgSCA0NC42ODc2NjMgYyAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjksLTEuNCAtMTIuNywtMS42IC0xNi4xLC03LjQgMCwwIC0wLjEsMCAtMC4xLC0wLjEgLTAuNiwtMC40IC0xLjEsLTAuOCAtMS43LC0xLjMgLTAuMiwwLjcgLTAuMiwxLjIgLTAuMSwxLjcgNC42LDQuNiAxMC44LDcuNSAxOCw3LjkgMi4zLDAuMSA0LjYsMC4xIDcsMC4xIEggNTMwLjk4NzY2IGMgNS4xLDAgMTAuMSwwIDE1LjEsLTEuOCA0LC0xLjUgNy4zLC0zLjUgOS45LC02IDAuMiwtMC42IDAuMywtMS4yIDAsLTEuOSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDIxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNjg3NjYzLDIxOC40NyBjIC0wLjMsLTAuNyAtMC43LC0xLjUgLTEuMSwtMi41IC0wLjMsMC40IC0wLjUsMC45IC0wLjYsMS4yIDAuNiwwLjUgMS4xLDAuOSAxLjcsMS4zIHogbSA1MzEuNTk5OTk3LC0wLjcgYyAwLjMsLTAuMiAwLjUsLTAuNCAwLjgsLTAuNiAtMC4xLC0wLjQgLTAuMywtMC44IC0wLjYsLTEuMiAwLDAuNyAtMC4xLDEuMyAtMC4yLDEuOCB6IG0gLTI0LjIsOS4xIEggNDYuODg3NjYzIGMgLTIuMywwIC00LjYsMC4xIC03LC0wLjEgLTcuMiwtMC40IC0xMy41LC0zLjMgLTE4LC03LjkgMC40LDEuMyAxLjcsMi4yIDMsMy4xIDUuOSw0LjIgMTIuNSw1LjQgMTkuNyw1LjQgMTU0LjU5OTk5NywtMC4xIDMwOS4xOTk5OTcsMCA0NjMuNzk5OTk3LDAgaCAyNy44IGMgNi4yLDAgMTEuOCwtMS44IDE2LjksLTUuNCAxLjMsLTAuOSAyLjYsLTEuOCAzLC0zIC0yLjYsMi41IC01LjksNC41IC05LjksNiAtNSwxLjkgLTEwLDEuOSAtMTUuMSwxLjkgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDM4LjQ4NzY2MywxNDIuMzcgYyAyLjQsMC42IDUuMSwwLjEgNy42LDAuMSBIIDUzNC41ODc2NiBjIDUuMywwIDEwLjYsMCAxNS4zLC0yLjkgMC43LC0xIDEuNCwtMi4xIDIuMSwtMy4xIC01LjUsMyAtMTEuNCwzLjkgLTE3LjYsMy45IC0xNjMuOCwtMC4xIC0zMjcuNSwtMC4xIC00OTEuMjk5OTk3LDAgLTcuMSwwIC0xMy41LC0xLjUgLTE5LjYsLTUuMSAzLjMsNS41IDkuNiw1LjggMTUsNy4xIHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDI1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuMjg3NjYzLDE0MC40NyBjIDE2My43OTk5OTcsLTAuMSAzMjcuNDk5OTk3LC0wLjEgNDkxLjI5OTk5NywwIDYuMiwwIDEyLjEsLTAuOCAxNy42LC0zLjkgMC43LC0wLjkgMS4zLC0xLjkgMiwtMi44IC02LjYsMy44IC0xMy44LDQuNyAtMjEuNCw0LjcgLTE2Mi42LC0wLjEgLTMyNS4yLC0wLjEgLTQ4Ny43OTk5OTcsMCAtOC4yLDAgLTE1LjYsLTEuMyAtMjIuNCwtNS44IDAuMywxLjEgMC43LDIgMS4yLDIuOCA1LjksMy42IDEyLjQsNSAxOS41LDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwMjciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NDguOTg3NjYsMTQxLjc3IGMgLTAuNCwwLjMgLTAuOCwwLjUgLTEuMiwwLjggMC4xLC0wLjEgMC4yLC0wLjEgMC40LC0wLjIgMi45LC0xLjggNS41LC0zLjggNy43LC02LjEgLTAuOCwwLjYgLTEuNiwxLjIgLTIuNSwxLjcgLTEuMiwxLjUgLTMuMSwyLjUgLTQuNCwzLjggeiBtIDExLjcsLTEyLjkgYyAtMC4zLDEuMSAtMC43LDIuMiAtMS4yLDMuMSAxLjUsLTIuMiAyLjcsLTQuNiAzLjUsLTcuMiAtMC4yLDAuNSAtMC40LDEgLTAuNiwxLjQgLTAuNiwxIC0xLjIsMS44IC0xLjcsMi43IHogbSAtMTU1LjksMTUuNiBIIDQ1Ljc4NzY2MyBjIC02LjgsMCAtMTMuNSwtMC41IC0xOS40LC00LjMgLTIuNCwtMS41IC01LC0zIC00LjQsLTYuMSAtNCwtMy40IC02LjUsLTcuOCAtOC4yLC0xMi42IC0wLjIsMy45IDEuMSw3LjMgMywxMC41IDEuMywxLjkgMi45LDMuNyA0LjksNS40IDIuNSwxLjggNSwzLjUgNy43LDQuOCA0LjEsMiA4LjQsMi41IDEyLjgsMi41IEggNTM1Ljg4NzY2IGMgMi4xLDAgNC4xLC0wLjEgNi4xLC0wLjUgLTEuOSwwLjIgLTMuOSwwLjIgLTUuOCwwLjIgLTQzLjcsMC4xIC04Ny42LDAuMSAtMTMxLjQsMC4xIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsMTM0LjE3IGMgMC4xLC0wLjUgMC4yLC0xIDAuNSwtMS41IC0zLjksLTQgLTYuMywtOC45IC04LjMsLTEzLjkgLTAuMiwxIC0wLjMsMS45IC0wLjQsMi44IDEuNyw0LjggNC4yLDkuMSA4LjIsMTIuNiB6IG0gNTQwLjI5OTk5NywtNy45IGMgMC4yLC0wLjUgMC40LC0xIDAuNiwtMS40IDAuOCwtMi43IDEuMywtNS41IDEuMiwtOC43IC0xLDMuMiAtMiw2LjQgLTMsOS43IC0wLjEsMS4xIC0wLjMsMi4xIC0wLjUsMy4xIDAuNiwtMSAxLjIsLTEuOCAxLjcsLTIuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU5LjQ4NzY2LDEzMS45NyBjIC0wLjksMS43IC0yLjEsMy4xIC0zLjYsNC40IC0yLjIsMi4yIC00LjgsNC4yIC03LjcsNi4xIC0wLjEsMC4xIC0wLjIsMC4xIC0wLjQsMC4yIC0xLjgsMS4xIC0zLjcsMS41IC01LjcsMS44IC0yLDAuMyAtNCwwLjUgLTYuMSwwLjUgSCA0Mi4yODc2NjMgYyAtNC41LDAgLTguOCwtMC41IC0xMi44LC0yLjUgLTIuNywtMS40IC01LjMsLTMgLTcuNywtNC44IC0yLC0xLjcgLTMuNiwtMy41IC00LjksLTUuNCAxLjMsMi4yIDIuOCw0LjIgNC4zLDYuMyAxLDIuNSAzLjYsMyA1LjYsNC4yIDEyLjQsMy43IDI1LjIsMi44IDM3LjksMi44IEggNTE0LjQ4NzY2IGMgMTIuNCwwIDI1LDAuOSAzNy4yLC0yLjggMi4xLC0xLjggNC4zLC0zLjUgNi4xLC01LjUgNC43LC01IDcuNywtMTAuNiA3LjIsLTE3LjMgLTAuNSwxLjcgLTEuMSwzLjQgLTEuOCw1IC0xLjEsMi40IC0yLjMsNC44IC0zLjcsNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTYyLjg4NzY2LDEyNC43NyBjIDAuNywtMS42IDEuMywtMy4zIDEuOCwtNSAtMC4xLC0xLjIgLTAuMywtMi40IC0wLjYsLTMuNyAwLjEsMy4yIC0wLjQsNi4xIC0xLjIsOC43IHogbSAtOS41LDEzLjMgYyAtMSwwLjYgLTIuMiwxLjIgLTMuNCwxLjcgLTQuOCwyLjggLTEwLDIuOSAtMTUuMywyLjkgLTE2Mi44LC0wLjEgLTMyNS43LDAgLTQ4OC40OTk5OTcsMCAtMi42LDAgLTUuMiwwLjUgLTcuNiwtMC4xIC01LjUsLTEuMyAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4yLC0wLjEgLTAuMywtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjYsMy4xIDIuMSw0LjYgNC40LDYuMSA1LjksMy44IDEyLjUsNC4zIDE5LjQsNC4zIDExOS42OTk5OTcsLTAuMSAyMzkuMjk5OTk3LDAgMzU4Ljk5OTk5NywwIGggMTMxLjUgYyAxLjksMCAzLjksMCA1LjgsLTAuMiAxLjksLTAuMyAzLjgsLTAuOSA1LjcsLTEuOCAwLjQsLTAuMiAwLjgsLTAuNSAxLjIsLTAuOCAxLjIsLTEuMyAzLjEsLTIuMyA0LjMsLTMuNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMzg3NjYzLDEzNS4yNyBjIDAuMSwwLjEgMC4yLDAuMSAwLjMsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjIsMC41IC0wLjQsMSAtMC41LDEuNSAwLjUsMC4zIDAuOSwwLjcgMS40LDEuMSB6IG0gNTI0LjM5OTk5Nyw3LjMgYyAtMS44LDAuOSAtMy43LDEuNCAtNS43LDEuOCAyLC0wLjMgMy45LC0wLjggNS43LC0xLjggeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDAzNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEyLjc4NzY2MywxMTguNTcgYyAwLC0wLjIgLTAuMSwtMC40IC0wLjEsLTAuNSAwLDEuNiAwLjEsMy4xIDAuMyw0LjcgMC4xLC0wLjcgMC4yLC0xLjQgMC41LC0yLjEgLTAuMywtMC43IC0wLjUsLTEuNCAtMC43LC0yLjEgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwMzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi43ODc2NjMsMTE4LjU3IGMgMC4yLDAuNyAwLjQsMS40IDAuNiwyIDAuMiwtMC42IDAuNCwtMS4yIDAuNywtMS45IDAsLTMuMiAtMC4xLC02LjQgLTAuMSwtOS42IC0wLjgsMy4xIC0xLjMsNiAtMS4zLDguOSAwLDAuMiAwLjEsMC40IDAuMSwwLjYgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQwNDEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMi45ODc2NjMsMTIyLjY3IGMgLTAuMiwtMS41IC0wLjMsLTMuMSAtMC4zLC00LjcgLTAuNCwtMS43IC0wLjUsLTMuNCAtMC41LC01LjEgLTMuMDk5OTk5Nyw5LjIgMC43LDIxLjIgOC44LDI1LjQgLTQuNCwtNC41IC04LjksLTkuMSAtOCwtMTUuNiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA0MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjk4NzY2MywxMDkuMTcgYyAtMC43LDEuMiAtMS4zLDIuNSAtMS44LDMuOCAwLDEuNyAwLjEsMy40IDAuNSw1LjEgMC4xLC0yLjkgMC41LC01LjkgMS4zLC04LjkgeiBtIC0wLjIsMTIuMyAtMC4zLC0wLjkgYyAtMC4yLDAuNyAtMC40LDEuNCAtMC41LDIuMSAwLjUsMy4zIDEuNyw2LjQgMy44LDkuMyAtMS45LC0zLjEgLTMuMiwtNi41IC0zLC0xMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMTMuNzg3NjYzLDEyMS40NyBjIDAsLTAuOSAwLjIsLTEuOCAwLjQsLTIuOCAtMC4zLDAuNiAtMC41LDEuMyAtMC43LDEuOSB6IG0gMywxMC42IGMgLTIsLTIuOSAtMy4yLC02IC0zLjgsLTkuMyAtMC45LDYuNSAzLjYsMTEuMSA4LDE1LjcgLTEuNSwtMi4yIC0zLC00LjMgLTQuMiwtNi40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDQ3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIC0wLjgsMC43IC0xLjYsMS4zIC0yLjQsMS45IDAsMC4zIDAsMC42IC0wLjEsMC44IDAuOCwtMC44IDEuNywtMS43IDIuNSwtMi43IHoiCiAgICAgY2xhc3M9InN0NjMiCiAgICAgaWQ9InBhdGg0MDQ5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NkY2RjZSIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2Ljc4NzY2LDEzMy4zNyBjIDEuOCwtMi4zIDMuMywtNC44IDQuNCwtNy42IC0yLjMsMi43IC00LjcsNS40IC03LDguMSAwLjEsMC42IDAuMiwxIDAuMiwxLjUgMC44LC0wLjcgMS42LC0xLjMgMi40LC0yIHogbSAtMi42LDIuOCBjIDAsLTAuMyAwLjEsLTAuNSAwLjEsLTAuOCAtMC42LDAuNCAtMS4xLDAuNyAtMS43LDEuMSAtMC4xLDAuMSAtMC4zLDAuMSAtMC40LDAuMiAtMC43LDEgLTEuNCwyLjEgLTIuMSwzLjEgMS40LC0xLjEgMi44LC0yLjMgNC4xLC0zLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTIuMTg3NjYsMTM2LjY3IGMgMC4xLC0wLjEgMC4zLC0wLjEgMC40LC0wLjIgMC42LC0wLjMgMS4yLC0wLjcgMS43LC0xLjEgMCwtMC41IC0wLjEsLTEgLTAuMiwtMS41IC0wLjYsMC45IC0xLjMsMS44IC0xLjksMi44IHogbSA0LjYsLTMuMyBjIC0wLjgsMSAtMS42LDEuOSAtMi41LDIuOCAtMC4xLDAuNyAtMC40LDEuMyAtMC45LDEuOSAwLjksLTAuNSAxLjcsLTEuMSAyLjUsLTEuNyAxLjQsLTEuNCAyLjYsLTIuOCAzLjYsLTQuNCAwLjUsLTAuOSAwLjksLTIgMS4yLC0zLjEgLTEuMiwxLjYgLTIuNSwzLjIgLTMuOSw0LjUgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjAuNjg3NjYsMTI4Ljg3IGMgMC4zLC0xIDAuNCwtMiAwLjUsLTMuMSAtMS4xLDIuOCAtMi42LDUuNCAtNC40LDcuNiAxLjQsLTEuMyAyLjcsLTIuOSAzLjksLTQuNSB6IG0gLTEuMiwzLjEgYyAtMS4xLDEuNSAtMi4zLDMgLTMuNiw0LjQgMS40LC0xLjMgMi42LC0yLjcgMy42LC00LjQgeiBtIC05LjUsNy43IGMgMS4yLC0wLjUgMi4zLC0xLjEgMy40LC0xLjcgMC40LC0wLjUgMC43LC0xLjIgMC45LC0xLjkgLTEuNCwxLjQgLTIuOCwyLjYgLTQuMywzLjYgeiIKICAgICBjbGFzcz0ic3Q2MyIKICAgICBpZD0icGF0aDQwNTUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2RjZGNlIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyOC4yODc2NjMsMzg3Ljg3IGMgMiwxLjEgNC4yLDEuOSA2LjUsMi41IEggNTQwLjI4NzY2IGMgNSwtMS45IDExLjIsLTIgMTQuMSwtNy4yIC02LjIsMy44IC0xMi45LDUuMSAtMjAuMiw1LjEgLTE2My41LC0wLjEgLTMyNy4xLC0wLjEgLTQ5MC41OTk5OTcsMCAtNi40LDAgLTEyLjUsLTAuNiAtMTguMSwtNCAtMC4xLC0wLjEgLTAuMiwtMC4xIC0wLjMsLTAuMiAxLDEuMSAyLjIsMiAyLjcsMy40IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MDU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjUuNTg3NjYzLDM4NC4yNyBjIDUuNiwzLjQgMTEuNyw0IDE4LjEsNCAxNjMuNDk5OTk3LC0wLjEgMzI3LjA5OTk5NywtMC4xIDQ5MC41OTk5OTcsMCA3LjMsMCAxNCwtMS40IDIwLjIsLTUuMSAwLjUsLTAuOCAwLjgsLTEuNyAxLjEsLTIuOCAtNi41LDQuNiAtMTMuNyw1LjkgLTIxLjYsNS45IC0xNjMuMSwtMC4xIC0zMjYuMiwtMC4xIC00ODkuMTk5OTk3LDAgLTcuNCwwIC0xNC4zLC0wLjkgLTIwLjYsLTQuNyAwLjEsMS4xIDAuNywxLjggMS4zLDIuNiAtMC4xLDAgMCwwLjEgMC4xLDAuMSB6IG0gOS4yLDYuMSBjIC0yLjMsLTAuNiAtNC41LC0xLjQgLTYuNSwtMi41IDEuOCwyIDQuMSwyLjQgNi41LDIuNSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgYyAwLjcsMi4xIDEuNyw0LjEgMi45LDUuOSAtMC42LC0xLjEgLTEuMSwtMi4zIC0xLjUsLTMuNSAtMC41LC0wLjggLTAuOSwtMS42IC0xLjQsLTIuNCB6IG0gNTQxLjA5OTk5Nyw5LjEgYyAwLjEsMC41IDAuMiwxIDAuMSwxLjQgMi41LC0yLjUgNC41LC01LjQgNS44LC04LjcgLTEuNSwyLjYgLTMuNCw1LjEgLTUuOSw3LjMgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDE0Ljk4NzY2MywzNzIuNzcgMS41LDIuNCBjIC0wLjQsLTEuNCAtMC43LC0yLjkgLTAuOSwtNC41IC0xLjksLTEuOSAtMC41LC00LjcgLTEuNiwtNi44IC0wLjQsMy4xIDAsNiAxLDguOSB6IG0gNTQ2Ljk5OTk5NywxLjcgYyAxLjMsLTMuMiAyLjEsLTYuOCAyLjEsLTEwLjYgLTEuOCw2IC00LjEsMTEuOCAtOC42LDE2LjUgMC4zLDAuNSAwLjUsMSAwLjYsMS41IDIuNSwtMi4yIDQuNCwtNC43IDUuOSwtNy40IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NTYuMTg3NjYsMzgzLjI3IGMgLTAuMywxLjkgLTIuMywzLjEgLTQsNC4xIC00LjIsMi41IC04LjcsNCAtMTMuNyw0LjMgaCAtMC42IGMgLTEuNCwwLjMgLTIuOCwwLjEgLTQuMiwwIEggNDQuMDg3NjYzIGMgLTEuMywwLjEgLTIuNywwLjMgLTQsMCBoIC0wLjYgYyAtNC4xLC0wLjMgLTguMiwtMC4zIC0xMS44LC0yLjcgLTEsLTEuMiAtMi41LC0yLjIgLTMuNCwtMy40IC0yLjgsLTEuOCAtNSwtNC4xIC02LjUsLTYuOSAtMS4zLC0xLjkgLTIuMiwtMy45IC0yLjksLTUuOSAtMC4zLC0wLjUgLTAuNiwtMC45IC0wLjgsLTEuNCAtMC43LC0xLjEgLTEuMiwtMi4zIC0xLjUsLTMuNSAwLjEsMC45IDAuMywxLjcgMC41LDIuNiAzLjUsMTQuOSAxMy4yLDIyLjYgMjguOSwyMi42IDE2NC42OTk5OTcsMCAzMjkuMzk5OTk3LDAgNDk0LjA5OTk5NywwLjEgNCwwIDcuOSwtMC44IDExLjYsLTEuOSAxMC4yLC0zLjEgMTcuNiwtMTQuMSAxNy4xLC0yMy43IC0wLjcsMi40IC0xLjYsNC43IC0yLjcsNi45IC0xLjQsMy4zIC0zLjQsNi4zIC01LjksOC44IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwNjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjEuOTg3NjYsMzc0LjQ3IGMgMS4yLC0yLjEgMiwtNC41IDIuNywtNi45IC0wLjEsLTEuMyAtMC4zLC0yLjUgLTAuNiwtMy43IDAsMy44IC0wLjgsNy40IC0yLjEsMTAuNiB6IG0gLTU0Ni45OTk5OTcsLTEuNyBjIC0wLjksLTIuOCAtMS40LC01LjggLTEuMSwtOC45IC0xLjEsMS4yIC0xLjMsMi42IC0xLjIsMy45IDAuMywxLjIgMC43LDIuNCAxLjUsMy41IDAuMiwwLjUgMC41LDEgMC44LDEuNSB6IG0gMTEsMTMuOCBjIDAuOCwwLjUgMS41LDAuOSAyLjMsMS40IGwgLTAuMywtMC4zIGMgLTAuNywtMC40IC0xLjQsLTAuOCAtMiwtMS4xIHogbSA1MzAuMDk5OTk3LC00LjcgYyAtMC40LDAuNCAtMC45LDAuOCAtMS40LDEuMiAtMC4xLDAuMSAtMC4yLDAuMSAtMC4zLDAuMiAtMi45LDUuMiAtOS4xLDUuMyAtMTQuMSw3LjIgbCAtMC42LDAuNiBjIDEuNCwtMC4xIDIuOCwtMC40IDQuMiwtMC43IDQuOSwtMS4zIDkuMSwtMy43IDEyLjQsLTcgMCwtMC42IC0wLjEsLTEgLTAuMiwtMS41IHogbSAtNTIxLjI5OTk5Nyw4LjUgYyAxLjIsMC4zIDIuNCwwLjUgMy42LDAuNiAtMC4yLC0wLjIgLTAuNSwtMC40IC0wLjcsLTAuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0Ljc4NzY2LDM4Mi45NyBjIDAuNSwtMC40IDAuOSwtMC44IDEuNCwtMS4yIC0wLjEsLTAuNSAtMC4zLC0wLjkgLTAuNiwtMS41IC0wLjMsMS4xIC0wLjYsMiAtMS4xLDIuOCAwLDAgMC4xLDAgMC4zLC0wLjEgeiBtIC01MDkuNzk5OTk3LDguNyBoIC0wLjggNDg5LjU5OTk5NyAtMC42IGMgLTE2Mi44LDAuMSAtMzI1LjUsMC4xIC00ODguMTk5OTk3LDAgeiBtIDQ5NC42OTk5OTcsLTAuOCBjIC0wLjUsMC40IC0xLjEsMC43IC0xLjcsMC44IGggMC42IGMgNC45LC0wLjMgOS41LC0xLjggMTMuNywtNC4zIDEuOCwtMS4xIDMuOCwtMi4yIDQsLTQuMSAtMy4zLDMuMyAtNy41LDUuNyAtMTIuNCw3IC0xLjUsMC4zIC0yLjksMC41IC00LjIsMC42IHogbSAtNTA0Ljg5OTk5NywtMC41IGMgLTIuNCwtMC4xIC00LjcsLTAuNSAtNi41LC0yLjUgLTAuOCwtMC40IC0xLjYsLTAuOSAtMi4zLC0xLjQgbCAtMS41LC0wLjkgYyAwLjksMS4yIDIuNCwyLjIgMy40LDMuNCAzLjYsMi40IDcuNywyLjQgMTEuOCwyLjcgaCAwLjYgYyAtMC42LC0wLjEgLTEuMiwtMC40IC0xLjcsLTAuOCAtMS40LDAgLTIuNiwtMC4zIC0zLjgsLTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDY5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIC0wLjgsLTAuNSAtMS41LC0xLjEgLTIuMSwtMS43IDAuNywwLjggMS40LDEuNiAyLjIsMi4zIC0wLjEsLTAuMSAtMC4xLC0wLjMgLTAuMSwtMC42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDcxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuNTg3NjYzLDM4My4wNyBjIDAsLTAuNSAwLjEsLTEgMC40LC0xLjYgLTMuNCwtMy4xIC02LC02LjkgLTguNSwtMTAuOSAxLjMsNC4xIDMuMyw3LjYgNiwxMC43IDAuNywwLjcgMS40LDEuMyAyLjEsMS44IHogbSA0LjQsNC41IGMgLTAuNSwtMS40IC0xLjcsLTIuMyAtMi43LC0zLjQgLTAuNiwtMC4zIC0xLjEsLTAuNiAtMS42LC0xIHYgMC42IGMgMS4zLDEuMyAyLjgsMi42IDQuMywzLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNS4yODc2NjMsMzg0LjA3IGMgLTAuNiwtMC43IC0xLjIsLTEuNSAtMS4zLC0yLjYgLTAuMiwwLjYgLTAuMywxLjEgLTAuNCwxLjYgMC42LDAuNCAxLjEsMC43IDEuNywxIHogbSAtMSwxLjMgYyAtMC4zLC0wLjUgLTAuNSwtMSAtMC42LC0xLjYgLTAuOCwtMC44IC0xLjUsLTEuNSAtMi4yLC0yLjMgLTIsLTEuOCAtMy42LC0zLjkgLTUuMSwtNi4yIDAuNCwxLjMgMC45LDIuNCAxLjUsMy41IDEuNywyLjQgMy45LDQuNyA2LjQsNi42IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MDc1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuNDg3NjYzLDM4MS4zNyBjIC0yLjYsLTMuMSAtNC43LC02LjYgLTYsLTEwLjcgMC4yLDEuNiAwLjUsMy4xIDAuOSw0LjUgMS41LDIuMyAzLjEsNC40IDUuMSw2LjIgeiBtIC0zLjYsLTIuNyBjIDEuNSwyLjggMy43LDUuMSA2LjUsNi45IC0wLjEsLTAuMSAtMC4xLC0wLjIgLTAuMiwtMC4zIC0yLjQsLTEuOCAtNC42LC00LjEgLTYuMywtNi42IHogbSA1LjgsNS4xIGMgMC4xLDAuNiAwLjMsMS4xIDAuNiwxLjYgMC42LDAuNCAxLjEsMC44IDEuNywxLjIgMC43LDAuNCAxLjMsMC43IDIsMSAtMS41LC0xLjIgLTMsLTIuNSAtNC4zLC0zLjggeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyNC4yODc2NjMsMzg1LjM3IGMgMC4xLDAuMSAwLjEsMC4yIDAuMiwwLjMgbCAxLjUsMC45IGMgLTAuNiwtMC40IC0xLjIsLTAuOCAtMS43LC0xLjIgeiIKICAgICBjbGFzcz0ic3Q2NCIKICAgICBpZD0icGF0aDQwNzkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojY2ZjZmNmIiAvPgogIDxwYXRoCiAgICAgZD0ibSAzOC40ODc2NjMsNjAuMjcgYyAxLjUsMC40IDMuMiwwLjEgNC45LDAuMSAxNjMuNzk5OTk3LDAgMzI3LjQ5OTk5NywwIDQ5MS4yOTk5OTcsMC4xIDYsMCAxMS40LC0xLjMgMTYuNiwtNC4yIDEuNiwtMC45IDMuMSwtMS45IDMuOCwtMy41IC0wLjEsMC4xIC0wLjMsMC4yIC0wLjQsMC4zIC02LjMsMy45IC0xMy4xLDUuMyAtMjAuNSw1LjMgLTE2My40LC0wLjEgLTMyNi45LC0wLjEgLTQ5MC4yOTk5OTcsMCAtNy4zLDAgLTE0LC0xLjMgLTIwLjEsLTUuMSAzLDUuMyA5LjMsNS42IDE0LjcsNyB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDA4MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQzLjc4NzY2Myw1OC4zNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjYgMC41LC0xLjQgMC41LC0yLjIgLTYuOCw0LjYgLTE0LjIsNS44IC0yMi40LDUuOCAtMTYyLjgsLTAuMSAtMzI1LjUsLTAuMSAtNDg4LjI5OTk5NywwIC04LjIsMCAtMTUuNiwtMS4zIC0yMi40LC01LjggMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuMywzLjcgMTMsNSAyMC4yLDUgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQwODMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS45ODc2NjMsNTEuODcgYyAtMi45LC0yLjUgLTUuMSwtNS41IC02LjYsLTguOCAxLjQsNC4yIDMuNyw3LjggNi45LDExIC0wLjQsLTAuNiAtMC41LC0xLjMgLTAuMywtMi4yIHogbSA1MTAuMTk5OTk3LDEwLjUgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjI5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzUuNzg3NjYgYyA0LjUsMCA4LjgsLTAuNSAxMi44LC0yLjUgMS40LC0wLjcgMi43LC0xLjcgNCwtMi43IC0zLjksMi45IC04LjUsNC40IC0xMy40LDQuOCAtMi40LDAuMiAtNC43LDAuMSAtNywwLjEgeiBtIDMyLjEsLTIzIGMgLTEuNyw0LjggLTQuMiw5LjIgLTguMiwxMi42IDAuNCwxLjkgLTAuNiwzLjIgLTEuOSw0LjMgMC42LC0wLjUgMS4zLC0wLjkgMiwtMS4zIDIuNCwtMS43IDQuMywtMy44IDUuOCwtNi4yIDEuNSwtMi45IDIuNCwtNiAyLjMsLTkuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MDg1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuOTg3NjYzLDUxLjg3IGMgMC4xLC0wLjQgMC4zLC0wLjkgMC41LC0xLjQgLTQuNSwtNC43IC03LjIsLTEwLjMgLTguNiwtMTYuNSAwLDMuMyAwLjUsNi40IDEuNCw5LjIgMS42LDMuMyAzLjgsNi4yIDYuNyw4LjcgeiBNIDU2NC4yODc2NiwzOS4zNyBjIDAsLTAuOSAtMC4yLC0xLjggLTAuNCwtMi44IC0yLjEsNS4xIC00LjQsMTAgLTguMywxMy45IDAuMywwLjUgMC41LDEgMC42LDEuNCAzLjksLTMuNCA2LjMsLTcuNyA4LjEsLTEyLjUgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU1Ni4xODc2Niw1NC44NyBjIC0wLjcsMC40IC0xLjMsMC44IC0yLDEuMyAtMC41LDAuNCAtMSwwLjggLTEuNSwxLjEgbCAtMC4xLDAuMSBjIC0xLjMsMSAtMi41LDEuOSAtNCwyLjcgLTQsMiAtOC4zLDIuNSAtMTIuOCwyLjUgSCA0MS45ODc2NjMgYyAtNC4yLDAgLTguMywtMC41IC0xMi4yLC0yLjQgLTAuOSwtMC42IC0xLjcsLTEuMSAtMi41LC0xLjcgLTAuNiwtMC40IC0xLjMsLTAuOCAtMS45LC0xLjIgLTEuMywtMC45IC0yLjYsLTEuOSAtMy4zLC0zLjEgLTMuMSwtMy4yIC01LjUsLTYuOCAtNi45LC0xMSAtMS4xLC0yLjIgLTEuOSwtNC42IC0yLjUsLTcuMiAtMC4zLDEuNCAwLjEsMyAwLjMsNC41IDEuMyw4LjggNi42LDE0LjkgMTMuNCwxOS45IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjM4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjgsLTEuNCAzLjcsLTIuOCA1LjUsLTQuMiAxLjgsLTIuNCAzLjYsLTQuOSA1LC03LjUgLTEuMywyLjQgLTMuMiw0LjUgLTUuNiw2LjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA4OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDEzLjg4NzY2MywzMy45NyBjIC0wLjYsMC42IC0wLjksMS4zIC0xLjEsMiAwLjYsMi41IDEuNCw0LjkgMi41LDcuMiAtMC45LC0yLjggLTEuNCwtNS45IC0xLjQsLTkuMiB6IG0gNTQyLjE5OTk5NywxNy45IGMgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy41LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjUsLTEuNCAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC45IC0wLjEsMS42IDAuMiwyLjIgMS41LDEuNiAzLjMsMyA1LjEsNC40IDUuNiwzLjQgMTIsMy45IDE4LjYsMy45IDE2Mi4wOTk5OTcsLTAuMSAzMjQuMTk5OTk3LC0wLjEgNDg2LjI5OTk5NywtMC4xIDIuMywwIDQuNiwwLjEgNywtMC4xIDQuOSwtMC40IDkuNSwtMS45IDEzLjQsLTQuOCAwLjUsLTAuNCAxLjEsLTAuOCAxLjYsLTEuMiAxLjQsLTEgMi40LC0yLjMgMiwtNC4yIHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQwOTEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMy4yODc2NjMsNTMuMDcgYyAwLjEsMC4xIDAuMywwLjEgMC40LDAuMiAtMC41LC0wLjggLTAuOSwtMS43IC0xLjIsLTIuOCAtMC4zLDAuNSAtMC40LDEgLTAuNSwxLjQgMC40LDAuNCAwLjgsMC44IDEuMywxLjIgeiBtIDUzMi43OTk5OTcsLTEuMiBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjUsMi4yIDAuNSwtMC4yIDAuOCwtMC41IDEuMSwtMC44IHogbSAtMy40LDUuNSBjIDAuNSwtMC40IDEsLTAuNyAxLjUsLTEuMSAtMC42LDAuNCAtMS4xLDAuOCAtMS42LDEuMiAwLC0wLjEgMCwtMC4xIDAuMSwtMC4xIHogTSAyNS4zODc2NjMsNTcuMjcgYyAwLjYsMC41IDEuMiwwLjkgMS45LDEuMiAtMS45LC0xLjQgLTMuNiwtMi44IC01LjEsLTQuNCAwLjYsMS4zIDIsMi4zIDMuMiwzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDA5MyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC41ODc2NiwzOC40NyBjIDAuMiwwLjYgMC4zLDEuMiAwLjQsMS44IDAuMiwtMS40IDAuMywtMi45IDAuMywtNC40IDAsMC4yIDAsMC4zIC0wLjEsMC41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MDk1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDM4LjQ3IGMgMC4yLC0wLjcgMC41LC0xLjQgMC43LC0yLjEgMCwtMC4yIDAsLTAuMyAwLjEsLTAuNSAwLC0yLjggLTAuNCwtNS44IC0xLjMsLTguOSAwLDMuMiAtMC4xLDYuNCAtMC4xLDkuNiAwLjIsMC43IDAuNCwxLjMgMC42LDEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5NyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAsMS41IC0wLjEsMyAtMC4zLDQuNCAxLjEsNi42IC0zLjUsMTEuMyAtOCwxNS45IDguMiwtNC4yIDEyLC0xNi4zIDguOCwtMjUuNiAwLDEuOCAtMC4xLDMuNiAtMC41LDUuMyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDA5OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwzNS44NyBjIDAuNCwtMS44IDAuNSwtMy41IDAuNCwtNS4zIC0wLjQsLTEuMyAtMSwtMi41IC0xLjcsLTMuNiAwLjksMy4xIDEuMyw2LjEgMS4zLDguOSB6IG0gLTEsMy41IGMgMC4yLDMuNSAtMC44LDYuNSAtMi4zLDkuNCAxLjUsLTIuNSAyLjYsLTUuMyAzLC04LjQgLTAuMSwtMC42IC0wLjIsLTEuMiAtMC40LC0xLjggLTAuMSwwLjIgLTAuMiwwLjUgLTAuMywwLjggeiBtIC0wLjQsLTIuOCBjIDAuMiwwLjkgMC4zLDEuOSAwLjQsMi44IGwgMC4zLC0wLjkgYyAtMC4yLC0wLjYgLTAuNCwtMS4yIC0wLjcsLTEuOSB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEwMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC45ODc2Niw0MC4yNyBjIC0wLjUsMy4xIC0xLjUsNS45IC0zLDguNCAtMS40LDIuNiAtMy4yLDUgLTUsNy41IDQuNSwtNC42IDksLTkuMyA4LC0xNS45IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTAzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDMwOC4wNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTQsLTEuMyAtMjAuMSwtNS4xIDMsNS4zIDkuMyw1LjYgMTQuNyw3IHoiCiAgICAgY2xhc3M9InN0NjEiCiAgICAgaWQ9InBhdGg0MTA1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2JkYmRiZCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNDMuODg3NjYzLDMwNi4xNyBjIDE2My4zOTk5OTcsLTAuMSAzMjYuODk5OTk3LC0wLjEgNDkwLjI5OTk5NywwIDcuNCwwIDE0LjIsLTEuNCAyMC41LC01LjMgMC4xLC0wLjEgMC4zLC0wLjIgMC40LC0wLjMgMC4zLC0wLjcgMC41LC0xLjQgMC40LC0yLjMgLTYuNiw0LjQgLTEzLjcsNS45IC0yMS43LDUuOSAtMTYzLjIsLTAuMSAtMzI2LjUsLTAuMSAtNDg5LjY5OTk5NywwIC04LDAgLTE1LjEsLTEuNSAtMjEuNywtNS45IDAuMywxLjEgMC43LDIgMS4yLDIuOCA2LjMsMy44IDEzLDUuMSAyMC4zLDUuMSB6IgogICAgIGNsYXNzPSJzdDYxIgogICAgIGlkPSJwYXRoNDEwNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNiZGJkYmQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDUzMi4xODc2NiwzMTAuMTcgYyAtMTYyLjEsMCAtMzI0LjIsMCAtNDg2LjM5OTk5NywwLjEgLTYuNiwwIC0xMi45LC0wLjUgLTE4LjYsLTMuOSAwLjgsMC42IDEuNywxLjIgMi41LDEuNyAzLjgsMS45IDcuOSwyLjQgMTIuMiwyLjQgSCA1MzYuMDg3NjYgYyA0LjMsMCA4LjMsLTAuNiAxMi4xLC0yLjQgMS42LC0wLjggMywtMS44IDQuMywtMi45IC00LDIuOSAtOC42LDQuNSAtMTMuNSw0LjkgLTIuMSwwLjIgLTQuNSwwLjEgLTYuOCwwLjEgeiBtIDIzLjksLTEwLjUgYyAwLjQsMS42IC0wLjMsMi43IC0xLjMsMy43IDEuMywtMS4xIDIuNiwtMi4zIDQsLTMuNSAxLjUsLTEuNCAyLjcsLTIuOSAzLjcsLTQuNSAxLjEsLTIuNiAxLjksLTUuMyAxLjgsLTguMiAtMS44LDQuOCAtNC4yLDkuMiAtOC4yLDEyLjUgeiBtIC01MzQuMTk5OTk3LDAgYyAtMi45LC0yLjUgLTUsLTUuNSAtNi42LC04LjggMS40LDQuMiAzLjcsNy44IDYuOCwxMSAtMC4yLC0wLjYgLTAuMywtMS4zIC0wLjIsLTIuMiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTA5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjE4NzY2LDI4Ny4yNyBjIDAsLTAuOSAtMC4xLC0xLjkgLTAuNCwtMi45IC0yLDUuMSAtNC41LDkuOSAtOC4zLDEzLjkgMC4zLDAuNSAwLjUsMSAwLjYsMS40IDQsLTMuMyA2LjQsLTcuNyA4LjEsLTEyLjQgeiBtIC01NDIuMjk5OTk3LDEyLjQgYyAwLjEsLTAuNCAwLjMsLTAuOSAwLjYsLTEuNCAtNC40LC00LjcgLTcuMywtMTAuMiAtOC42LC0xNi41IDAsMy4zIDAuNSw2LjQgMS40LDkuMiAxLjYsMy4yIDMuNyw2LjIgNi42LDguNyB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTExIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU4Ljc4NzY2LDI5OS45NyBjIC0xLjMsMS4yIC0yLjYsMi4zIC00LDMuNSAtMC41LDAuNSAtMS4xLDEgLTEuNywxLjQgLTAuMSwwLjEgLTAuMiwwLjIgLTAuNCwwLjMgLTEuNCwxLjEgLTIuOCwyLjEgLTQuMywyLjkgLTMuOCwxLjggLTcuOSwyLjQgLTEyLjEsMi40IEggNDIuMDg3NjYzIGMgLTQuMiwwIC04LjMsLTAuNSAtMTIuMiwtMi40IC0wLjksLTAuNiAtMS43LC0xLjEgLTIuNSwtMS43IC0wLjYsLTAuNCAtMS4zLC0wLjggLTEuOSwtMS4zIC0xLjIsLTAuOSAtMi42LC0xLjkgLTMuMiwtMy4xIC0zLjEsLTMuMiAtNS41LC02LjggLTYuOCwtMTEgLTEuMSwtMi4zIC0xLjksLTQuNiAtMi41LC03LjIgLTAuMywxLjQgMC4xLDMgMC4zLDQuNSAxLjMsOC44IDYuNiwxNC45IDEzLjQsMTkuOSAxMi4yLDMuNyAyNC43LDIuOCAzNy4yLDIuOCBIIDUxMy42ODc2NiBjIDEyLjcsMCAyNS40LDAuOSAzNy45LC0yLjggMi44LC0yLjMgNS41LC00LjYgOC4zLC03IDAuOSwtMS45IDEuOSwtMy44IDIuNywtNS44IC0xLjEsMS43IC0yLjMsMy4yIC0zLjgsNC42IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMTMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsMjgxLjc3IGMgLTAuNiwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNiwyLjUgMS40LDQuOSAyLjUsNy4yIC0wLjksLTIuOCAtMS40LC01LjkgLTEuNCwtOS4yIHogbSA1NDIuMTk5OTk3LDE3LjkgYyAtMC4zLDAuMyAtMC43LDAuNiAtMSwwLjggLTAuNywxLjYgLTIuMiwyLjYgLTMuOCwzLjUgLTUuMiwyLjkgLTEwLjYsNC4yIC0xNi42LDQuMiAtMTYzLjgsLTAuMSAtMzI3LjYsLTAuMSAtNDkxLjI5OTk5NywtMC4xIC0xLjYsMCAtMy4zLDAuMyAtNC45LC0wLjEgLTUuNCwtMS41IC0xMS43LC0xLjcgLTE0LjgsLTcgLTAuMSwtMC4xIC0wLjMsLTAuMSAtMC40LC0wLjIgLTAuNSwtMC40IC0wLjksLTAuOCAtMS40LC0xLjIgLTAuMiwwLjggLTAuMSwxLjYgMC4yLDIuMiAxLjUsMS42IDMuMywzIDUuMSw0LjQgNS42LDMuNCAxMiwzLjkgMTguNiwzLjkgMTYyLjA5OTk5NywtMC4xIDMyNC4xOTk5OTcsLTAuMSA0ODYuMzk5OTk3LC0wLjEgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNiwtMiAxMy41LC00LjkgMC4xLC0wLjEgMC4yLC0wLjIgMC40LC0wLjMgMC42LC0wLjUgMS4xLC0wLjkgMS43LC0xLjQgMSwtMC44IDEuNywtMiAxLjMsLTMuNiB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU2LjA4NzY2LDI5OS42NyBjIC0wLjEsLTAuNCAtMC4zLC0wLjkgLTAuNiwtMS40IDAsMC45IC0wLjIsMS42IC0wLjQsMi4zIDAuMywtMC4zIDAuNywtMC42IDEsLTAuOSB6IG0gLTUzMi43OTk5OTcsMS4yIGMgMC4xLDAuMSAwLjMsMC4xIDAuNCwwLjIgLTAuNSwtMC44IC0wLjksLTEuOCAtMS4yLC0yLjggLTAuMywwLjUgLTAuNSwxIC0wLjYsMS40IDAuNSwwLjQgMC45LDAuOCAxLjQsMS4yIHogbSAyLjEsNC4yIGMgMC42LDAuNSAxLjMsMC45IDEuOSwxLjMgLTEuOSwtMS40IC0zLjYsLTIuOCAtNS4xLC00LjQgMC42LDEuMiAyLDIuMSAzLjIsMy4xIHogbSA1MjkuMzk5OTk3LC0xLjYgYyAtMC42LDAuNSAtMS4xLDAuOSAtMS43LDEuNCAwLjYsLTAuNSAxLjIsLTAuOSAxLjcsLTEuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTE3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY0LjU4NzY2LDI4Ni4wNyBjIDAuMiwwLjYgMC40LDEuMiAwLjUsMS44IDAuMiwtMS40IDAuMiwtMi44IDAuMiwtNC4yIDAsMC4yIC0wLjEsMC40IC0wLjEsMC42IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTE5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjE4NzY2LDI4NC4yNyBjIDAuMSwtMC4yIDAuMSwtMC40IDAuMSwtMC42IC0wLjEsLTIuNCAtMC41LC00LjkgLTEuMiwtNy40IGwgLTAuMyw4LjEgYyAwLjMsMC42IDAuNiwxLjEgMC44LDEuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4xODc2NiwyODcuODcgYyAwLjksNS4xIC0yLjQsOS4yIC01LjQsMTMuNCA2LjUsLTUuNSA4LjksLTE1LjIgNiwtMjIuMiAwLDEuNSAtMC4xLDMuMSAtMC40LDQuNiAwLDEuNCAtMC4xLDIuOCAtMC4yLDQuMiB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDEyMyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NS4yODc2NiwyODMuNTcgYyAwLjMsLTEuNSAwLjQsLTMuMSAwLjQsLTQuNiAtMC40LC0xIC0xLC0yIC0xLjYsLTIuOCAwLjcsMi42IDEuMSw1IDEuMiw3LjQgeiBtIC0xLjEsMy43IGMgMC4xLDIuOSAtMC43LDUuNiAtMS44LDguMiAxLjUsLTIuNCAyLjMsLTUgMi43LC03LjYgLTAuMSwtMC42IC0wLjMsLTEuMiAtMC41LC0xLjggLTAuMSwwLjQgLTAuMiwwLjggLTAuNCwxLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxMjUiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjQuNTg3NjYsMjg2LjA3IGMgLTAuMiwtMC42IC0wLjQsLTEuMSAtMC44LC0xLjcgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAuMiwtMC40IDAuMywtMC44IDAuNCwtMS4yIHogbSAwLjYsMS44IGMgLTAuNCwyLjcgLTEuMiw1LjIgLTIuNyw3LjYgLTAuOCwxLjkgLTEuOCwzLjggLTIuNyw1LjggMi45LC00LjIgNi4zLC04LjMgNS40LC0xMy40IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTI3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMzguNDg3NjYzLDQ3Mi4zNyBjIDEuNSwwLjQgMy4yLDAuMSA0LjksMC4xIDE2My43OTk5OTcsMCAzMjcuNTk5OTk3LDAgNDkxLjI5OTk5NywwLjEgNiwwIDExLjQsLTEuMyAxNi42LC00LjIgMS42LC0wLjkgMy4xLC0xLjkgMy44LC0zLjUgLTAuMSwwLjEgLTAuMywwLjIgLTAuNCwwLjMgLTYuMywzLjkgLTEzLjEsNS4zIC0yMC41LDUuMyAtMTYzLjQsLTAuMSAtMzI2LjksLTAuMSAtNDkwLjI5OTk5NywwIC03LjMsMCAtMTMuOSwtMS4zIC0yMC4xLC01LjEgMyw1LjMgOS4zLDUuNSAxNC43LDcgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMjkiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSA0My43ODc2NjMsNDcwLjQ3IGMgMTYzLjM5OTk5NywtMC4xIDMyNi44OTk5OTcsLTAuMSA0OTAuMjk5OTk3LDAgNy40LDAgMTQuMiwtMS40IDIwLjUsLTUuMyAwLjEsLTAuMSAwLjMsLTAuMiAwLjQsLTAuMyAwLjMsLTAuNyAwLjUsLTEuNCAwLjQsLTIuMyAtNi42LDQuNCAtMTMuNyw1LjkgLTIxLjcsNS45IC0xNjMuMiwtMC4xIC0zMjYuNSwtMC4xIC00ODkuNjk5OTk3LDAgLTgsMCAtMTUuMSwtMS41IC0yMS43LC01LjkgMC4zLDEuMSAwLjcsMiAxLjIsMi44IDYuNCwzLjcgMTMuMSw1LjEgMjAuMyw1LjEgeiIKICAgICBjbGFzcz0ic3Q2MSIKICAgICBpZD0icGF0aDQxMzEiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojYmRiZGJkIiAvPgogIDxwYXRoCiAgICAgZD0ibSAyMS44ODc2NjMsNDYzLjk3IGMgLTMuMSwtMi43IC01LjQsLTYgLTcsLTkuNiAxLjQsNC41IDMuOSw4LjMgNy4yLDExLjcgLTAuMiwtMC42IC0wLjMsLTEuMyAtMC4yLC0yLjEgeiBtIDU0Mi4yOTk5OTcsLTEyLjUgYyAtMS43LDQuOCAtNC4yLDkuMSAtOC4xLDEyLjUgMC42LDIuNSAtMS41LDQgLTMuMyw1LjQgLTQsMi45IC04LjYsNC41IC0xMy42LDQuOSAtMi4zLDAuMiAtNC42LDAuMSAtNywwLjEgLTE2Mi4xLDAgLTMyNC4zLDAgLTQ4Ni4zOTk5OTcsMC4xIC03LDAgLTEzLjcsLTAuNiAtMTkuNSwtNC41IDEuMSwwLjkgMi4yLDEuOCAzLjQsMi43IDQuMiwxLjcgOC41LDIuMSAxMywyLjEgSCA1MzUuMjg3NjYgYyA0LjcsMCA5LjIsLTAuNSAxMy42LC0yLjMgMS45LC0xLjQgMy43LC0yLjkgNS44LC00IDIuNywtMS42IDQuOSwtMy44IDYuNiwtNi41IDEuOSwtMy4yIDMuMSwtNi42IDIuOSwtMTAuNSB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjEuODg3NjYzLDQ2My45NyBjIDAuMSwtMC40IDAuMywtMC45IDAuNiwtMS40IC00LjQsLTQuNyAtNy4zLC0xMC4yIC04LjYsLTE2LjUgLTAuMSwzLjEgMC4zLDUuOCAxLjEsOC40IDEuNiwzLjYgMy44LDYuOCA2LjksOS41IHogbSA1NDIuMjk5OTk3LC0xMi41IGMgMCwtMC45IC0wLjIsLTEuOSAtMC40LC0yLjkgLTIsNS4xIC00LjUsOS45IC04LjMsMTMuOSAwLjMsMC41IDAuNSwxIDAuNiwxLjQgNCwtMy4zIDYuNCwtNy42IDguMSwtMTIuNCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTU0LjY4NzY2LDQ2OC40NyBjIC0yLjEsMS4xIC0zLjksMi42IC01LjgsNCAtNC4zLDEuOCAtOC45LDIuMyAtMTMuNiwyLjMgSCA0Mi42ODc2NjMgYyAtNC41LDAgLTguOCwtMC40IC0xMywtMi4xIC0xLjIsLTAuOSAtMi4zLC0xLjcgLTMuNCwtMi43IC0wLjMsLTAuMiAtMC42LC0wLjQgLTAuOSwtMC43IC0xLjMsLTEgLTIuNywtMS45IC0zLjMsLTMuMiAtMy4zLC0zLjQgLTUuOCwtNy4yIC03LjIsLTExLjcgLTAuOSwtMiAtMS42LC00LjIgLTIuMSwtNi40IC0wLjYsMS45IC0wLjEsMy45IDAuNCw1LjkgMS44LDguMSA3LDEzLjggMTMuNCwxOC42IDEyLjIsMy43IDI0LjcsMi44IDM3LjIsMi44IEggNTEzLjU4NzY2IGMgMTIuNywwIDI1LjQsMC45IDM3LjksLTIuOCAxLjQsLTAuOSAyLjgsLTEuOSA0LjEsLTIuOCAyLC0yLjUgNC4xLC01IDUuNywtNy43IC0xLjcsMi42IC0zLjksNC44IC02LjYsNi41IHoiCiAgICAgY2xhc3M9InN0NSIKICAgICBpZD0icGF0aDQxMzciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZDRkNGQ0IiAvPgogIDxwYXRoCiAgICAgZD0ibSAxMy44ODc2NjMsNDQ2LjA3IGMgLTAuNSwwLjYgLTAuOSwxLjMgLTEuMSwyIDAuNSwyLjIgMS4yLDQuNCAyLjEsNi40IC0wLjcsLTIuNiAtMS4xLC01LjQgLTEsLTguNCB6IG0gNTE4LjM5OTk5NywyOC40IGMgMi4zLDAgNC42LDAuMSA3LC0wLjEgNSwtMC40IDkuNSwtMiAxMy42LC00LjkgMS45LC0xLjQgMy45LC0yLjkgMy4zLC01LjQgLTAuMywwLjMgLTAuNywwLjYgLTEsMC44IC0wLjcsMS42IC0yLjIsMi42IC0zLjgsMy41IC01LjIsMi45IC0xMC42LDQuMiAtMTYuNiw0LjIgLTE2My44LC0wLjEgLTMyNy42LC0wLjEgLTQ5MS4yOTk5OTcsLTAuMSAtMS42LDAgLTMuMywwLjMgLTQuOSwtMC4xIC01LjQsLTEuNSAtMTEuNywtMS43IC0xNC44LC03IC0wLjEsLTAuMSAtMC4zLC0wLjEgLTAuNCwtMC4yIC0wLjUsLTAuNCAtMC45LC0wLjggLTEuNCwtMS4yIC0wLjIsMC44IC0wLjEsMS41IDAuMiwyLjEgMS4zLDEuNCAyLjcsMi42IDQuMiwzLjkgNS45LDMuOSAxMi41LDQuNSAxOS41LDQuNSAxNjIuMDk5OTk3LC0wLjEgMzI0LjE5OTk5NywwIDQ4Ni4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDUiCiAgICAgaWQ9InBhdGg0MTM5IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2Q0ZDRkNCIgLz4KICA8cGF0aAogICAgIGQ9Im0gMjMuMjg3NjYzLDQ2NS4xNyBjIDAuMSwwLjEgMC4zLDAuMSAwLjQsMC4yIC0wLjUsLTAuOCAtMC45LC0xLjcgLTEuMiwtMi44IC0wLjMsMC41IC0wLjUsMSAtMC42LDEuNCAwLjUsMC40IDAuOSwwLjggMS40LDEuMiB6IG0gNTMyLjc5OTk5NywtMS4yIGMgLTAuMSwtMC40IC0wLjMsLTAuOSAtMC42LC0xLjQgMCwwLjkgLTAuMiwxLjYgLTAuNCwyLjMgMC4zLC0wLjMgMC43LC0wLjYgMSwtMC45IHogbSAtNTMwLjY5OTk5Nyw1LjMgYyAwLjMsMC4yIDAuNiwwLjQgMC45LDAuNyAtMS41LC0xLjIgLTIuOSwtMi41IC00LjIsLTMuOSAwLjYsMS4zIDIsMi4zIDMuMywzLjIgeiIKICAgICBjbGFzcz0ic3Q1IgogICAgIGlkPSJwYXRoNDE0MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNkNGQ0ZDQiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgYyAwLjIsMC44IDAuMywxLjUgMC40LDIuMyAwLjQsLTEuOCAwLjUsLTMuNiAwLjUsLTUuNSAtMC4xLDAuMyAtMC4xLDAuNiAtMC4yLDEgLTAuMiwwLjYgLTAuNCwxLjQgLTAuNywyLjIgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDMiCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjUuMTg3NjYsNDQ4LjQ3IGMgMC4xLC0wLjMgMC4xLC0wLjYgMC4yLC0xIDAsLTIuOCAtMC41LC01LjcgLTEuNCwtOC40IC0wLjEsMy4yIC0wLjEsNi40IC0wLjIsOS41IDAuMywwLjcgMC41LDEuNCAwLjYsMi4xIDAuNCwtMC43IDAuNiwtMS41IDAuOCwtMi4yIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTQ1IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTY1LjM4NzY2LDQ0Ny40NyBjIDAsMS45IC0wLjIsMy43IC0wLjUsNS41IDAuNSw1LjggLTIuNiwxMS4yIC05LjMsMTYuNyA3LjksLTMuNCAxMC40LC0xMC41IDExLC0xOCAwLjMsLTMuNiAxLjksLTcuOSAtMC45LC0xMS4yIDAuMSwyLjMgMC4xLDQuNyAtMC4zLDcgeiIKICAgICBjbGFzcz0ic3Q2MiIKICAgICBpZD0icGF0aDQxNDciCiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICBzdHlsZT0iZmlsbDojZThlOGU4IiAvPgogIDxwYXRoCiAgICAgZD0ibSA1NjMuOTg3NjYsNDM5LjA3IGMgMC45LDIuOCAxLjMsNS42IDEuNCw4LjQgMC40LC0yLjMgMC40LC00LjcgMC4yLC03LjEgLTAuNCwtMC40IC0wLjksLTAuOSAtMS42LC0xLjMgeiBtIDAuMiwxMi40IGMgMC4yLDQgLTEuMSw3LjMgLTMsMTAuNSAxLjcsLTIuNiAyLjksLTUuNyAzLjYsLTguOSAtMC4xLC0wLjggLTAuMiwtMS41IC0wLjQsLTIuMyAwLDAuMiAtMC4xLDAuNCAtMC4yLDAuNyB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE0OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDU2NC40ODc2Niw0NTAuNzcgLTAuNiwtMi4xIGMgMC4yLDEgMC4zLDEuOSAwLjQsMi45IDAsLTAuNCAwLjEsLTAuNiAwLjIsLTAuOCB6IG0gMC40LDIuMiBjIC0wLjYsMy4yIC0xLjksNi4zIC0zLjYsOC45IC0xLjYsMi43IC0zLjcsNS4yIC01LjcsNy43IDYuNywtNS40IDkuNywtMTAuOCA5LjMsLTE2LjYgeiBtIC01MjIuMTk5OTk3LDIzIGMgLTUuNywwIC0xMSwtMS4xIC0xNi4xLC0zLjUgMy44LDQuMyA4LjksNC4yIDE0LDQuMiBIIDUzNi43ODc2NiBjIDUuMywwIDEwLjYsMC4yIDE0LjcsLTQuMiAtNS4xLDIuNCAtMTAuNSwzLjUgLTE2LjEsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUxIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTEzLjU4NzY2LDQ3NS4yNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuMSwyLjQgMTAuNCwzLjUgMTYuMSwzLjUgSCA1MzUuMjg3NjYgYyA1LjcsMCAxMSwtMS4xIDE2LjEsLTMuNSAtMTIuNCwzLjcgLTI1LjEsMi44IC0zNy44LDIuOCB6IG0gMTkuNiwtMTYzLjUgYyAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIC02LjQsMCAtMTIuNCwtMSAtMTguMiwtMy41IDMuNywzLjMgOC4xLDQuMiAxMi44LDQuMiBIIDUzOC41ODc2NiBjIDQuNywwIDkuMiwtMC45IDEyLjgsLTQuMiAtNS44LDIuNSAtMTEuOCwzLjUgLTE4LjIsMy41IHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTUzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTMzLjE4NzY2LDMxMS43NyBjIDYuNCwwIDEyLjQsLTEgMTguMiwtMy41IC0xMi40LDMuNyAtMjUuMiwyLjggLTM3LjksMi44IEggNjMuNjg3NjYzIGMgLTEyLjQsMCAtMjUsMC45IC0zNy4yLC0yLjggNS44LDIuNiAxMS44LDMuNSAxOC4yLDMuNSAxNjIuODk5OTk3LC0wLjEgMzI1LjY5OTk5NywtMC4xIDQ4OC40OTk5OTcsMCB6IE0gNDQuNzg3NjYzLDYzLjk3IGMgLTYuNCwwIC0xMi40LC0xIC0xOC4yLC0zLjUgMy43LDMuMyA4LjEsNC4yIDEyLjgsNC4yIEggNTM4LjU4NzY2IGMgNC43LDAgOS4yLC0wLjkgMTIuOCwtNC4yIC01LjgsMi42IC0xMS44LDMuNSAtMTguMiwzLjUgLTE2Mi44LC0wLjEgLTMyNS42LC0wLjEgLTQ4OC4zOTk5OTcsMCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJNIDUxMy41ODc2Niw2My4xNyBIIDYzLjc4NzY2MyBjIC0xMi40LDAgLTI1LDAuOSAtMzcuMiwtMi44IDUuOCwyLjYgMTEuOCwzLjUgMTguMiwzLjUgMTYyLjc5OTk5NywtMC4xIDMyNS41OTk5OTcsLTAuMSA0ODguMzk5OTk3LDAgNi40LDAgMTIuNCwtMSAxOC4yLC0zLjUgLTEyLjQsMy43IC0yNS4xLDIuOCAtMzcuOCwyLjggeiBtIC00NjguNzk5OTk3LDgyLjkgYyAtNi40LDAgLTEyLjQsLTEgLTE4LjIsLTMuNSAzLjcsMy4zIDguMSw0LjIgMTIuOCw0LjIgSCA1MzguNTg3NjYgYyA0LjcsMCA5LjIsLTAuOSAxMi44LC00LjIgLTUuOCwyLjUgLTExLjgsMy41IC0xOC4yLDMuNSAtMTYyLjgsLTAuMSAtMzI1LjYsLTAuMSAtNDg4LjM5OTk5NywwIHoiCiAgICAgY2xhc3M9InN0NjIiCiAgICAgaWQ9InBhdGg0MTU3IgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2U4ZThlOCIgLz4KICA8cGF0aAogICAgIGQ9Ik0gNTE0LjI4NzY2LDE0NS4yNyBIIDY0LjQ4NzY2MyBjIC0xMi43LDAgLTI1LjQsMC45IC0zNy45LC0yLjggNS44LDIuNSAxMS44LDMuNSAxOC4yLDMuNSAxNjIuNzk5OTk3LC0wLjEgMzI1LjU5OTk5NywtMC4xIDQ4OC4zOTk5OTcsMCA2LjQsMCAxMi40LC0xIDE4LjIsLTMuNSAtMTIuMSwzLjggLTI0LjcsMi44IC0zNy4xLDIuOCB6IgogICAgIGNsYXNzPSJzdDYyIgogICAgIGlkPSJwYXRoNDE1OSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNlOGU4ZTgiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQwLjI4NzY2MywzOTEuMDcgaCAxLjYgYyAxLjEsMCAyLjIsLTAuMiAzLjMsLTAuMiBIIDUzMi43ODc2NiBjIDAuOCwwIDEuNiwwLjEgMi40LDAuMSAxLjEsMCAyLjIsLTAuMSAzLjMsLTAuMSAwLjYsLTAuMSAxLjIsLTAuMyAxLjgsLTAuNyBIIDM3LjY4NzY2MyBjIDAuOSwwLjYgMS44LDAuOSAyLjYsMC45IHogbSA0OTguMTk5OTk3LC0wLjEgYyAtMS4xLDAuMSAtMi4yLDAuMSAtMy4zLDAuMSAxLjEsMC4xIDIuMiwwLjIgMy4zLC0wLjEgeiBtIC00OTQuMzk5OTk3LDAuNyBoIC00IGMgMS4zLDAuMyAyLjcsMC4xIDQsMCB6IG0gNDkzLjc5OTk5NywwIGggLTQuMiBjIDEuNCwwLjEgMi45LDAuMyA0LjIsMCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2MSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+CiAgPHBhdGgKICAgICBkPSJtIDQ1LjE4NzY2MywzOTAuOTcgYyAtMS4xLDAgLTIuMiwwLjEgLTMuMywwLjIgSCA1MzUuMDg3NjYgYyAtMC44LDAgLTEuNiwtMC4xIC0yLjQsLTAuMSAtMTYyLjQsMCAtMzI0LjksMCAtNDg3LjQ5OTk5NywtMC4xIHogbSA0OTQuNDk5OTk3LC0wLjEgYyAwLjIsLTAuMiAwLjQsLTAuMyAwLjYsLTAuNiAtMC42LDAuMyAtMS4yLDAuNSAtMS44LDAuNyAwLjQsMCAwLjgsMCAxLjIsLTAuMSB6IG0gLTUwMS45OTk5OTcsLTAuNSBjIDAuMiwwLjMgMC41LDAuNSAwLjcsMC42IDAuNCwwIDAuNywwLjEgMS4xLDAuMSBoIDAuOCBjIC0wLjgsMCAtMS43LC0wLjMgLTIuNiwtMC43IHoiCiAgICAgY2xhc3M9InN0NjQiCiAgICAgaWQ9InBhdGg0MTYzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc3R5bGU9ImZpbGw6I2NmY2ZjZiIgLz4KICA8cGF0aAogICAgIGQ9Im0gNTM4LjQ4NzY2LDM5MC45NyBjIC0xLjEsMC4yIC0yLjIsMC4yIC0zLjMsMC4xIEggMzkuNTg3NjYzIGMgLTAuNCwwIC0wLjcsLTAuMSAtMS4xLC0wLjEgMC41LDAuNCAxLjEsMC42IDEuNywwLjggSCA1MzcuODg3NjYgYyAwLjYsLTAuMSAxLjIsLTAuNCAxLjcsLTAuOCB6IgogICAgIGNsYXNzPSJzdDY0IgogICAgIGlkPSJwYXRoNDE2NSIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgIHN0eWxlPSJmaWxsOiNjZmNmY2YiIC8+Cjwvc3ZnPgo= - mediatype: image/svg+xml - install: - spec: - clusterPermissions: - - rules: - - apiGroups: - - "" - resources: - - events - - persistentvolumeclaims - - secrets - - services - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - '*' - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - create - - apiGroups: - - apps - resources: - - replicasets - verbs: - - get - serviceAccountName: nexus-operator - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - strategy: deployment - installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: true - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - nexus - - sonatype - - maven - - docker - - ci - - continuous integration - - continuous delivery - - repository - - repository manager - - dev tools - labels: - name: nexus-operator - links: - - name: Documentation - url: https://github.com/m88i/nexus-operator/blob/main/README.md - - name: Nexus Operator source code repository - url: https://github.com/m88i/nexus-operator - maintainers: - - email: nexus-operator@googlegroups.com - name: m88i Labs - maturity: alpha - minKubeVersion: 1.11.0 - provider: - name: m88i Labs - replaces: nexus-operator.v0.3.0 - version: 0.4.0 diff --git a/deploy/olm-catalog/nexus-operator/metadata/annotations.yaml b/deploy/olm-catalog/nexus-operator/metadata/annotations.yaml deleted file mode 100644 index b2e030a7..00000000 --- a/deploy/olm-catalog/nexus-operator/metadata/annotations.yaml +++ /dev/null @@ -1,7 +0,0 @@ -annotations: - operators.operatorframework.io.bundle.channel.default.v1: alpha - operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.bundle.manifests.v1: manifests/ - operators.operatorframework.io.bundle.mediatype.v1: registry+v1 - operators.operatorframework.io.bundle.metadata.v1: metadata/ - operators.operatorframework.io.bundle.package.v1: nexus-operator-m88i diff --git a/deploy/olm-catalog/nexus-operator/nexus-operator-m88i.package.yaml b/deploy/olm-catalog/nexus-operator/nexus-operator-m88i.package.yaml deleted file mode 100644 index 96efd870..00000000 --- a/deploy/olm-catalog/nexus-operator/nexus-operator-m88i.package.yaml +++ /dev/null @@ -1,5 +0,0 @@ -channels: - - currentCSV: nexus-operator.v0.3.0 - name: alpha -defaultChannel: alpha -packageName: nexus-operator-m88i diff --git a/deploy/operator.yaml b/deploy/operator.yaml deleted file mode 100644 index 5dc613bd..00000000 --- a/deploy/operator.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nexus-operator -spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - template: - metadata: - labels: - name: nexus-operator - spec: - serviceAccountName: nexus-operator - containers: - - name: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - command: - - nexus-operator - imagePullPolicy: Always - env: - - name: WATCH_NAMESPACE - value: "" - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "nexus-operator" diff --git a/deploy/role.yaml b/deploy/role.yaml deleted file mode 100644 index 592cb84a..00000000 --- a/deploy/role.yaml +++ /dev/null @@ -1,104 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: nexus-operator -rules: - - apiGroups: - - "" - resources: - - events - - persistentvolumeclaims - - secrets - - services - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - "*" - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - create - - apiGroups: - - apps - resources: - - replicasets - verbs: - - get diff --git a/deploy/service_account.yaml b/deploy/service_account.yaml deleted file mode 100644 index af6049f3..00000000 --- a/deploy/service_account.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: nexus-operator diff --git a/docs/TLS.md b/docs/TLS.md deleted file mode 100644 index 58cc5e56..00000000 --- a/docs/TLS.md +++ /dev/null @@ -1,374 +0,0 @@ -# Nexus Operator TLS guide - -While TLS termination itself is automatically supported by the cluster in both Openshift and Kubernetes via self-signed certificates, the Nexus Operator defines a new resource "Nexus" that offers the following TLS configurations: - - - `spec.networking.tls.mandatory` (*boolean*): When exposing via Route, set to `true` to only allow encrypted traffic using TLS (disables HTTP in favor HTTPS). Defaults to false. - - `spec.networking.tls.secretName` (*string*): When exposing via Ingress, inform the name of the TLS secret containing certificate and private key for TLS encryption. It must be present in the same namespace as the Operator. - -This configuration is meant for testing purposes only and does not seek to address all requirements faced in a production environment. If more complex configuration is required, set `spec.networking.expose` to `false` in order to configure the desired network resource (e.g., Ingress) directly. - -## Constraints - -When using an Openshift [Route](https://docs.openshift.com/container-platform/4.3/networking/routes/route-configuration.html) only `spec.networking.tls.mandatory` is available. This is due to Routes containing the TLS information directly instead of sourcing it via a Secret. - -When using a Kubernetes [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) only `spec.networking.tls.secretName` is available. This is due to HTTP->HTTPS redirection being managed by the [Ingress Controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), not by the Ingress itself. - -> **Note**: There is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on NGINX, GCE, or any other platform specific Ingress controller to understand how TLS works in your environment - -When using NodePort none of them are available. - -`spec.networking.tls.secretName` must point to a valid "kubernetes.io/tls" Secret, such as: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: testsecret-tls - namespace: default -data: - tls.crt: - tls.key: -type: kubernetes.io/tls -``` - -## Examples - -In this section we'll have a look at some examples on how to use these features. The CRs in use can be found at `examples/`. It is assumed you have a cluster with a functioning Nexus Operator deployment (if you don't, check out our [README quick install guide](https://github.com/m88i/nexus-operator#quick-install)). - -### Kubernetes Ingress - -In this example we'll use the `spec.networking.tls.secretName` directive: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: testsecret-tls - namespace: nexus -data: - tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtakNDQW9LZ0F3SUJBZ0lKQUlQMFdHVEMxMnA5TUEwR0NTcUdTSWIzRFFFQkN3VUFNR0l4Q3pBSkJnTlYKQkFZVEFsaFlNUlV3RXdZRFZRUUhEQXhFWldaaGRXeDBJRU5wZEhreEhEQWFCZ05WQkFvTUUwUmxabUYxYkhRZwpRMjl0Y0dGdWVTQk1kR1F4SGpBY0JnTlZCQU1NRlc1bGVIVnpMWFJzY3k1bGVHRnRjR3hsTG1OdmJUQWVGdzB5Ck1EQTFNREl5TVRRd016ZGFGdzB5TVRBMU1ESXlNVFF3TXpkYU1HSXhDekFKQmdOVkJBWVRBbGhZTVJVd0V3WUQKVlFRSERBeEVaV1poZFd4MElFTnBkSGt4SERBYUJnTlZCQW9NRTBSbFptRjFiSFFnUTI5dGNHRnVlU0JNZEdReApIakFjQmdOVkJBTU1GVzVsZUhWekxYUnNjeTVsZUdGdGNHeGxMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU13RzF2ODJ0VjJnUHhjcmFGWXk3cmxLcHJVQnRVUHpuQ2Y3YzdlTUVsTEkKczRHWUJ6Z3Jyb3YrTnM3OXFPaHFsWmk3WEtjajYzT2RNYzg3RmZ3VHJZQ3NNUFZvbU9XdVgzTEJDVVZOSmJIOAowaUZwRmdlNGk0S05YVStWUTBoVmUyN2dkNzRGOWpBcUlYVWNPUUVISy9Ec0gwWnQyZW5rSVNLS2owdnlKYXJtCmIyeUd3MWRZUXozdVY1ak5XWEhOTjhEQTQzbFJBRlJzUW5kVXNTNzBnS0V1Qk8ycHkrYURoYU9rWUhxZ0pqVXkKTmVOcmxoYXltL1YyZGt6TkFVbnhFTFlQUkhicEJ2dnBubmkzQTdRcEtYQzJpOUFmTlYzWDVCajlkUVJIbEUxdQpWWWNMTmE2aXh0WGtjM1h5cTlqMmhUSElLdHJOUGxoMEMySDRucG5xK3o4Q0F3RUFBYU5UTUZFd0hRWURWUjBPCkJCWUVGRUJzV0xMTFV0K3ZOSlppLzU3dExlMWZEclhCTUI4R0ExVWRJd1FZTUJhQUZFQnNXTExMVXQrdk5KWmkKLzU3dExlMWZEclhCTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUN0ZQo2ekd5WHc2d3I4cFZvL0hMK25lMVNYc0lIRjVqWDRuRy9WOWdQNXlyMCtraDFuNkR6RzZYMTJuTnhJM08vZFJRClhuMzZWZk9TbFpjUFE3Rk1WeVRxdVNVTHJscFd2MnllTmFYTDRMMGMvbC80dWFKblphTytjZnk4b0lNeTJjaGQKWG1tS2l0eWFhVDNPZ1RGdHpjem1vWmZKbmJQM04zRjRxZWpta2hCOGRXb2RuOVVkNEdIOG9hamhZYkNvdDRoYQpCZ1BLbHEydFcvd2JUbUxHcGRJb3NjYWdhR1hVMG1wbTFUNExWL01oYWxIRmMvbXNtTGs3RHBzbkZVKytQeHFXCnFab0tDVnZYY05LMGpCSnNSVS9aaTFXS2o3dE1qRG10UE8wSFJCd0JJWnAwU1hDMnN3M2dnbWVOTmZ0TTZlZmQKVkU3L2JsTUFtbjRzRnpYWFdndz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2d0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktrd2dnU2xBZ0VBQW9JQkFRRE1CdGIvTnJWZG9EOFgKSzJoV011NjVTcWExQWJWRDg1d24rM08zakJKU3lMT0JtQWM0SzY2TC9qYk8vYWpvYXBXWXUxeW5JK3R6blRIUApPeFg4RTYyQXJERDFhSmpscmw5eXdRbEZUU1d4L05JaGFSWUh1SXVDalYxUGxVTklWWHR1NEhlK0JmWXdLaUYxCkhEa0JCeXZ3N0I5R2JkbnA1Q0VpaW85TDhpV3E1bTlzaHNOWFdFTTk3bGVZelZseHpUZkF3T041VVFCVWJFSjMKVkxFdTlJQ2hMZ1R0cWN2bWc0V2pwR0I2b0NZMU1qWGphNVlXc3B2MWRuWk16UUZKOFJDMkQwUjI2UWI3Nlo1NAp0d08wS1Nsd3RvdlFIelZkMStRWS9YVUVSNVJOYmxXSEN6V3Vvc2JWNUhOMThxdlk5b1V4eUNyYXpUNVlkQXRoCitKNlo2dnMvQWdNQkFBRUNnZ0VCQUtYcktneUNRUnZTcFh3Q0lPZDRwQXFyV3NiNGpLQ21DK2UzNVhMdXhqZnMKWDQ2VVE4cTZPMGc5Zy9Udzg5dU9VZm5TNUpaSDc4SWxvOHdURU4zZVlzcXhQVjlWb0lHb1BKYmx4TlJHMk5EVgorVXlTV1FnT1crWGZjSEszdisrakZLNG1mVHBiUHNvTWVRanoycWVyWFdDZnBROXhaalYvQURORzJ5RzMya29QCmg3VHFGb1ZWMnRuYk83MnNHbkprNmlZZzlsV2dweE1FOCtDYTdmT3B3aXdQK2F6LzBrNTM5QXJHbVNzQnN1MmoKNis5Sm5DK2JrY0Z0M0haK3FNUWdOc1QrNUdZQnRCOEFqWlpRZlJTczhTSWdybkZRcjJIeDNIcnRMcUdKb1NtOQpmcXdYWjRLMTFzT0lNMHhtaXBuYTk2aXM0TjFRRVBLM0F5RzNSVW1uTG9FQ2dZRUE3VFp5b0l3WTJFc2h2YWprCkFLeTBnSEVqY25EWW9ydHUvK0VtTkNjandFc2xScC9nN1dIdDNwTXl6MmlCR0FPaVlPQXdTb2lvSzBvbUR5MGwKNTFFYTZOd3NPOG1YMzY1b3U5VGRLL2VzN1ZERzdSZStiZG94OERMNkNSUVlYNU9oTUM5bVNXbVIzaDJML2hzQgpkU2preVArV3NkS2FwcFZsNGdpdVhhVkZkbHNDZ1lFQTNDK0pseWRDVmxwZWNXUjJCdTJHVTRCd3puU2xrazA3CkJIWkxBaEk3QXhnVVpjaGx6dGtURU9ENVJZUUxGVmdjQzFVMVB0Um16OVFnRW1qcTk0YzBHSFNRL0Z0Y2psdzgKcDlCYnlVTlF5Tms0eURZeElHdmsrdndHSkhob0VKYWIxNWpkS2FDY2xYRkN3TG9LTy8wZ2U5b1kxWEF0SlFGLwp6Tm9NQzUxYmkrMENnWUVBMWx2b2srcG1IVGN2dzJzV3R3RmFqK010akNJcnNrcThrT0NPSEh6dUVyd1ZjRS9UCis5QU9HNTliUUJDSThBR0F3QmgzcXpMNC9UMmhUUCtZakFNLzFRUDV1UUdBaS9MWTFEd1VyY0hBZENnVnkzVTAKY2FMR2svQU5BUjAydFUvOFRrWFhJaW9UVmV2UGNRNUliKzVIYU5lRy95UjQrbVp4VGlSWUpXblBicGNDZ1lBcAo0Q0NhenF5Zkg3QzJnQlN5WEpvZloxNE01Y0pYZ0xpb3NKYXpYaVE3QW1sZXNpNHFtTDQzaDVIZzFxd0U4eXppCk91SlZnSy9NOXRyaXBYR0tnZncyYW5Ub2liZWdtNG90b0VMVWxDalpDZmJ5bk52YS9xb2QwYkNaWHd6cm1ya28KMTdtNElRT21xRk81czZnZW9KVjgrSTJnaWlVTDFLMHBtSTZSNXV0eVFRS0JnUUNIdDBvb0NyaHdnRStiVEkwZApNbmxDNFZzREhxc3NrMElzZDZRaHExV1FwUUk2WjNOdXZDLy9hbzZjeHZsUGRLVkt5eXZBc3RyWUx5KzM2TDJBCkpmaldSRVplRjVENGl1K2ZsMWY4Uzl1MnBzM01pN3IrL1VOWjlxNGp4TVhDdy9lbkpUYkNwRSt6ZlQ2OEZJOXYKaThXcWt1OUxWbk1SbkN3L251Y3NCcUh0d0E9PQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg== -type: kubernetes.io/tls ---- -apiVersion: apps.m88i.io/v1alpha1 -kind: Nexus -metadata: - name: nexus3 -spec: - # Number of Nexus pod replicas (can't be increased after creation) - replicas: 1 - # Here you can specify the image version to fulfill your needs. Defaults to docker.io/sonatype/nexus3:latest if useRedHatImage is set to false - #image: "docker.io/sonatype/nexus3:latest" - # let's use the centOS image since we do not have access to Red Hat Catalog - useRedHatImage: false - # Set the resources requests and limits for Nexus pods. See: https://help.sonatype.com/repomanager3/system-requirements - resources: - limits: - cpu: "2" - memory: "2Gi" - requests: - cpu: "1" - memory: "2Gi" - # Data persistence details - persistence: - # Should we persist Nexus data? (turn this to false only if you're evaluating this resource) - persistent: false - # details regarding networking - networking: - # expose please - expose: true - # How do you want to expose the Nexus server? In this case, we're using Ingress. Only available on Kubernetes - exposeAs: "Ingress" - # The host is required when using Ingress, needs to resolve to your cluster - host: "nexus-tls.example.com" - # Configuration related to TLS - tls: - # Use the TLS secret we defined above - secretName: "testsecret-tls" -``` - -Note that a TLS Secret is also defined in the first few lines. It contains a self-signed x.509 certificate and its private key encoded in base64. - -> **Note**: Base64 encoding is not an encryption method and is considered the same as plain text. Access control to the Secret is still necessary. - -**Important**: the certificate used when generating the secret must have the Common Name field set to exactly the same hostname your Ingress is using or the Ingress Controller may reject your certificate. - -In this example the secret CR has already been defined in the same file as the nexus CR for simplicity, but you may also create your secret from existing files using `kubectl`: - -```bash -$ kubectl create secret tls secret-name --cert /path/to/certificate --key /path/to/private/key -``` - -Let's create these resources: - -``` -$ kubectl create -n nexus -f examples/nexus3-centos-tls-ingress.yaml -secret/testsecret-tls created -nexus.apps.m88i.io/nexus3 created -``` - -Now we should have an Ingress with TLS configuration: - -``` -$ kubectl get -n nexus ingress/nexus3 -NAME CLASS HOSTS ADDRESS PORTS AGE -nexus3 nexus-tls.example.com 192.168.39.29 80, 443 84s -$ kubectl get -n nexus ingress/nexus3 -o yaml -apiVersion: extensions/v1beta1 -kind: Ingress -# (output omitted) -spec: - rules: - - host: nexus-tls.example.com - http: - paths: - - backend: - serviceName: nexus3 - servicePort: 8081 - path: / - pathType: ImplementationSpecific - tls: - - hosts: - - nexus-tls.example.com - secretName: testsecret-tls -status: - loadBalancer: - ingress: - - ip: 192.168.39.29 -``` - -There it is: - -```yaml - tls: - - hosts: - - nexus-tls.example.com - secretName: testsecret-tls -``` - -Using openssl's `s_client` module we can actually connect and inspect the TLS handshake outcome (note the "-servername" flag which should enable the use of [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication)): - -``` -openssl s_client -connect 192.168.39.29:443 -servername nexus-tls.example.com < /dev/null -CONNECTED(00000003) -depth=0 C = XX, L = Default City, O = Default Company Ltd, CN = nexus-tls.example.com -verify error:num=18:self signed certificate -verify return:1 -depth=0 C = XX, L = Default City, O = Default Company Ltd, CN = nexus-tls.example.com -verify return:1 ---- -Certificate chain - 0 s:/C=XX/L=Default City/O=Default Company Ltd/CN=nexus-tls.example.com - i:/C=XX/L=Default City/O=Default Company Ltd/CN=nexus-tls.example.com ---- -Server certificate ------BEGIN CERTIFICATE----- -MIIDmjCCAoKgAwIBAgIJAIP0WGTC12p9MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV -BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg -Q29tcGFueSBMdGQxHjAcBgNVBAMMFW5leHVzLXRscy5leGFtcGxlLmNvbTAeFw0y -MDA1MDIyMTQwMzdaFw0yMTA1MDIyMTQwMzdaMGIxCzAJBgNVBAYTAlhYMRUwEwYD -VQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQx -HjAcBgNVBAMMFW5leHVzLXRscy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAMwG1v82tV2gPxcraFYy7rlKprUBtUPznCf7c7eMElLI -s4GYBzgrrov+Ns79qOhqlZi7XKcj63OdMc87FfwTrYCsMPVomOWuX3LBCUVNJbH8 -0iFpFge4i4KNXU+VQ0hVe27gd74F9jAqIXUcOQEHK/DsH0Zt2enkISKKj0vyJarm -b2yGw1dYQz3uV5jNWXHNN8DA43lRAFRsQndUsS70gKEuBO2py+aDhaOkYHqgJjUy -NeNrlhaym/V2dkzNAUnxELYPRHbpBvvpnni3A7QpKXC2i9AfNV3X5Bj9dQRHlE1u -VYcLNa6ixtXkc3Xyq9j2hTHIKtrNPlh0C2H4npnq+z8CAwEAAaNTMFEwHQYDVR0O -BBYEFEBsWLLLUt+vNJZi/57tLe1fDrXBMB8GA1UdIwQYMBaAFEBsWLLLUt+vNJZi -/57tLe1fDrXBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACte -6zGyXw6wr8pVo/HL+ne1SXsIHF5jX4nG/V9gP5yr0+kh1n6DzG6X12nNxI3O/dRQ -Xn36VfOSlZcPQ7FMVyTquSULrlpWv2yeNaXL4L0c/l/4uaJnZaO+cfy8oIMy2chd -XmmKityaaT3OgTFtzczmoZfJnbP3N3F4qejmkhB8dWodn9Ud4GH8oajhYbCot4ha -BgPKlq2tW/wbTmLGpdIoscagaGXU0mpm1T4LV/MhalHFc/msmLk7DpsnFU++PxqW -qZoKCVvXcNK0jBJsRU/Zi1WKj7tMjDmtPO0HRBwBIZp0SXC2sw3ggmeNNftM6efd -VE7/blMAmn4sFzXXWgw= ------END CERTIFICATE----- -subject=/C=XX/L=Default City/O=Default Company Ltd/CN=nexus-tls.example.com -issuer=/C=XX/L=Default City/O=Default Company Ltd/CN=nexus-tls.example.com ---- -No client certificate CA names sent -Peer signing digest: SHA256 -Server Temp Key: X25519, 253 bits ---- -SSL handshake has read 1603 bytes and written 377 bytes -Verification error: self signed certificate ---- -New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384 -Server public key is 2048 bit -Secure Renegotiation IS supported -Compression: NONE -Expansion: NONE -No ALPN negotiated -SSL-Session: - Protocol : TLSv1.2 - Cipher : ECDHE-RSA-AES256-GCM-SHA384 - Session-ID: 79A15F639F3896A0C9BC12FF46549069773B64BFEC5763BCD4C997ECFF54E8C2 - Session-ID-ctx: - Master-Key: CC4749CA60E60F0A1F568EE0592FA422598030A0C31755568F69A1C226E58FCBCDCA13A29D44864F2EC4EDFE611B1586 - PSK identity: None - PSK identity hint: None - SRP username: None - TLS session ticket lifetime hint: 600 (seconds) - TLS session ticket: - 0000 - 3c bd 0f f1 ba 97 ac 7d-8f 0c 19 49 f2 f2 80 a1 <......}...I.... - 0010 - a2 66 0b 98 2e cb 44 97-01 de cd 03 ce 8e cb 4c .f....D........L - 0020 - 7f 7b 1c 2f 67 35 8a e6-8b a4 f1 f7 e2 12 73 d1 .{./g5........s. - 0030 - 33 cd 0f 5c a1 51 ae c4-f9 64 c3 96 27 1f f9 8e 3..\.Q...d..'... - 0040 - 84 92 1e 7d 42 89 4d bd-54 35 1c 57 d2 e6 36 66 ...}B.M.T5.W..6f - 0050 - ab b6 77 65 ea af f9 81-d7 61 93 72 45 64 1c fb ..we.....a.rEd.. - 0060 - 43 d7 7c a1 75 a5 62 9f-a9 7c c9 b6 d2 4c c0 41 C.|.u.b..|...L.A - 0070 - 75 4a 9a 71 f7 d0 63 70-9f 58 7a 1f 4d bc 6f 1e uJ.q..cp.Xz.M.o. - 0080 - fc 7f 37 a7 e2 01 bf 8c-bd 36 3d 5d 49 99 97 6b ..7......6=]I..k - 0090 - f9 f6 4e 27 50 c0 e3 58-9b 29 0f 08 ac b8 1d 65 ..N'P..X.).....e - 00a0 - d4 ee c6 ca 40 23 ad c0-41 a2 89 c8 86 ab fb f5 ....@#..A....... - 00b0 - 22 d6 6f cf 13 46 ea 77-f5 19 68 ec a7 a8 4c d1 ".o..F.w..h...L. - 00c0 - 74 c8 7b aa 50 72 10 a0-d6 26 d7 38 7a b9 19 8d t.{.Pr...&.8z... - - Start Time: 1588457259 - Timeout : 7200 (sec) - Verify return code: 18 (self signed certificate) - Extended master secret: yes ---- -DONE -``` - -### Openshift Route - -In this example we'll make use of the `spec.networking.tls.mandatory` directive: - -```yaml -apiVersion: apps.m88i.io/v1alpha1 -kind: Nexus -metadata: - name: nexus3 -spec: - # Number of Nexus pod replicas (can't be increased after creation) - replicas: 1 - # Here you can specify the image version to fulfill your needs. Defaults to docker.io/sonatype/nexus3:latest if useRedHatImage is set to false - #image: "docker.io/sonatype/nexus3:latest" - # let's use the centOS image since we do not have access to Red Hat Catalog - useRedHatImage: false - # Set the resources requests and limits for Nexus pods. See: https://help.sonatype.com/repomanager3/system-requirements - resources: - limits: - cpu: "2" - memory: "2Gi" - requests: - cpu: "1" - memory: "2Gi" - # Data persistence details - persistence: - # Should we persist Nexus data? (turn this to false only if you're evaluating this resource) - persistent: false - # details regarding networking - networking: - # expose please - expose: true - # How do you want to expose the Nexus server? In this case, we're using Route. Only available on Openshift - exposeAs: "Route" - # Configuration related to TLS - tls: - # Causes all insecure traffic (HTTP) to be redirected to a secured port (HTTPS) - mandatory: true -``` - -Let's create this resource: - -``` -$ oc apply -f examples/nexus3-centos-tls-route.yaml -nexus.apps.m88i.io/nexus3 created -``` - -Now we should have a Route with edge TLS termination and a redirection policy: - -``` -$ oc get route/nexus3 -NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD -nexus3 nexus3-nexus.192.168.42.189.nip.io nexus3 8081 edge/Redirect None -``` - -To be sure, let's take a look at the YAML as well: - -``` -$ oc get route/nexus3 -o yaml -apiVersion: route.openshift.io/v1 -kind: Route -# (output omitted) -spec: - host: nexus3-nexus.192.168.42.189.nip.io - port: - targetPort: 8081 - tls: - insecureEdgeTerminationPolicy: Redirect - termination: edge - to: - kind: Service - name: nexus3 - weight: 100 - wildcardPolicy: None -status: - ingress: - - conditions: - - lastTransitionTime: 2020-05-03T02:52:13Z - status: "True" - type: Admitted - host: nexus3-nexus.192.168.42.189.nip.io - routerName: router - wildcardPolicy: None -``` - -There it is: - -```yaml -tls: - insecureEdgeTerminationPolicy: Redirect - termination: edge -``` - -We can use `curl` to test it out. First let's gather some verbose output when connecting using HTTP as our protocol: - -``` -$ curl http://nexus3-nexus.192.168.42.189.nip.io -v -* Rebuilt URL to: http://nexus3-nexus.192.168.42.189.nip.io/ -* Trying 192.168.42.189... -* TCP_NODELAY set -* Connected to nexus3-nexus.192.168.42.189.nip.io (192.168.42.189) port 80 (#0) -> GET / HTTP/1.1 -> Host: nexus3-nexus.192.168.42.189.nip.io -> User-Agent: curl/7.59.0 -> Accept: */* -> -< HTTP/1.1 302 Found -< Cache-Control: no-cache -< Content-length: 0 -< Location: https://nexus3-nexus.192.168.42.189.nip.io/ -< -* Connection #0 to host nexus3-nexus.192.168.42.189.nip.io left intact -``` - -See that "Location" header? That's responsible for the redirect, but we have to run it again with the "-L" flag. We're also adding the "-k" option to ignore TLS verification failure as we're using a self-signed certificate (for more information consult the curl(1) man page): - -``` -$ curl -vLk http://nexus3-nexus.192.168.42.189.nip.io -* Rebuilt URL to: http://nexus3-nexus.192.168.42.189.nip.io/ -* Trying 192.168.42.189... -* TCP_NODELAY set -* Connected to nexus3-nexus.192.168.42.189.nip.io (192.168.42.189) port 80 (#0) -> GET / HTTP/1.1 -> Host: nexus3-nexus.192.168.42.189.nip.io -> User-Agent: curl/7.59.0 -> Accept: */* -> -< HTTP/1.1 302 Found -< Cache-Control: no-cache -< Content-length: 0 -< Location: https://nexus3-nexus.192.168.42.189.nip.io/ -< -* Connection #0 to host nexus3-nexus.192.168.42.189.nip.io left intact -* Issue another request to this URL: 'https://nexus3-nexus.192.168.42.189.nip.io/' -* Trying 192.168.42.189... -* TCP_NODELAY set -* Connected to nexus3-nexus.192.168.42.189.nip.io (192.168.42.189) port 443 (#1) -# (output omitted) -``` diff --git a/docs/img/operator-hub.png b/docs/img/operator-hub.png deleted file mode 100644 index 8f250e8e..00000000 Binary files a/docs/img/operator-hub.png and /dev/null differ diff --git a/docs/img/sonatype-nexus-crop.svg b/docs/img/sonatype-nexus-crop.svg deleted file mode 100644 index 8435a330..00000000 --- a/docs/img/sonatype-nexus-crop.svg +++ /dev/null @@ -1,600 +0,0 @@ - - - - - - image/svg+xml - - Sonatype Nexus logo - - - - - - Sonatype Nexus logo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/img/sonatype-nexus.svg b/docs/img/sonatype-nexus.svg deleted file mode 100644 index c25c278f..00000000 --- a/docs/img/sonatype-nexus.svg +++ /dev/null @@ -1 +0,0 @@ -Sonatype Nexus logo \ No newline at end of file diff --git a/docs/operator-hub.png b/docs/operator-hub.png deleted file mode 100644 index 8f250e8e..00000000 Binary files a/docs/operator-hub.png and /dev/null differ diff --git a/docs/sonatype-nexus-crop.svg b/docs/sonatype-nexus-crop.svg deleted file mode 100644 index 8435a330..00000000 --- a/docs/sonatype-nexus-crop.svg +++ /dev/null @@ -1,600 +0,0 @@ - - - - - - image/svg+xml - - Sonatype Nexus logo - - - - - - Sonatype Nexus logo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/sonatype-nexus.svg b/docs/sonatype-nexus.svg deleted file mode 100644 index c25c278f..00000000 --- a/docs/sonatype-nexus.svg +++ /dev/null @@ -1 +0,0 @@ -Sonatype Nexus logo \ No newline at end of file diff --git a/go.mod b/go.mod index 538349a0..435b70ee 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,31 @@ module github.com/m88i/nexus-operator +go 1.14 + require ( - github.com/RHsyseng/operator-utils v0.0.0-20200709142328-d5a5812a443f + github.com/RHsyseng/operator-utils v1.4.4 + // controller-runtime uses v0.1.0, klogv2 uses v0.2.0, which is the log module for k8s + // as soon as they sync, we can migrate to v0.2.0 github.com/go-logr/logr v0.1.0 - github.com/go-openapi/spec v0.19.8 - github.com/go-openapi/swag v0.19.7 // indirect - github.com/golang/protobuf v1.3.3 // indirect - github.com/google/uuid v1.1.1 - github.com/googleapis/gnostic v0.3.1 + github.com/go-openapi/spec v0.19.6 + github.com/google/uuid v1.1.2 + github.com/googleapis/gnostic v0.5.1 github.com/heroku/docker-registry-client v0.0.0-20190909225348-afc9e1acc3d5 github.com/m88i/aicura v0.2.0 - github.com/openshift/api v0.0.0-20200312145924-779a333deb13 // branch release-3.11 - github.com/operator-framework/operator-sdk v0.18.1 - github.com/spf13/pflag v1.0.5 + github.com/onsi/ginkgo v1.12.1 + github.com/onsi/gomega v1.10.2 + github.com/openshift/api v0.0.0-20201005153912-821561a7f2a2 github.com/stretchr/testify v1.6.1 - go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 - go.uber.org/zap v1.15.0 - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - k8s.io/api v0.18.3 - k8s.io/apimachinery v0.18.3 + k8s.io/api v0.19.0 + k8s.io/apimachinery v0.19.0 k8s.io/client-go v12.0.0+incompatible - k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 - sigs.k8s.io/controller-runtime v0.6.0 + k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 + sigs.k8s.io/controller-runtime v0.6.3 ) replace ( - github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.3.2+incompatible // Required by OLM - k8s.io/client-go => k8s.io/client-go v0.18.3 // Required by prometheus-operator + k8s.io/api => k8s.io/api v0.19.0 + k8s.io/client-go => k8s.io/client-go v0.19.0 + // latest klog whic uses logr 0.1.0 + k8s.io/klog/v2 => k8s.io/klog/v2 v2.1.0 ) - -go 1.14 diff --git a/go.sum b/go.sum index 6af5dff8..7c74d616 100644 --- a/go.sum +++ b/go.sum @@ -1,73 +1,35 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.49.0 h1:CH+lkubJzcPYB1Ggupcq0+k8Ni2ILdG2lYjDIgavDBQ= -cloud.google.com/go v0.49.0/go.mod h1:hGvAdzcWNbyuxS3nWhD7H2cIJxjRRTRLQVB0bdputVY= +cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA= -contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v23.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v13.3.2+incompatible h1:VxzPyuhtnlBOzc4IWCZHqpyH2d+QMLQEuy3wREyY4oc= -github.com/Azure/go-autorest v13.3.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503 h1:uUhdsDMg2GbFLF5GfQPtLMWd5vdDZSfqvqQp3waafxQ= -github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 h1:Hxqlh1uAA8aGpa1dFhDNhll7U/rkWtG8ZItFvRMr7l0= -github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= -github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= -github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= -github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk= -github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I= github.com/PaesslerAG/gval v1.0.1 h1:QnCvok0w0Y3uZNxmNmC6GZ0cuBl+jH0tu/rBMT8pso4= @@ -82,223 +44,91 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/RHsyseng/operator-utils v0.0.0-20200709142328-d5a5812a443f h1:bU3BgrMr2CqFasfYSy/16dsUuUOlFQyrDnw/PiZIJlM= -github.com/RHsyseng/operator-utils v0.0.0-20200709142328-d5a5812a443f/go.mod h1:E+hCtYz+9UsXfAGnRjX2LGuaa5gSGNKHCVTmGZR79vY= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/RHsyseng/operator-utils v1.4.4 h1:uRgqPIKmorv8wYtBeKrWfoeLLVaBQd5ymlZRYgnqT48= +github.com/RHsyseng/operator-utils v1.4.4/go.mod h1:ZFQi9Pp9lp0+2rKqgESwj1MMEgHqPfsMm2JqOXEh+Ok= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= -github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= 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/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/brancz/gojsontoyaml v0.0.0-20191212081931-bf2969bbd742/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= -github.com/brancz/kube-rbac-proxy v0.5.0/go.mod h1:cL2VjiIFGS90Cjh5ZZ8+It6tMcBt8rwvuw2J6Mamnl0= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/brancz/gojsontoyaml v0.0.0-20190425155809-e8bd32d46b3d/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= -github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA= -github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= -github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb h1:nXPkFq8X1a9ycY3GYQpFNxHh3j2JgY7zDZfq2EXMIzk= -github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v1.0.1 h1:IfVOxKbjyBn9maoye2JN95pgGYOmPkQVqxtOu7rtNIc= -github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/prometheus-operator v0.38.1-0.20200424145508-7e176fda06cc h1:nMbUjGuF7UzVluucix/vsy4973BNdEiT/aX6kFtskKM= -github.com/coreos/prometheus-operator v0.38.1-0.20200424145508-7e176fda06cc/go.mod h1:erio69w1R/aC14D5nfvAXSlE8FT8jt2Hnavc50Dp33A= +github.com/coreos/prometheus-operator v0.35.1/go.mod h1:XHYZUStZWcwd1yk/1DjZv/fywqKIyAJ6pSwvIr+v9BQ= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= -github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= -github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= -github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= -github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= -github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= -github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= -github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= -github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= github.com/davecgh/go-spew 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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= 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/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= -github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af h1:ujR+JcSHkOZMctuIgvi+a/VHpTn0nSy0W7eV5p34xjg= github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= -github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce h1:KXS1Jg+ddGcWA8e1N7cupxaHHZhit5rB9tfDU+mfjyY= -github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 h1:yWHOI+vFjEsAakUTSrtqc/SAHrhSkmn48pqjidZX3QA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyzzjiW90t8cY= -github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= -github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/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/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/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 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/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= +github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= @@ -306,75 +136,70 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.7/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= -github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.18.0/go.mod h1:uI6pHuxWYTy94zZxgcwJkUWa9wbIlhteGfloI10GD4U= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.11/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.8 h1:qAdZLh1r6QF/hI/gTq+TJTvsQUodZsM7KLqkAJdiJNg= -github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.6 h1:rMMMj8cV38KVXK7SFc+I2MWClbEfbK705+j+dyqun5g= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.4/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s= github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-openapi/validate v0.19.6/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= @@ -389,57 +214,64 @@ github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoM github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= -github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +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/gobuffalo/envy v1.7.1 h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8= -github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/flect v0.2.1/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= -github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= -github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= -github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 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.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= @@ -458,169 +290,88 @@ github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlS github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= -github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= 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/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-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/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.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/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.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.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 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/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.2.0 h1:lD2Bce2xBAMNNcFZ0dObTpXkGLlVIb33RPVUNVpw6ic= -github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.6.0 h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU= -github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.4/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= -github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.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/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= github.com/heroku/docker-registry-client v0.0.0-20190909225348-afc9e1acc3d5 h1:6ZR6HQ+P9ZUwHlYq+bU7e9wqAImxKUguq8fp2gZSgCo= github.com/heroku/docker-registry-client v0.0.0-20190909225348-afc9e1acc3d5/go.mod h1:Yho0S7KhsnHQRCC5lDraYF1SsLMeWtf/tKdufKu3TJA= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 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/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/improbable-eng/thanos v0.3.2/go.mod h1:GZewVGILKuJVPNRn7L4Zw+7X96qzFOwj63b22xYGXBE= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= 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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/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/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jsonnet-bundler/jsonnet-bundler v0.3.1/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jsonnet-bundler/jsonnet-bundler v0.1.0/go.mod h1:YKsSFc9VFhhLITkJS3X2PrRqWG9u2Jq99udTdDjQLfM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -629,25 +380,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= -github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.0/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= github.com/m88i/aicura v0.2.0 h1:K14Sdtyi6VtBxrPQl08R3gvpgV0NRLt1yCkEwasroOA= github.com/m88i/aicura v0.2.0/go.mod h1:b0nxZ+ddcXw0/PR5Pz+ivKGC3MjZBLQeTXtcfbc0HJw= github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -659,57 +399,24 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/markbates/inflect v1.0.4 h1:5fh1gzTFhfae06u3hzHYO9xe3l3v3nW5Pwt3naLTP5g= -github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do= -github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= 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/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU= -github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0= -github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -717,102 +424,51 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN 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/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3DnAZsJsoaE= -github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v0.0.0-20170117200651-66bb6560562f/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.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/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/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/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= -github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/openshift/api v0.0.0-20200312145924-779a333deb13 h1:8FyIpQ41MJUaLjWThSE/heRwocxRWxpxblLKu3zwqFA= -github.com/openshift/api v0.0.0-20200312145924-779a333deb13/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= +github.com/openshift/api v0.0.0-20200205145930-e9d93e317dd1/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/openshift/api v0.0.0-20201005153912-821561a7f2a2 h1:MFjn80G3dVC5EAWwhQUryMduv8NvoxnRBUEd1q7dP9U= +github.com/openshift/api v0.0.0-20201005153912-821561a7f2a2/go.mod h1:Si/I9UGeRR3qzg01YWPmtlr0GeGk2fnuggXJRmjAZ6U= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/openshift/client-go v3.9.0+incompatible/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= -github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/api v0.3.7-0.20200602203552-431198de9fc2 h1:2KtDe3jI6ftXGj5M875WVvv6pBIk4K9DyrwPuE+XfOc= -github.com/operator-framework/api v0.3.7-0.20200602203552-431198de9fc2/go.mod h1:Xbje9x0SHmh0nihE21kpesB38vk3cyxnE6JdDS8Jo1Q= -github.com/operator-framework/operator-registry v1.12.6-0.20200605115407-01fa069730e2 h1:G7helxG2m7xgIsn4KX5qu62mqbgjK9kVUZC3AHiPnOQ= -github.com/operator-framework/operator-registry v1.12.6-0.20200605115407-01fa069730e2/go.mod h1:loVINznYhgBIkmv83kU4yee88RS0BBk+hqOw9r4bhJk= -github.com/operator-framework/operator-sdk v0.18.1 h1:AOUOBchkx8r3yYF/MDjH0gdtd13ACENuy2gnsSXQXt0= -github.com/operator-framework/operator-sdk v0.18.1/go.mod h1:QMFHXj8+SxF56tfR1QmIU/tc9FKI73TG8Qw7Iy4D2zY= -github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -820,277 +476,159 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prometheus/alertmanager v0.18.0/go.mod h1:WcxHBl40VSPuOaqWae6l6HpnEOVRIycEJ7i9iYkadEE= -github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= -github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/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.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.2.0/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -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/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/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-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/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/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI= +github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.8.0/go.mod h1:fSI0j+IUQrDd7+ZtR9WKIGtoYAYAJUKcKhYLG25tN4g= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= +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/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180825020608-02ddb050ef6b/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= -github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= 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.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= 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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 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 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc= -github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= -go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk= -go.elastic.co/apm/module/apmhttp v1.5.0/go.mod h1:1FbmNuyD3ddauwzgVwFB0fqY6KbZt3JkV187tGCYYhY= -go.elastic.co/apm/module/apmot v1.5.0/go.mod h1:d2KYwhJParTpyw2WnTNy8geNlHKKFX+4oK3YLlsesWE= -go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= 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/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +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= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200208060501-ecb85df21340/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1099,141 +637,113 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk 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/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/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-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09 h1:KaQtG+aDELoNmXYas3TVkGNYRuq8JQ1aa7LJt8EXVyo= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438 h1:khxRGsvPk4n2y8I/mLLjp7e5dMTJmH75wvqS6nMwUtY= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= +golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/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.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -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/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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= @@ -1242,14 +752,12 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/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-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1259,227 +767,165 @@ golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3 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-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190813034749-528a2984e271/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190918214516-5a1a30219888/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191030203535-5e247c9ad0a0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b h1:AFZdJUT7jJYXQEC29hYH/WZkoV7+KhwxQGmdZ19yYoY= -golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200207224406-61798d64f025/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto= -gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU= 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.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2 h1:iTp+3yyl/KOtxa/d1/JUE0GGSoR6FuW5udver22iwpw= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= 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/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24 h1:wDju+RU97qa0FZT0QnZDg9Uc2dH0Ql513kFvHocz+WM= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= 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/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= -gopkg.in/imdario/mergo.v0 v0.3.7/go.mod h1:9qPP6AGrlC1G2PTNXko614FwGZvorN7MiBU0Eppok+U= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.1.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -helm.sh/helm/v3 v3.2.0/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= -k8s.io/api v0.0.0-20190813020757-36bff7324fb7/go.mod h1:3Iy+myeAORNCLgjd/Xu9ebwN7Vh59Bw0vh9jhoX+V58= -k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48= -k8s.io/api v0.0.0-20191115095533-47f6de673b26/go.mod h1:iA/8arsvelvo4IDqIhX4IbjTEKBGgvsf2OraTuRtLFU= -k8s.io/api v0.0.0-20191122220107-b5267f2975e0/go.mod h1:vYpRfxYkMrmPPSesoHEkGNHxNKTk96REAwqm/inQbs0= -k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= -k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= -k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0= -k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/api v0.19.0 h1:XyrFIJqTYZJ2DU7FBE/bSPz7b1HvbVBuBf07oeo6eTc= +k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY= -k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo= -k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8= -k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= -k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= -k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8= +k8s.io/apiextensions-apiserver v0.18.6 h1:vDlk7cyFsDyfwn2rNAO2DbmUbvXy5yT5GE3rrqOzaMo= +k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M= k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4= -k8s.io/apimachinery v0.0.0-20191115015347-3c7067801da2/go.mod h1:dXFS2zaQR8fyzuvRdJDHw2Aerij/yVGJSre0bZQSVJA= -k8s.io/apimachinery v0.0.0-20191121175448-79c2a76c473a/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk= -k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apimachinery v0.18.6 h1:RtFHnfGNfd1N0LeSrKCUznz5xtUP1elRGvHJbL3Ntag= +k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apimachinery v0.19.0 h1:gjKnAda/HZp5k4xQYjL0K/Yb66IvNqjthCb03QlKpaQ= +k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg= -k8s.io/apiserver v0.0.0-20191122221311-9d521947b1e1/go.mod h1:RbsZY5zzBIWnz4KbctZsTVjwIuOpTp4Z8oCgFHN4kZQ= -k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw= -k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= -k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA= -k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ= -k8s.io/cli-runtime v0.18.2/go.mod h1:yfFR2sQQzDsV0VEKGZtrJwEy4hLZ2oj4ZIfodgxAHWQ= -k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k= -k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/apiserver v0.18.6/go.mod h1:Zt2XvTHuaZjBz6EFYzpp+X4hTmgWGy8AthNVnTdm3Wg= +k8s.io/client-go v0.19.0 h1:1+0E0zfWFIWeyRhQYWzimJOyAk2UT7TiARaLNwJCf7k= +k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU= k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE= -k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= -k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= +k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA= -k8s.io/component-base v0.0.0-20191122220729-2684fb322cb9/go.mod h1:NFuUusy/X4Tk21m21tcNUihnmp4OI7lXU7/xA+rYXkc= -k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c= -k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= +k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200114144118-36b2048a9120 h1:RPscN6KhmG54S33L+lr3GS+oD1jmchIU0ll519K6FA4= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -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/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= +k8s.io/klog/v2 v2.1.0 h1:X3+Mru/L3jy4BI4vcAYkHvL6PyU+QBsuhEqwlI4mgkA= +k8s.io/klog/v2 v2.1.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-state-metrics v1.7.2 h1:6vdtgXrrRRMSgnyDmgua+qvgCYv954JNfxXAtDkeLVQ= -k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= -k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= -k8s.io/kubectl v0.18.2/go.mod h1:OdgFa3AlsPKRpFFYE7ICTwulXOcMGXHTc+UKhHKvrb4= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= -k8s.io/metrics v0.18.2/go.mod h1:qga8E7QfYNR9Q89cSCAjinC9pTZ7yv1XSVGUB0vJypg= -k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6 h1:p0Ai3qVtkbCG/Af26dBmU0E1W58NID3hSSh7cMyylpM= -k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 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= @@ -1489,27 +935,21 @@ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIa mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM= -rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= -sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM= -sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= -sigs.k8s.io/controller-tools v0.2.4 h1:la1h46EzElvWefWLqfsXrnsO3lZjpkI0asTpX6h8PLA= +sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns= +sigs.k8s.io/controller-runtime v0.6.3 h1:SBbr+inLPEKhvlJtrvDcwIpm+uhDvp63Bl72xYJtoOE= +sigs.k8s.io/controller-runtime v0.6.3/go.mod h1:WlZNXcM0++oyaQt4B7C2lEE5JYRs8vJUzRP4N4JpdAY= sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= -sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= -sigs.k8s.io/kubebuilder v1.0.9-0.20200513134826-f07a0146a40b h1:/ldZApUjz/QfKav8hg3OMYAGDrSozVgMVoDlN0VXJgk= -sigs.k8s.io/kubebuilder v1.0.9-0.20200513134826-f07a0146a40b/go.mod h1:FGPx0hvP73+bapzWoy5ePuhAJYgJjrFbPxgvWyortM0= -sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ= sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= -vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/go.tools.mod b/go.tools.mod deleted file mode 100644 index 43b085c9..00000000 --- a/go.tools.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/m88i/nexus-operator - -go 1.14 - -require github.com/golangci/golangci-lint v1.27.0 // indirect diff --git a/go.tools.sum b/go.tools.sum deleted file mode 100644 index f62cfd80..00000000 --- a/go.tools.sum +++ /dev/null @@ -1,378 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157 h1:hY39LwQHh+1kaovmIjOrlqnXNX6tygSRfLkkK33IkZU= -github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= -github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -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/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/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bombsimon/wsl/v3 v3.0.0 h1:w9f49xQatuaeTJFaNP4SpiWSR5vfT6IstPtM62JjcqA= -github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= -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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-critic/go-critic v0.4.1 h1:4DTQfT1wWwLg/hzxwD9bkdhDQrdJtxe6DUTadPlrIeE= -github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= -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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -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-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.27.0 h1:VYLx63qb+XJsHdZ27PMS2w5JZacN0XG8ffUwe7yQomo= -github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 h1:jNYPNLe3d8smommaoQlK7LOA5ESyUJJ+Wf79ZtA7Vp4= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -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 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= -github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= -github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -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/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8= -github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE= -github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE= -github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= -github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tetafro/godot v0.3.7 h1:+mecr7RKrUKB5UQ1gwqEMn13sDKTyDR8KNIquB9mm+8= -github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa h1:RC4maTWLKKwb7p1cnoygsbKIgNlJqSYBeAFON3Ar8As= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -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/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= -github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= -github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= -github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= -github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -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/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/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-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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-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/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/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-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-20180525024113-a5b4c53f6e8b/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-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/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-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.21.0/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/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/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.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/hack/addheaders.sh b/hack/addheaders.sh index 3b18a102..44ba23c5 100755 --- a/hack/addheaders.sh +++ b/hack/addheaders.sh @@ -13,8 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -which ./bin/addlicense >/dev/null || go build -o ./bin/addlicense github.com/google/addlicense +source ./hack/go-path.sh + +command -v addlicense >/dev/null || go build -o "${GOPATH}"/bin/addlicense github.com/google/addlicense # https://github.com/google/addlicense -./bin/addlicense -c "Nexus Operator and/or its authors" -l apache cmd hack pkg version +addlicense -c "Nexus Operator and/or its authors" -l apache controllers hack pkg diff --git a/hack/ci/install-operator-sdk.sh b/hack/ci/install-operator-sdk.sh index d59ca0b5..5f2c14ee 100755 --- a/hack/ci/install-operator-sdk.sh +++ b/hack/ci/install-operator-sdk.sh @@ -16,7 +16,7 @@ set -e -default_operator_sdk_version=v0.18.1 +default_operator_sdk_version=v1.0.1 if [[ -z ${OPERATOR_SDK_VERSION} ]]; then OPERATOR_SDK_VERSION=$default_operator_sdk_version diff --git a/hack/ci/load-operator-image.sh b/hack/ci/load-operator-image.sh index 56850932..81d6650f 100755 --- a/hack/ci/load-operator-image.sh +++ b/hack/ci/load-operator-image.sh @@ -14,7 +14,7 @@ # limitations under the License. -source ./hack/export-version.sh +source ./hack/verify-version.sh echo "---> Loading Operator Image into Kind" kind load docker-image quay.io/m88i/nexus-operator:${OP_VERSION} --name ${CLUSTER_NAME} diff --git a/hack/ci/operator-ensure-manifest.sh b/hack/ci/operator-ensure-manifest.sh index fc0d4fc4..e3a19cb0 100755 --- a/hack/ci/operator-ensure-manifest.sh +++ b/hack/ci/operator-ensure-manifest.sh @@ -14,7 +14,7 @@ # limitations under the License. -source ./hack/export-version.sh +source ./hack/verify-version.sh OUTPUT="${PWD}/build/_output/operatorhub" @@ -24,11 +24,19 @@ echo "---> Output dir is set to ${OUTPUT}" rm -rf "${OUTPUT}" mkdir -p "${OUTPUT}" -cp -r "./deploy/olm-catalog/nexus-operator/" "${OUTPUT}/" -mv "${OUTPUT}/nexus-operator" "${OUTPUT}/nexus-operator-m88i" -rm "${OUTPUT}/nexus-operator-m88i/manifests" -rf -rm "${OUTPUT}/nexus-operator-m88i/metadata" -rf -rm "${OUTPUT}/nexus-operator-m88i/0.1.0" -rf + +rm -rf ~/operators/ +git clone --depth 1 --filter=blob:none https://github.com/operator-framework/community-operators.git ~/operators/ + +cp -r ~/operators/community-operators/nexus-operator-m88i "${OUTPUT}" +rm -rf ~/operators/ + +mkdir -p "${OUTPUT}/nexus-operator-m88i/${OP_VERSION}" +cp -v "./bundle/manifests/apps.m88i.io_nexus.yaml" "${OUTPUT}/nexus-operator-m88i/${OP_VERSION}/apps.m88i.io_nexus_crd.yaml" +cp -v "./bundle/manifests/nexus-operator.clusterserviceversion.yaml" "${OUTPUT}/nexus-operator-m88i/${OP_VERSION}/nexus-operator.v${OP_VERSION}.clusterserviceversion.yaml" +cp -v "./bundle/nexus-operator-m88i.package.yaml" "${OUTPUT}/nexus-operator-m88i/" + +sed -i "s/{version}/${OP_VERSION}/g" "${OUTPUT}/nexus-operator-m88i/nexus-operator-m88i.package.yaml" echo "---> Manifest files in the output directory for OLM verification" ls -la "${OUTPUT}/nexus-operator-m88i/" diff --git a/hack/ci/operator-olm-test.sh b/hack/ci/operator-olm-test.sh index 8e1025ec..2ba84c4b 100755 --- a/hack/ci/operator-olm-test.sh +++ b/hack/ci/operator-olm-test.sh @@ -14,8 +14,8 @@ # limitations under the License. +source ./hack/verify-version.sh source ./hack/ci/operator-ensure-manifest.sh -source ./hack/export-version.sh CATALOG_IMAGE="operatorhubio-catalog:temp" OP_PATH="community-operators/nexus-operator-m88i" diff --git a/hack/generate-manifests.sh b/hack/generate-manifests.sh deleted file mode 100755 index bf88d632..00000000 --- a/hack/generate-manifests.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - -source ./hack/export-version.sh - - -# generate manifests for package format -# use --from-version to upgrade: https://operator-sdk.netlify.app/docs/olm-integration/generating-a-csv/#upgrading-your-csv -operator-sdk generate csv --apis-dir ./pkg/apis/apps/v1alpha1 --update-crds --csv-version $OP_VERSION --make-manifests=false --verbose --operator-name nexus-operator - -# manifests format for bundle image -operator-sdk generate csv --apis-dir ./pkg/apis/apps/v1alpha1 --verbose --operator-name nexus-operator --csv-version $OP_VERSION - -# our package doesn't have the same name as the operator -rm ./deploy/olm-catalog/nexus-operator/nexus-operator.package.yaml -rf - -source ./hack/generate-yaml-installer.sh \ No newline at end of file diff --git a/hack/generate-yaml-installer.sh b/hack/generate-yaml-installer.sh deleted file mode 100755 index 4003ce68..00000000 --- a/hack/generate-yaml-installer.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - -# generating all in one yaml file -cat ./deploy/namespace.yaml > nexus-operator.yaml -echo "---" >> nexus-operator.yaml -cat ./deploy/crds/apps.m88i.io_nexus_crd.yaml >> nexus-operator.yaml -echo "---" >> nexus-operator.yaml -sed '4 a \ \ namespace: operators' ./deploy/service_account.yaml >> nexus-operator.yaml -echo "---" >> nexus-operator.yaml -cat ./deploy/role.yaml >> nexus-operator.yaml -echo "---" >> nexus-operator.yaml -cat ./deploy/role_binding.yaml >> nexus-operator.yaml -echo "---" >> nexus-operator.yaml -sed '4 a \ \ namespace: operators' ./deploy/operator.yaml >> nexus-operator.yaml - -sed -i "s/\${NAMESPACE}/operators/g" nexus-operator.yaml \ No newline at end of file diff --git a/hack/go-build.sh b/hack/go-build.sh deleted file mode 100755 index ba67e921..00000000 --- a/hack/go-build.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - - -# CUSTOM_IMAGE_TAG: name of the operator tag. set this var to change the default name of the image being built. Default to quay.io/m88i/nexus-operator:current-version -# BUILDER: builder to build the image. either podman or docker. default to podman - -# include -source ./hack/go-mod-env.sh -source ./hack/export-version.sh - -REGISTRY=quay.io/m88i -IMAGE=nexus-operator -TAG=${OP_VERSION} -DEFAULT_BASE_IMAGE=registry.redhat.io/ubi8/ubi-minimal:latest - -setGoModEnv -go generate ./... - -if [[ -n ${CUSTOM_BASE_IMAGE} ]]; then - sed -i -e 's,'"${DEFAULT_BASE_IMAGE}"','"${CUSTOM_BASE_IMAGE}"',' ./build/Dockerfile -fi -if [[ -z ${CUSTOM_IMAGE_TAG} ]]; then - CUSTOM_IMAGE_TAG=${REGISTRY}/${IMAGE}:${TAG} -fi -if [[ -z ${BUILDER} ]]; then - BUILDER=podman -fi - -# changed to podman, see: https://www.linuxuprising.com/2019/11/how-to-install-and-use-docker-on-fedora.html -operator-sdk build ${CUSTOM_IMAGE_TAG} --image-builder ${BUILDER} diff --git a/hack/go-fmt.sh b/hack/go-fmt.sh index 39fe5b75..b564bdbc 100755 --- a/hack/go-fmt.sh +++ b/hack/go-fmt.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright 2020 Nexus Operator and/or its authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,12 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +source ./hack/go-path.sh -gofmt -s -l -w cmd/ pkg/ version/ -# get the goimports binary -command -v goimports >/dev/null || go build -o $GOPATH/bin/goimports golang.org/x/tools/cmd/goimports -goimports -local github.com/m88i/nexus-operator -l -w cmd/ pkg/ version/ +go mod tidy -if [[ -n ${CI} ]]; then - git diff --exit-code -fi +gofmt -s -l -w . +# get the goimports binary +command -v goimports >/dev/null || go build -o "${GOPATH}"/bin/goimports golang.org/x/tools/cmd/goimports +goimports -local github.com/m88i/nexus-operator -l -w . diff --git a/hack/go-lint.sh b/hack/go-lint.sh index 6a5f47fc..eeafa04a 100755 --- a/hack/go-lint.sh +++ b/hack/go-lint.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright 2020 Nexus Operator and/or its authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,9 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +source ./hack/go-path.sh # it's expected to have GOPATH in your PATH # The command in or will fetch the latest tag available for golangci-lint and install in $GOPATH/bin/ -which golangci-lint >/dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin +command -v golangci-lint >/dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}"/bin -golangci-lint run ./pkg/... ./test/... +golangci-lint run --enable=golint diff --git a/hack/go-mod-env.sh b/hack/go-mod-env.sh deleted file mode 100755 index 0c590a96..00000000 --- a/hack/go-mod-env.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - - -# If inside GOPATH/src, set GO111MODULE=on -setGoModEnv() { - pwdPath=$(pwd -P 2>/dev/null || env PWD= pwd) - goPath=$(go env GOPATH) - cd $goPath || exit - goPath=$(pwd -P 2>/dev/null || env PWD= pwd) - cd $pwdPath || exit - if [ "${pwdPath#"$goPath"}" != "${pwdPath}" ]; then - export GO111MODULE=on - fi -} diff --git a/hack/go-mod.sh b/hack/go-path.sh similarity index 86% rename from hack/go-mod.sh rename to hack/go-path.sh index f149c52d..b23c7afc 100755 --- a/hack/go-mod.sh +++ b/hack/go-path.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright 2020 Nexus Operator and/or its authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,10 +14,6 @@ # limitations under the License. -. ./hack/go-mod-env.sh - -echo Resetting vendor directory - -setGoModEnv - -go mod tidy +# enforce GOROOT +export GOROOT=$(go env GOROOT) +export GOPATH=$(go env GOPATH) diff --git a/hack/go-vet.sh b/hack/go-vet.sh deleted file mode 100755 index b3bf44ae..00000000 --- a/hack/go-vet.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - -set -e -GOPATH=$(go env GOPATH) -./hack/go-mod.sh -./hack/addheaders.sh - -operator-sdk generate k8s -operator-sdk generate crds --crd-version=v1beta1 - -# get the openapi binary -command -v openapi-gen >/dev/null || go build -o $GOPATH/bin/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen -echo "Generating openapi files" -openapi-gen --logtostderr=true -o "" -i ./pkg/apis/apps/v1alpha1 -O zz_generated.openapi -p ./pkg/apis/apps/v1alpha1 -h ./hack/boilerplate.go.txt -r "-" - -./hack/generate-manifests.sh - -go vet ./... diff --git a/hack/olm-integration.sh b/hack/olm-integration.sh deleted file mode 100755 index 92b1398b..00000000 --- a/hack/olm-integration.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - - -source ./hack/export-version.sh - -operator-sdk generate csv --apis-dir ./pkg/apis/apps/v1alpha1 --verbose --operator-name nexus-operator --csv-version $OP_VERSION -operator-sdk bundle create quay.io/m88i/nexus-operator.v${OP_VERSION}:latest -d ./deploy/olm-catalog/nexus-operator/${OP_VERSION} --package nexus-operator-m88i --channels alpha --overwrite --image-builder podman -podman push quay.io/m88i/nexus-operator.v${OP_VERSION}:latest -operator-sdk bundle validate quay.io/m88i/nexus-operator.v${OP_VERSION}:latest - -# For future reference when creating a cool CI: -# deployment testing: https://operator-sdk.netlify.app/docs/olm-integration/olm-deployment/ -# operator-sdk olm install -# operator-sdk run --olm --operator-namespace nexus --operator-version ${VERSION} -# kubectl apply -f ./examples/nexus3-centos-no-volume.yaml -# after testing .... -# operator-sdk cleanup --olm --operator-namespace nexus --operator-version ${VERSION} -# operator-sdk olm uninstall diff --git a/hack/go-test.sh b/hack/openapi.sh similarity index 63% rename from hack/go-test.sh rename to hack/openapi.sh index c419fc2d..f602eb06 100755 --- a/hack/go-test.sh +++ b/hack/openapi.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright 2020 Nexus Operator and/or its authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,11 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -. ./hack/go-mod-env.sh -./hack/go-vet.sh -./hack/go-fmt.sh -./hack/go-lint.sh +source ./hack/go-path.sh -setGoModEnv -go test ./pkg/... -count=1 +# get the openapi binary +command -v openapi-gen >/dev/null || go build -o "${GOPATH}"/bin/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen +echo "Generating openapi files" +openapi-gen --logtostderr=true -o "" -i ./api/v1alpha1 -O zz_generated.openapi -p ./api/v1alpha1 -h ./hack/boilerplate.go.txt -r "-" diff --git a/hack/pr-prep.sh b/hack/pr-prep.sh index eb8ef6c7..3714ffb1 100755 --- a/hack/pr-prep.sh +++ b/hack/pr-prep.sh @@ -56,9 +56,7 @@ prompt_and_push_or_die() { ) } -./hack/go-test.sh -./hack/go-build.sh -./hack/run-e2e-test.sh +make test echo "All tests were successful!" diff --git a/hack/run-e2e-test.sh b/hack/run-e2e-test.sh deleted file mode 100755 index f788420e..00000000 --- a/hack/run-e2e-test.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# Copyright 2020 Nexus Operator and/or its authors -# -# 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. - - -if [[ -z ${NAMESPACE_E2E} ]]; then - NAMESPACE_E2E="nexus-e2e" -fi - -if [[ -z ${TIMEOUT_E2E} ]]; then - TIMEOUT_E2E="15m" -fi - -if [[ ${CREATE_NAMESPACE^^} == "TRUE" ]]; then - echo "---> Creating Namespace ${NAMESPACE_E2E} to run e2e tests" - kubectl create namespace $NAMESPACE_E2E -else - echo "---> Skipping creating namespace" -fi - -echo "---> Executing e2e tests on ${NAMESPACE_E2E}" - -if [[ ${RUN_WITH_IMAGE^^} == "TRUE" ]]; then - echo "---> Running tests with image instead of local" - # see: https://kind.sigs.k8s.io/docs/user/quick-start/#loading-an-image-into-your-cluster - echo "---> Updating deployment file to imagePullPolicy: Never" - sed -i.bak 's/imagePullPolicy:\s*Always/imagePullPolicy: Never/g' ./deploy/operator.yaml - echo "---> Updating cluster role binding to SA on ${NAMESPACE_E2E}" - sed -i.bak "s/\${NAMESPACE}/${NAMESPACE_E2E}/g" ./deploy/role_binding.yaml - - kubectl delete -f ./deploy/service_account.yaml - kubectl delete -f ./deploy/role_binding.yaml - kubectl delete -f ./deploy/role.yaml - kubectl delete -f ./deploy/operator.yaml - - operator-sdk test local ./test/e2e --go-test-flags "-v -timeout $TIMEOUT_E2E $ADDITIONAL_FLAGS" --debug --operator-namespace $NAMESPACE_E2E - test_exit_code=$? - mv -f ./deploy/operator.yaml.bak ./deploy/operator.yaml - mv -f ./deploy/role_binding.yaml.bak ./deploy/role_binding.yaml -else - echo "---> Running tests with local binary" - operator-sdk test local ./test/e2e --go-test-flags "-v -timeout $TIMEOUT_E2E $ADDITIONAL_FLAGS" --debug --up-local --operator-namespace $NAMESPACE_E2E - test_exit_code=$? -fi - -if [[ ${CREATE_NAMESPACE^^} == "TRUE" ]]; then - echo "---> Cleaning up namespace ${NAMESPACE_E2E}" - kubectl delete namespace $NAMESPACE_E2E -fi - -if [ $test_exit_code -eq 0 ]; then - echo "Success: e2e test ended successfully!" - exit 0 -else - echo "Failure: e2e test failed to run. See the logs for more information" >&2 - exit 1 -fi diff --git a/hack/uninstall.sh b/hack/uninstall.sh index 7b981ea7..16ffa27e 100755 --- a/hack/uninstall.sh +++ b/hack/uninstall.sh @@ -14,19 +14,12 @@ # limitations under the License. -NAMESPACE=nexus +VERSION=$1 -echo "....... Uninstalling ......." -echo "....... Deleting CRDs......." -kubectl delete -f deploy/crds/apps.m88i.io_nexus_crd.yaml +if [ -z ${VERSION} ]; then + VERSION=$(curl https://api.github.com/repos/m88i/nexus-operator/releases/latest | python -c "import sys, json; print(json.load(sys.stdin)['tag_name'])") +fi -echo "....... Deleting Rules and Service Account ......." -kubectl delete -f deploy/role.yaml -n ${NAMESPACE} -kubectl delete -f deploy/role_binding.yaml -n ${NAMESPACE} -kubectl delete -f deploy/service_account.yaml -n ${NAMESPACE} +echo "....... Uninstall Nexus Operator ${VERSION} ......." -echo "....... Deleting Operator ......." -kubectl delete -f deploy/operator.yaml -n ${NAMESPACE} - -echo "....... Deleting namespace ${NAMESPACE}......." -kubectl delete namespace ${NAMESPACE} +kubectl delete -f https://github.com/m88i/nexus-operator/releases/download/${VERSION}/nexus-operator.yaml \ No newline at end of file diff --git a/hack/export-version.sh b/hack/verify-version.sh similarity index 79% rename from hack/export-version.sh rename to hack/verify-version.sh index 052db729..e2d18cf8 100755 --- a/hack/export-version.sh +++ b/hack/verify-version.sh @@ -14,6 +14,7 @@ # limitations under the License. -OP_VERSION=$(grep -m 1 'Version =' ./version/version.go) && OP_VERSION=$(echo ${OP_VERSION#*=} | tr -d '"') - -echo "Operator version is ${OP_VERSION}" +if [ -z "${OP_VERSION}"]; then + echo "---> Operator version not defined. Export OP_VERSION variable or call this script from the Makefile" + exit 1 +fi \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 00000000..cc9eae60 --- /dev/null +++ b/main.go @@ -0,0 +1,125 @@ +/* + + +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" + "fmt" + "os" + "strings" + + routev1 "github.com/openshift/api/route/v1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/discovery" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + appsv1alpha1 "github.com/m88i/nexus-operator/api/v1alpha1" + "github.com/m88i/nexus-operator/controllers" + "github.com/m88i/nexus-operator/controllers/nexus/resource" + // +kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + // adding routev1 + utilruntime.Must(routev1.AddToScheme(scheme)) + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(appsv1alpha1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + + watchNamespace, err := getWatchNamespace() + if err != nil { + setupLog.Error(err, "unable to get WatchNamespace, "+ + "the manager will watch and manage resources in all namespaces") + } + options := ctrl.Options{ + Scheme: scheme, + MetricsBindAddress: metricsAddr, + Port: 9443, + LeaderElection: enableLeaderElection, + LeaderElectionID: "363e6adb.m88i.io", + Namespace: watchNamespace, + } + + // Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2) + if strings.Contains(watchNamespace, ",") { + setupLog.Info("manager will be watching ", "namespace", watchNamespace) + // configure cluster-scoped with MultiNamespacedCacheBuilder + options.Namespace = "" + options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(watchNamespace, ",")) + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig()) + if err = (&controllers.NexusReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Nexus"), + Scheme: mgr.GetScheme(), + DiscoveryClient: discoveryClient, + Supervisor: resource.NewSupervisor(mgr.GetClient(), discoveryClient), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Nexus") + os.Exit(1) + } + // +kubebuilder:scaffold:builder + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} + +// getWatchNamespace returns the Namespace the operator should be watching for changes +func getWatchNamespace() (string, error) { + // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE + // which specifies the Namespace to watch. + // An empty value means the operator is running with cluster scope. + var watchNamespaceEnvVar = "WATCH_NAMESPACE" + + ns, found := os.LookupEnv(watchNamespaceEnvVar) + if !found { + return "", fmt.Errorf("%s must be set", watchNamespaceEnvVar) + } + return ns, nil +} diff --git a/nexus-operator.yaml b/nexus-operator.yaml index 66a5bf14..1bfa9614 100644 --- a/nexus-operator.yaml +++ b/nexus-operator.yaml @@ -1,11 +1,16 @@ apiVersion: v1 kind: Namespace metadata: - name: operators + labels: + control-plane: controller-manager + name: nexus-operator-system --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + creationTimestamp: null name: nexus.apps.m88i.io spec: group: apps.m88i.io @@ -19,17 +24,12 @@ spec: status: {} validation: openAPIV3Schema: - description: Nexus custom resource to deploy the Nexus Server properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -40,76 +40,51 @@ spec: description: Automatic updates configuration properties: disabled: - description: Whether or not the Operator should perform automatic - updates. Defaults to `false` (auto updates are enabled). Is set - to `false` if `spec.image` is not empty and is different from - the default community image. + description: Whether or not the Operator should perform automatic updates. Defaults to `false` (auto updates are enabled). Is set to `false` if `spec.image` is not empty and is different from the default community image. type: boolean minorVersion: - description: The Nexus image minor version the deployment should - stay in. If left blank and automatic updates are enabled the latest - minor is set. + description: The Nexus image minor version the deployment should stay in. If left blank and automatic updates are enabled the latest minor is set. minimum: 0 type: integer type: object generateRandomAdminPassword: - description: 'GenerateRandomAdminPassword enables the random password - generation. Defaults to `false`: the default password for a newly - created instance is ''admin123'', which should be changed in the first - login. If set to `true`, you must use the automatically generated - ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. - The operator uses the default credentials to create a user for itself - to create default repositories. If set to `true`, the repositories - won''t be created since the operator won''t fetch for the random password.' + description: 'GenerateRandomAdminPassword enables the random password generation. Defaults to `false`: the default password for a newly created instance is ''admin123'', which should be changed in the first login. If set to `true`, you must use the automatically generated ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. The operator uses the default credentials to create a user for itself to create default repositories. If set to `true`, the repositories won''t be created since the operator won''t fetch for the random password.' type: boolean image: - description: 'Full image tag name for this specific deployment. Will - be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' + description: 'Full image tag name for this specific deployment. Will be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' type: string imagePullPolicy: - description: 'The image pull policy for the Nexus image. If left blank - behavior will be determined by the image tag (`Always` if "latest" - and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` - or `Never`.' + description: 'The image pull policy for the Nexus image. If left blank behavior will be determined by the image tag (`Always` if "latest" and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` or `Never`.' enum: - Always - IfNotPresent - Never type: string livenessProbe: - description: LivenessProbe describes how the Nexus container liveness - probe should work + description: LivenessProbe describes how the Nexus container liveness probe should work properties: failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. format: int32 minimum: 1 type: integer initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. + description: Number of seconds after the container has started before probes are initiated. Defaults to 240 seconds. Minimum value is 0. format: int32 minimum: 0 type: integer periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. + description: How often (in seconds) to perform the probe. Defaults to 10 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. format: int32 minimum: 1 type: integer timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. + description: Number of seconds after which the probe times out. Defaults to 15 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer @@ -118,41 +93,30 @@ spec: description: Networking definition properties: expose: - description: Set to `true` to expose the Nexus application. Defaults - to `false`. + description: Set to `true` to expose the Nexus application. Defaults to `false`. type: boolean exposeAs: - description: 'Type of networking exposure: NodePort, Route or Ingress. - Defaults to Route on OpenShift and Ingress on Kubernetes. Routes - are only available on Openshift and Ingresses are only available - on Kubernetes.' + description: 'Type of networking exposure: NodePort, Route or Ingress. Defaults to Route on OpenShift and Ingress on Kubernetes. Routes are only available on Openshift and Ingresses are only available on Kubernetes.' enum: - NodePort - Route - Ingress type: string host: - description: Host where the Nexus service is exposed. This attribute - is required if the service is exposed via Ingress. + description: Host where the Nexus service is exposed. This attribute is required if the service is exposed via Ingress. type: string nodePort: - description: NodePort defined in the exposed service. Required if - exposed via NodePort. + description: NodePort defined in the exposed service. Required if exposed via NodePort. format: int32 type: integer tls: description: TLS/SSL-related configuration properties: mandatory: - description: When exposing via Route, set to `true` to only - allow encrypted traffic using TLS (disables HTTP in favor - of HTTPS). Defaults to `false`. + description: When exposing via Route, set to `true` to only allow encrypted traffic using TLS (disables HTTP in favor of HTTPS). Defaults to `false`. type: boolean secretName: - description: When exposing via Ingress, inform the name of the - TLS secret containing certificate and private key for TLS - encryption. It must be present in the same namespace as the - Operator. + description: When exposing via Ingress, inform the name of the TLS secret containing certificate and private key for TLS encryption. It must be present in the same namespace as the Operator. type: string type: object type: object @@ -160,8 +124,7 @@ spec: description: Persistence definition properties: persistent: - description: Flag to indicate if this instance will be persistent - or not + description: Flag to indicate if this instance will be persistent or not type: boolean storageClass: description: StorageClass used by the managed PVC. @@ -173,39 +136,30 @@ spec: - persistent type: object readinessProbe: - description: ReadinessProbe describes how the Nexus container readiness - probe should work + description: ReadinessProbe describes how the Nexus container readiness probe should work properties: failureThreshold: - description: Minimum consecutive failures for the probe to be considered - failed after having succeeded. Defaults to 3. Minimum value is - 1. + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. format: int32 minimum: 1 type: integer initialDelaySeconds: - description: Number of seconds after the container has started before - probes are initiated. Defaults to 240 seconds. Minimum value is - 0. + description: Number of seconds after the container has started before probes are initiated. Defaults to 240 seconds. Minimum value is 0. format: int32 minimum: 0 type: integer periodSeconds: - description: How often (in seconds) to perform the probe. Defaults - to 10 seconds. Minimum value is 1. + description: How often (in seconds) to perform the probe. Defaults to 10 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer successThreshold: - description: Minimum consecutive successes for the probe to be considered - successful after having failed. Defaults to 1. Must be 1 for liveness - and startup. Minimum value is 1. + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. format: int32 minimum: 1 type: integer timeoutSeconds: - description: Number of seconds after which the probe times out. - Defaults to 15 seconds. Minimum value is 1. + description: Number of seconds after which the probe times out. Defaults to 15 seconds. Minimum value is 1. format: int32 minimum: 1 type: integer @@ -226,8 +180,7 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object requests: additionalProperties: @@ -236,43 +189,24 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' type: object type: object serverOperations: - description: ServerOperations describes the options for the operations - performed on the deployed server instance + description: ServerOperations describes the options for the operations performed on the deployed server instance properties: disableOperatorUserCreation: - description: DisableOperatorUserCreation disables the auto-creation - of the `nexus-operator` user on the deployed server. This user - performs all the operations on the server (such as creating the - community repos). If disabled, the Operator will use the default - `admin` user. Defaults to `false` (always create the user). Setting - this to `true` is not recommended as it grants the Operator more - privileges than it needs and it would not be possible to tell - apart operations performed by the `admin` and the Operator. + description: DisableOperatorUserCreation disables the auto-creation of the `nexus-operator` user on the deployed server. This user performs all the operations on the server (such as creating the community repos). If disabled, the Operator will use the default `admin` user. Defaults to `false` (always create the user). Setting this to `true` is not recommended as it grants the Operator more privileges than it needs and it would not be possible to tell apart operations performed by the `admin` and the Operator. type: boolean disableRepositoryCreation: - description: DisableRepositoryCreation disables the auto-creation - of Apache, JBoss and Red Hat repositories and their addition to - the Maven Public group in this Nexus instance. Defaults to `false` - (always try to create the repos). Set this to `true` to not create - them. Only works if `spec.generateRandomAdminPassword` is `false`. + description: DisableRepositoryCreation disables the auto-creation of Apache, JBoss and Red Hat repositories and their addition to the Maven Public group in this Nexus instance. Defaults to `false` (always try to create the repos). Set this to `true` to not create them. Only works if `spec.generateRandomAdminPassword` is `false`. type: boolean type: object serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount used - to run the Pods. If left blank, a default ServiceAccount is created - with the same name as the Nexus CR (`metadata.name`). + description: ServiceAccountName is the name of the ServiceAccount used to run the Pods. If left blank, a default ServiceAccount is created with the same name as the Nexus CR (`metadata.name`). type: string useRedHatImage: - description: If you have access to Red Hat Container Catalog, set this - to `true` to use the certified image provided by Sonatype Defaults - to `false` + description: If you have access to Red Hat Container Catalog, set this to `true` to use the certified image provided by Sonatype Defaults to `false` type: boolean required: - persistence @@ -286,26 +220,20 @@ spec: description: Condition status for the Nexus deployment properties: availableReplicas: - description: Total number of available pods (ready for at least - minReadySeconds) targeted by this deployment. + description: Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. format: int32 type: integer collisionCount: - description: Count of hash collisions for the Deployment. The Deployment - controller uses this field as a collision avoidance mechanism - when it needs to create the name for the newest ReplicaSet. + description: Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet. format: int32 type: integer conditions: - description: Represents the latest available observations of a deployment's - current state. + description: Represents the latest available observations of a deployment's current state. items: - description: DeploymentCondition describes the state of a deployment - at a certain point. + description: DeploymentCondition describes the state of a deployment at a certain point. properties: lastTransitionTime: - description: Last time the condition transitioned from one - status to another. + description: Last time the condition transitioned from one status to another. format: date-time type: string lastUpdateTime: @@ -313,15 +241,13 @@ spec: format: date-time type: string message: - description: A human readable message indicating details about - the transition. + description: A human readable message indicating details about the transition. type: string reason: description: The reason for the condition's last transition. type: string status: - description: Status of the condition, one of True, False, - Unknown. + description: Status of the condition, one of True, False, Unknown. type: string type: description: Type of deployment condition. @@ -340,21 +266,15 @@ spec: format: int32 type: integer replicas: - description: Total number of non-terminated pods targeted by this - deployment (their labels match the selector). + description: Total number of non-terminated pods targeted by this deployment (their labels match the selector). format: int32 type: integer unavailableReplicas: - description: Total number of unavailable pods targeted by this deployment. - This is the total number of pods that are still required for the - deployment to have 100% available capacity. They may either be - pods that are running but not yet available or pods that still - have not been created. + description: Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created. format: int32 type: integer updatedReplicas: - description: Total number of non-terminated pods targeted by this - deployment that have the desired template spec. + description: Total number of non-terminated pods targeted by this deployment that have the desired template spec. format: int32 type: integer type: object @@ -368,8 +288,7 @@ spec: description: Gives more information about a failure status type: string serverOperationsStatus: - description: ServerOperationsStatus describes the general status for - the operations performed in the Nexus server instance + description: ServerOperationsStatus describes the general status for the operations performed in the Nexus server instance properties: communityRepositoriesCreated: type: boolean @@ -395,159 +314,296 @@ spec: - name: v1alpha1 served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] --- -apiVersion: v1 -kind: ServiceAccount +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role metadata: - name: nexus-operator - namespace: operators + name: nexus-operator-leader-election-role + namespace: nexus-operator-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null - name: nexus-operator + name: nexus-operator-manager-role rules: - - apiGroups: - - "" - resources: - - events - - persistentvolumeclaims - - secrets - - services - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create - - apiGroups: - - apps - resourceNames: - - nexus-operator - resources: - - deployments/finalizers - verbs: - - update - - apiGroups: - - "" - resources: - - pods - verbs: - - get - - apiGroups: - - apps.m88i.io - resources: - - "*" - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - route.openshift.io - resources: - - routes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - create - - apiGroups: - - apps - resources: - - replicasets - verbs: - - get +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get +- apiGroups: + - apps.m88i.io + resources: + - nexus + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps.m88i.io + resources: + - nexus/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get +- apiGroups: + - "" + resources: + - events + - persistentvolumeclaims + - secrets + - serviceaccounts + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - get +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch --- -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: - name: nexus-operator + name: nexus-operator-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: nexus-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: nexus-operator-leader-election-rolebinding + namespace: nexus-operator-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: nexus-operator-leader-election-role subjects: - kind: ServiceAccount - name: nexus-operator - namespace: operators + name: default + namespace: nexus-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nexus-operator-manager-rolebinding roleRef: + apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: nexus-operator + name: nexus-operator-manager-role +subjects: +- kind: ServiceAccount + name: default + namespace: nexus-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nexus-operator-proxy-rolebinding +roleRef: apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nexus-operator-proxy-role +subjects: +- kind: ServiceAccount + name: default + namespace: nexus-operator-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: nexus-operator-controller-manager-metrics-service + namespace: nexus-operator-system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager --- apiVersion: apps/v1 kind: Deployment metadata: - name: nexus-operator - namespace: operators + labels: + control-plane: controller-manager + name: nexus-operator-controller-manager + namespace: nexus-operator-system spec: replicas: 1 selector: matchLabels: - name: nexus-operator + control-plane: controller-manager template: metadata: labels: - name: nexus-operator + control-plane: controller-manager spec: - serviceAccountName: nexus-operator containers: - - name: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - command: - - nexus-operator - imagePullPolicy: Always - env: - - name: WATCH_NAMESPACE - value: "" - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "nexus-operator" + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + - args: + - --metrics-addr=127.0.0.1:8080 + - --enable-leader-election + command: + - /manager + image: quay.io/m88i/nexus-operator:0.4.0 + name: manager + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + terminationGracePeriodSeconds: 10 +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + name: nexus-operator-controller-manager-metrics-monitor + namespace: nexus-operator-system +spec: + endpoints: + - path: /metrics + port: https + selector: + matchLabels: + control-plane: controller-manager diff --git a/pkg/apis/addtoscheme_apps_v1alpha1.go b/pkg/apis/addtoscheme_apps_v1alpha1.go deleted file mode 100644 index f2b76c88..00000000 --- a/pkg/apis/addtoscheme_apps_v1alpha1.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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/m88i/nexus-operator/pkg/apis/apps/v1alpha1" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme) -} diff --git a/pkg/apis/apis.go b/pkg/apis/apis.go deleted file mode 100644 index 283f12f7..00000000 --- a/pkg/apis/apis.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 ( - "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/apps/group.go b/pkg/apis/apps/group.go deleted file mode 100644 index 0a9c3ac7..00000000 --- a/pkg/apis/apps/group.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 apps contains apps API versions. - -// This file ensures Go source parsers acknowledge the apps package -// and any child packages. It can be removed if any other Go source files are -// added to this package. -package apps diff --git a/pkg/apis/apps/v1alpha1/doc.go b/pkg/apis/apps/v1alpha1/doc.go deleted file mode 100644 index 4fd01839..00000000 --- a/pkg/apis/apps/v1alpha1/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package v1alpha1 contains API Schema definitions for the apps v1alpha1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=apps.m88i.io -package v1alpha1 diff --git a/pkg/apis/apps/v1alpha1/register.go b/pkg/apis/apps/v1alpha1/register.go deleted file mode 100644 index 07038dc2..00000000 --- a/pkg/apis/apps/v1alpha1/register.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 v1alpha1 contains API Schema definitions for the apps v1alpha1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=apps.m88i.io -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "apps.m88i.io", Version: "v1alpha1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} -) diff --git a/pkg/cluster/kubernetes/events_test.go b/pkg/cluster/kubernetes/events_test.go index 9106a325..ec30c1ad 100644 --- a/pkg/cluster/kubernetes/events_test.go +++ b/pkg/cluster/kubernetes/events_test.go @@ -24,7 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/test" ) diff --git a/pkg/controller/add_nexus.go b/pkg/controller/add_nexus.go deleted file mode 100644 index 3c120377..00000000 --- a/pkg/controller/add_nexus.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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/m88i/nexus-operator/pkg/controller/nexus" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, nexus.Add) -} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go deleted file mode 100644 index adc0b2ae..00000000 --- a/pkg/controller/controller.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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/nexus/nexus_controller.go b/pkg/controller/nexus/nexus_controller.go deleted file mode 100644 index 719111c4..00000000 --- a/pkg/controller/nexus/nexus_controller.go +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 nexus - -import ( - "context" - "fmt" - "reflect" - "time" - - resUtils "github.com/RHsyseng/operator-utils/pkg/resource" - "github.com/RHsyseng/operator-utils/pkg/resource/write" - routev1 "github.com/openshift/api/route/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/discovery" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" - - appsv1alpha1 "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" - "github.com/m88i/nexus-operator/pkg/cluster/openshift" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" - "github.com/m88i/nexus-operator/pkg/controller/nexus/server" - "github.com/m88i/nexus-operator/pkg/controller/nexus/update" - "github.com/m88i/nexus-operator/pkg/framework" - "github.com/m88i/nexus-operator/pkg/logger" -) - -var log = logger.GetLogger("controller_nexus") - -const ( - updatePollWaitTimeout = 500 * time.Millisecond - updateCancelTimeout = 30 * time.Second -) - -// Add creates a new Nexus Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - reconcileNexus := &ReconcileNexus{ - client: mgr.GetClient(), - discoveryClient: discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig()), - scheme: mgr.GetScheme(), - } - reconcileNexus.resourceSupervisor = resource.NewSupervisor(reconcileNexus.client, reconcileNexus.discoveryClient) - return reconcileNexus -} - -// 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("nexus-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to primary resource Nexus - err = c.Watch(&source.Kind{Type: &appsv1alpha1.Nexus{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - controllerWatcher := framework.NewControllerWatcher(r.(*ReconcileNexus).discoveryClient, mgr, c, &appsv1alpha1.Nexus{}) - watchedObjects := []framework.WatchedObjects{ - { - GroupVersion: routev1.GroupVersion, - AddToScheme: routev1.Install, - Objects: []runtime.Object{&routev1.Route{}}, - }, - { - GroupVersion: networking.SchemeGroupVersion, - AddToScheme: networking.AddToScheme, - Objects: []runtime.Object{&networking.Ingress{}}, - }, - {Objects: []runtime.Object{&corev1.Service{}, &appsv1.Deployment{}, &corev1.PersistentVolumeClaim{}, &corev1.ServiceAccount{}}}, - } - if err = controllerWatcher.Watch(watchedObjects...); err != nil { - return err - } - return nil -} - -// blank assignment to verify that ReconcileNexus implements reconcile.Reconciler -var _ reconcile.Reconciler = &ReconcileNexus{} - -// ReconcileNexus reconciles a Nexus object -type ReconcileNexus struct { - // This client, initialized using mgr.Client() above, is a split client - // that reads objects from the cache and writes to the apiserver - client client.Client - scheme *runtime.Scheme - discoveryClient discovery.DiscoveryInterface - resourceSupervisor resource.Supervisor -} - -// Reconcile reads that state of the cluster for a Nexus object and makes changes based on the state read -// and what is in the Nexus.Spec -// Note: -// The Controller will requeue the Request to be processed again if the returned error is non-nil or -// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. -func (r *ReconcileNexus) Reconcile(request reconcile.Request) (result reconcile.Result, err error) { - log.Infof("Reconciling Nexus '%s' on namespace '%s'", request.Name, request.Namespace) - result = reconcile.Result{} - - // Fetch the Nexus instance - instance := &appsv1alpha1.Nexus{} - err = r.client.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - return result, nil - } - // Error reading the object - requeue the request. - return result, err - } - - v, err := validation.NewValidator(r.client, r.scheme, r.discoveryClient) - if err != nil { - // Error using the discovery API - requeue the request. - return - } - - validatedNexus, err := v.SetDefaultsAndValidate(instance) - // In case of any errors from here, we should update the Nexus CR and its status - defer r.updateNexus(validatedNexus, instance, &err) - if err != nil { - return - } - - // Initialize the resource managers - err = r.resourceSupervisor.InitManagers(validatedNexus) - if err != nil { - return - } - // Create the objects as desired by the Nexus instance - requiredRes, err := r.resourceSupervisor.GetRequiredResources() - if err != nil { - return - } - // Get the actual deployed objects - deployedRes, err := r.resourceSupervisor.GetDeployedResources() - if err != nil { - return - } - // Get the resource comparator - comparator, err := r.resourceSupervisor.GetComparator() - if err != nil { - return - } - deltas := comparator.Compare(deployedRes, requiredRes) - - writer := write.New(r.client).WithOwnerController(validatedNexus, r.scheme) - for resourceType, delta := range deltas { - if !delta.HasChanges() { - continue - } - log.Info("Will ", - "create ", len(delta.Added), - ", update ", len(delta.Updated), - ", delete ", len(delta.Removed), - " instances of ", resourceType) - _, err = writer.AddResources(delta.Added) - if err != nil { - return - } - _, err = writer.UpdateResources(deployedRes[resourceType], delta.Updated) - if err != nil { - return - } - _, err = writer.RemoveResources(delta.Removed) - if err != nil { - return - } - } - - if err = r.ensureServerUpdates(validatedNexus); err != nil { - return - } - - // Check if we are performing an update and act upon it if needed - err = r.handleUpdate(validatedNexus, requiredRes, deployedRes) - return -} - -func (r *ReconcileNexus) handleUpdate(nexus *appsv1alpha1.Nexus, required, deployed map[reflect.Type][]resUtils.KubernetesResource) error { - requiredDeployment := required[reflect.TypeOf(appsv1.Deployment{})][0].(*appsv1.Deployment) - deployedDeployments := deployed[reflect.TypeOf(appsv1.Deployment{})] - if len(deployedDeployments) == 0 { - // nothing previously deployed, not an update - return nil - } - deployedDeployment := deployedDeployments[0].(*appsv1.Deployment) - return update.HandleUpdate(nexus, deployedDeployment, requiredDeployment, r.scheme, r.client) -} - -func (r *ReconcileNexus) ensureServerUpdates(instance *appsv1alpha1.Nexus) error { - log.Info("Performing Nexus server operations if needed") - status, err := server.HandleServerOperations(instance, r.client) - if err != nil { - return err - } - log.Infof("Server Operations finished. Status is %v", status) - instance.Status.ServerOperationsStatus = status - return nil -} - -func (r *ReconcileNexus) updateNexus(nexus *appsv1alpha1.Nexus, originalNexus *appsv1alpha1.Nexus, err *error) { - log.Info("Updating application status before leaving") - - if statusErr := r.getNexusDeploymentStatus(nexus); statusErr != nil { - log.Errorf("Error while fetching Nexus Deployment status: %v", err) - } - - if *err != nil { - nexus.Status.Reason = fmt.Sprintf("Failed to deploy Nexus: %s", *err) - nexus.Status.NexusStatus = appsv1alpha1.NexusStatusFailure - } else { - nexus.Status.Reason = "" - if nexus.Status.DeploymentStatus.AvailableReplicas == nexus.Spec.Replicas { - nexus.Status.NexusStatus = appsv1alpha1.NexusStatusOK - } else { - nexus.Status.NexusStatus = appsv1alpha1.NexusStatusPending - } - } - - if urlErr := r.getNexusURL(nexus); urlErr != nil { - log.Errorf("Error while fetching Nexus URL status: %v", urlErr) - } - - if !reflect.DeepEqual(originalNexus.Spec, nexus.Spec) { - log.Infof("Updating Nexus instance '%s'", nexus.Name) - waitErr := wait.Poll(updatePollWaitTimeout, updateCancelTimeout, func() (bool, error) { - if updateErr := r.client.Update(context.TODO(), nexus); errors.IsConflict(updateErr) { - newNexus := &appsv1alpha1.Nexus{ObjectMeta: v1.ObjectMeta{ - Name: nexus.Name, - Namespace: nexus.Namespace, - }} - if err := r.client.Get(context.TODO(), framework.Key(newNexus), newNexus); err != nil { - return false, err - } - // we override only the spec, which we are interested into - newNexus.Spec = nexus.Spec - nexus = newNexus - return false, nil - } else if updateErr != nil { - return false, updateErr - } - return true, nil - }) - if waitErr != nil { - log.Error(waitErr, "Error while updating Nexus status") - } - } - - if !reflect.DeepEqual(originalNexus.Status, nexus.Status) { - log.Infof("Updating status for Nexus instance '%s'", nexus.Name) - waitErr := wait.Poll(updatePollWaitTimeout, updateCancelTimeout, func() (bool, error) { - if updateErr := r.client.Status().Update(context.TODO(), nexus); errors.IsConflict(updateErr) { - newNexus := &appsv1alpha1.Nexus{ObjectMeta: v1.ObjectMeta{ - Name: nexus.Name, - Namespace: nexus.Namespace, - }} - if err := r.client.Get(context.TODO(), framework.Key(newNexus), newNexus); err != nil { - return false, err - } - // we override only the spec, which we are interested into - newNexus.Status = nexus.Status - nexus = newNexus - return false, nil - } else if updateErr != nil { - return false, updateErr - } - return true, nil - }) - if waitErr != nil { - log.Error(waitErr, "Error while updating Nexus status") - } - } - - log.Info("Controller finished reconciliation") -} - -func (r *ReconcileNexus) getNexusDeploymentStatus(nexus *appsv1alpha1.Nexus) error { - log.Info("Checking Deployment Status") - deployment := &appsv1.Deployment{} - if err := r.client.Get(context.TODO(), types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}, deployment); err != nil { - if !errors.IsNotFound(err) { - return err - } - } - nexus.Status.DeploymentStatus = deployment.Status - return nil -} - -func (r *ReconcileNexus) getNexusURL(nexus *appsv1alpha1.Nexus) error { - if nexus.Spec.Networking.Expose { - var err error - uri := "" - if nexus.Spec.Networking.ExposeAs == appsv1alpha1.RouteExposeType { - log.Info("Checking Route Status") - uri, err = openshift.GetRouteURI(r.client, r.discoveryClient, types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}) - } else if nexus.Spec.Networking.ExposeAs == appsv1alpha1.IngressExposeType { - log.Info("Checking Ingress Status") - uri, err = kubernetes.GetIngressURI(r.client, types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}) - } - if err != nil { - return err - } - nexus.Status.NexusRoute = uri - } - return nil -} diff --git a/pkg/controller/nexus/nexus_controller_test.go b/pkg/controller/nexus/nexus_controller_test.go deleted file mode 100644 index 2c1e8b35..00000000 --- a/pkg/controller/nexus/nexus_controller_test.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 nexus - -import ( - "context" - "fmt" - "reflect" - "testing" - - resUtils "github.com/RHsyseng/operator-utils/pkg/resource" - routev1 "github.com/openshift/api/route/v1" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - nexusres "github.com/m88i/nexus-operator/pkg/controller/nexus/resource" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" - "github.com/m88i/nexus-operator/pkg/test" -) - -func TestReconcileNexus_Reconcile_NoInstance(t *testing.T) { - - // create objects to run reconcile - cl := test.NewFakeClientBuilder().OnOpenshift().Build() - r := newFakeReconcileNexus(cl) - req := reconcile.Request{NamespacedName: types.NamespacedName{ - Namespace: t.Name(), - Name: "nexus3", - }} - - // reconcile phase - res, err := r.Reconcile(req) - assert.NoError(t, err) - assert.False(t, res.Requeue) -} - -func TestReconcileNexus_Reconcile_NotPersistent(t *testing.T) { - ns := t.Name() - appName := "nexus3" - nexus := &v1alpha1.Nexus{ - ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: appName}, - Spec: v1alpha1.NexusSpec{ - Replicas: 1, - Persistence: v1alpha1.NexusPersistence{ - Persistent: false, - }, - Networking: v1alpha1.NexusNetworking{ - Expose: true, - }, - ServerOperations: v1alpha1.ServerOperationsOpts{DisableOperatorUserCreation: true, DisableRepositoryCreation: true}, - }, - } - - // create objects to run reconcile - cl := test.NewFakeClientBuilder(nexus).OnOpenshift().Build() - r := newFakeReconcileNexus(cl) - req := reconcile.Request{NamespacedName: types.NamespacedName{ - Namespace: ns, - Name: appName, - }} - - // reconcile phase - res, err := r.Reconcile(req) - assert.NoError(t, err) - assert.False(t, res.Requeue) - // let's check our replica - dep := &appsv1.Deployment{} - err = r.client.Get(context.TODO(), req.NamespacedName, dep) - assert.NoError(t, err) - assert.Equal(t, int32(1), *dep.Spec.Replicas) - // shouldn't exist a pvc - pvc := &corev1.PersistentVolumeClaim{} - err = r.client.Get(context.TODO(), req.NamespacedName, pvc) - assert.Error(t, err) - assert.True(t, errors.IsNotFound(err)) - // we have routes \o/ - route := &routev1.Route{} - err = r.client.Get(context.TODO(), req.NamespacedName, route) - assert.NoError(t, err) - assert.Nil(t, route.Spec.TLS) - assert.Equal(t, route.Spec.Port.TargetPort.IntVal, dep.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort) - - err = r.client.Get(context.TODO(), req.NamespacedName, nexus) - assert.NoError(t, err) - assert.NotNil(t, nexus) - assert.False(t, nexus.Status.ServerOperationsStatus.ServerReady) - assert.NotEmpty(t, nexus.Status.ServerOperationsStatus.Reason) - - // a second attempt must not requeue and not fail - res, err = r.Reconcile(req) - assert.NoError(t, err) - assert.False(t, res.Requeue) -} - -func TestReconcileNexus_Reconcile_Persistent(t *testing.T) { - ns := t.Name() - appName := "nexus3" - nexus := &v1alpha1.Nexus{ - ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: appName}, - Spec: v1alpha1.NexusSpec{ - Replicas: 1, - Persistence: v1alpha1.NexusPersistence{ - Persistent: true, - }, - ServerOperations: v1alpha1.ServerOperationsOpts{DisableOperatorUserCreation: true, DisableRepositoryCreation: true}, - Networking: v1alpha1.NexusNetworking{Expose: true, ExposeAs: v1alpha1.IngressExposeType, Host: "http://example.com"}, - }, - } - - // create objects to run reconcile - cl := test.NewFakeClientBuilder(nexus).WithIngress().Build() - r := newFakeReconcileNexus(cl) - - req := reconcile.Request{NamespacedName: types.NamespacedName{ - Namespace: ns, - Name: appName, - }} - - // reconcile phase - res, err := r.Reconcile(req) - assert.NoError(t, err) - assert.False(t, res.Requeue) - // should exist a pvc - pvc := &corev1.PersistentVolumeClaim{} - err = r.client.Get(context.TODO(), req.NamespacedName, pvc) - assert.NoError(t, err) - assert.Equal(t, resource.MustParse("10Gi"), pvc.Spec.Resources.Requests[corev1.ResourceStorage]) - ingress := &v1beta1.Ingress{} - err = r.client.Get(context.TODO(), req.NamespacedName, ingress) - assert.NoError(t, err) - assert.False(t, errors.IsNotFound(err)) -} - -func Test_add(t *testing.T) { - cli := test.NewFakeClientBuilder().Build() - mgr := test.NewManager(cli) - r := newFakeReconcileNexus(cli) - err := add(mgr, &r) - assert.NoError(t, err) -} - -func TestReconcileNexus_handleUpdate(t *testing.T) { - r := newFakeReconcileNexus(test.NewFakeClientBuilder().Build()) - baseNexus := validation.AllDefaultsCommunityNexus.DeepCopy() - baseNexus.Spec.AutomaticUpdate.Disabled = true - deploymentType := reflect.TypeOf(appsv1.Deployment{}) - - // First, let's test the first deployment scenario, which isn't an update - requiredRes := make(map[reflect.Type][]resUtils.KubernetesResource) - deployedRes := make(map[reflect.Type][]resUtils.KubernetesResource) - - requiredDep := &appsv1.Deployment{ - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Image: fmt.Sprintf("%s:%s", baseNexus.Spec.Image, "3.25.1"), - }, - }, - }, - }, - }, - } - requiredRes[deploymentType] = []resUtils.KubernetesResource{requiredDep} - assert.NoError(t, r.handleUpdate(baseNexus, requiredRes, deployedRes)) - - // Now let's test with an existing deployment - deployedDep := requiredDep.DeepCopy() - deployedRes[deploymentType] = []resUtils.KubernetesResource{deployedDep} - assert.NoError(t, r.handleUpdate(baseNexus, requiredRes, deployedRes)) -} - -func newFakeReconcileNexus(cl *test.FakeClient) ReconcileNexus { - return ReconcileNexus{ - client: cl, - scheme: scheme.Scheme, - discoveryClient: cl, - resourceSupervisor: nexusres.NewSupervisor(cl, cl), - } -} diff --git a/pkg/framework/controller_watcher.go b/pkg/framework/controller_watcher.go deleted file mode 100644 index 5c3e1dd1..00000000 --- a/pkg/framework/controller_watcher.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 framework - -import ( - "fmt" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - controllerruntime "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -// WatchedObjects objects that the controller supposed to watch for -type WatchedObjects struct { - // GroupVersion for the watched objects - GroupVersion schema.GroupVersion - // AddToScheme function to register the Scheme to the Kubernetes Client. This will enable the controller to query for those objects during the reconcile loop. - AddToScheme func(scheme *runtime.Scheme) error - // Objects list of required objects that should be watched by the controller - Objects []runtime.Object - // Owner of the object if different from the actual controller - Owner runtime.Object -} - -// ControllerWatcher helps to add required objects to the controller watch list given the required runtime objects -type ControllerWatcher interface { - // Watch add the given objects to the controller watch list - Watch(objects ...WatchedObjects) (err error) - // AreAllObjectsWatched verifies if this instance already has registered every required object in the watch list - AreAllObjectsWatched() bool - // IsGroupWatched verifies if the given group has it's objects watched or not - IsGroupWatched(group string) bool -} - -// NewControllerWatcher creates a new ControllerWatcher to control the objects that needed to be watched -func NewControllerWatcher(discoveryClient discovery.DiscoveryInterface, manager controllerruntime.Manager, controller controller.Controller, owner runtime.Object) ControllerWatcher { - return &controllerWatcher{ - manager: manager, - controller: controller, - owner: owner, - groupsNotWatched: map[string]bool{}, - discoverClient: discoveryClient, - } -} - -type controllerWatcher struct { - discoverClient discovery.DiscoveryInterface - manager controllerruntime.Manager - controller controller.Controller - owner runtime.Object - groupsNotWatched map[string]bool -} - -func (c *controllerWatcher) AreAllObjectsWatched() bool { - return len(c.groupsNotWatched) == 0 -} - -func (c *controllerWatcher) IsGroupWatched(group string) bool { - if len(c.groupsNotWatched) == 0 { - return true - } - _, exists := c.groupsNotWatched[group] - return !exists -} - -func (c *controllerWatcher) Watch(watchedObjects ...WatchedObjects) (err error) { - serverGroupMap, err := c.getServerGroupMap() - if err != nil { - return - } - - var addToScheme runtime.SchemeBuilder - var desiredObjects []WatchedObjects - - for _, object := range watchedObjects { - // core resources - if object.AddToScheme == nil { - desiredObjects = append(desiredObjects, object) - } else { - if _, found := serverGroupMap[object.GroupVersion.String()]; found { - addToScheme = append(addToScheme, object.AddToScheme) - desiredObjects = append(desiredObjects, object) - delete(c.groupsNotWatched, object.GroupVersion.Group) - } else { - c.groupsNotWatched[object.GroupVersion.Group] = true - log.Infof("Skipping registration of GroupVersion %s. CRD not installed in the cluster", object.GroupVersion) - } - } - } - - if len(addToScheme) > 0 { - log.Debug("Registering additional controller schemes") - if err = addToScheme.AddToScheme(c.manager.GetScheme()); err != nil { - return - } - } - - ownerHandler := &handler.EnqueueRequestForOwner{IsController: true, OwnerType: c.owner} - for _, desiredObject := range desiredObjects { - for _, runtimeObj := range desiredObject.Objects { - if desiredObject.Owner == nil { - if err = c.controller.Watch(&source.Kind{Type: runtimeObj}, ownerHandler); err != nil { - return - } - } else { - if err = c.controller.Watch( - &source.Kind{Type: runtimeObj}, - &handler.EnqueueRequestForOwner{IsController: true, OwnerType: desiredObject.Owner}); err != nil { - return - } - } - } - } - - return -} - -func (c *controllerWatcher) getServerGroupMap() (map[string]bool, error) { - serverGroups, err := c.discoverClient.ServerGroups() - if err != nil { - return nil, fmt.Errorf("couldn't fetch server groups list: %v", err) - } - - serverGroupMap := make(map[string]bool) - for _, serverGroup := range serverGroups.Groups { - for _, version := range serverGroup.Versions { - key := fmt.Sprintf("%s/%s", serverGroup.Name, version.Version) - serverGroupMap[key] = true - } - } - return serverGroupMap, nil -} diff --git a/pkg/framework/controller_watcher_test.go b/pkg/framework/controller_watcher_test.go deleted file mode 100644 index dbaf65c3..00000000 --- a/pkg/framework/controller_watcher_test.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 framework - -import ( - "testing" - - routev1 "github.com/openshift/api/route/v1" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/test" -) - -var requiredObjects = []WatchedObjects{ - { - GroupVersion: routev1.GroupVersion, - AddToScheme: routev1.Install, - Objects: []runtime.Object{&routev1.Route{}}, - }, - { - GroupVersion: networkingv1beta1.SchemeGroupVersion, - AddToScheme: networkingv1beta1.AddToScheme, - Objects: []runtime.Object{&networkingv1beta1.Ingress{}}, - }, - {Objects: []runtime.Object{&corev1.Service{}, &appsv1.Deployment{}, &corev1.PersistentVolumeClaim{}, &corev1.ServiceAccount{}}}, -} - -// K8s < 3.14 -func Test_controllerWatcher_WatchWithoutIngressOnKubernetes(t *testing.T) { - cli := test.NewFakeClientBuilder().Build() - controller := test.NewController() - manager := test.NewManager(cli) - - watcher := NewControllerWatcher(cli, manager, controller, &v1alpha1.Nexus{}) - assert.NotNil(t, watcher) - - err := watcher.Watch(requiredObjects...) - assert.NoError(t, err) - // We're not watching Routes and Ingresses - assert.False(t, watcher.AreAllObjectsWatched()) - // we should only have the objects from Kubernetes core - assert.Len(t, controller.GetWatchedSources(), 4) -} - -// K8s > 3.14 -func Test_controllerWatcher_WatchWithIngressOnKubernetes(t *testing.T) { - cli := test.NewFakeClientBuilder().WithIngress().Build() - controller := test.NewController() - manager := test.NewManager(cli) - - watcher := NewControllerWatcher(cli, manager, controller, &v1alpha1.Nexus{}) - assert.NotNil(t, watcher) - - err := watcher.Watch(requiredObjects...) - assert.NoError(t, err) - // We're not watching Routes - assert.False(t, watcher.AreAllObjectsWatched()) - // we should only have the objects from Kubernetes core and Ingress (networking/v1beta1) - assert.Len(t, controller.GetWatchedSources(), 5) -} - -// OCP -func Test_controllerWatcher_WatchWithRouteOnOpenShift(t *testing.T) { - cli := test.NewFakeClientBuilder().OnOpenshift().Build() - controller := test.NewController() - manager := test.NewManager(cli) - - watcher := NewControllerWatcher(cli, manager, controller, &v1alpha1.Nexus{}) - assert.NotNil(t, watcher) - - err := watcher.Watch(requiredObjects...) - assert.NoError(t, err) - // We're not watching Ingresses - assert.False(t, watcher.AreAllObjectsWatched()) - // we should only have the objects from Kubernetes core and Route (route/v1) - assert.Len(t, controller.GetWatchedSources(), 5) -} diff --git a/pkg/framework/fetcher.go b/pkg/framework/fetcher.go index 4c4f7008..58e4b421 100644 --- a/pkg/framework/fetcher.go +++ b/pkg/framework/fetcher.go @@ -21,16 +21,13 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/m88i/nexus-operator/pkg/logger" ) func Fetch(client client.Client, key types.NamespacedName, instance resource.KubernetesResource, kind string) error { - log := logger.GetLoggerWithNamespacedName("resource_fetcher", key) - log.Debugf("Attempting to fetch deployed %s", kind) + log.Info("Attempting to fetch deployed resource", "kind", kind, "namespacedName", key) if err := client.Get(ctx.TODO(), key, instance); err != nil { if errors.IsNotFound(err) { - log.Debugf("There is no deployed %s", kind) + log.Debug("Unable to find resource", "kind", kind, "namespacedName", key) } return err } diff --git a/pkg/framework/log.go b/pkg/framework/log.go index 44bc53db..a5f87321 100644 --- a/pkg/framework/log.go +++ b/pkg/framework/log.go @@ -18,4 +18,4 @@ import ( "github.com/m88i/nexus-operator/pkg/logger" ) -var log = logger.GetLogger("nexus_framework") +var log = logger.GetLogger("framework") diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 460f0c24..303e878e 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -15,167 +15,41 @@ package logger import ( - "io" - "os" - "time" - "github.com/RHsyseng/operator-utils/pkg/resource" "github.com/go-logr/logr" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" "k8s.io/apimachinery/pkg/types" - logf "sigs.k8s.io/controller-runtime/pkg/log" - logzap "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "github.com/m88i/nexus-operator/pkg/util" + "sigs.k8s.io/controller-runtime/pkg/log/zap" ) -var ( - defaultOutput = os.Stdout -) - -// Logger shared logger struct type Logger struct { - Logger logr.Logger - SugaredLogger *zap.SugaredLogger + logr.Logger } -// Opts describe logger options -type Opts struct { - // Verbose will increase logging - Verbose bool - // Output specifies where to log - Output io.Writer - // Output format - OutputFormat string - // Console logging doesn't display level nor timestamp and should be readable by humans - Console bool +func (l *Logger) Debug(message string, keysAndValues ...interface{}) { + l.Logger.V(1).Info(message, keysAndValues...) } -// GetLoggerWithOptions returns a custom named logger with given options -func GetLoggerWithOptions(name string, options *Opts) *zap.SugaredLogger { - if options == nil { - options = getDefaultOpts() - } else if options.Output == nil { - options.Output = defaultOutput - } - return getLogger(name, options) +// Warn alternative for info format with sprintf and WARN named. +func (l *Logger) Warn(message string, keysAndValues ...interface{}) { + l.Logger.WithName("WARNING").V(0).Info(message, keysAndValues...) } // GetLoggerWithResource returns a custom named logger with a resource's namespace and name as fields -func GetLoggerWithResource(name string, res resource.KubernetesResource) *zap.SugaredLogger { +func GetLoggerWithResource(name string, res resource.KubernetesResource) Logger { // we can't use framework.Key() here as it generates an import cycle (framework needs logging) key := types.NamespacedName{Name: res.GetName(), Namespace: res.GetNamespace()} return GetLoggerWithNamespacedName(name, key) } -func GetLoggerWithNamespacedName(name string, key types.NamespacedName) *zap.SugaredLogger { - options := getDefaultOpts() - return getLogger(name, options).With("namespace", key.Namespace, "resource name", key.Name) +func GetLoggerWithNamespacedName(name string, key types.NamespacedName) Logger { + logger := GetLogger(name) + logger.WithValues("nexus", key) + return logger } // GetLogger returns a custom named logger -func GetLogger(name string) *zap.SugaredLogger { - options := getDefaultOpts() - return getLogger(name, options) -} - -func getDefaultOpts() *Opts { - return &Opts{ - Verbose: util.GetBoolOSEnv("DEBUG"), - Output: defaultOutput, - Console: false, - } -} - -func getLogger(name string, options *Opts) *zap.SugaredLogger { - // Set log level... override default w/ command-line variable if set. - // The logger instantiated here can be changed to any logger - // implementing the logr.Logger interface. This logger will - // be propagated through the whole operator, generating - // uniform and structured logs. - logger := createLogger(options) - //logger.Logger = logf.Log.WithName(name) - return logger.SugaredLogger.Named(name) -} - -func createLogger(options *Opts) (logger Logger) { - log := Logger{ - Logger: logzap.New(func(opts *logzap.Options) { - opts.Development = options.Verbose - }), - SugaredLogger: zapSugaredLogger(options), - } - - logf.SetLogger(log.Logger) - return log -} - -// zapSugaredLogger is a Logger implementation. -// If development is true, a Zap development config will be used, -// otherwise a Zap production config will be used -// (stacktraces on errors, sampling). -func zapSugaredLogger(options *Opts) *zap.SugaredLogger { - return zapSugaredLoggerTo(options) -} - -// zapSugaredLoggerTo returns a new Logger implementation using Zap which logs -// to the given destination, instead of stderr. It otherise behaves like -// ZapLogger. -func zapSugaredLoggerTo(options *Opts) *zap.SugaredLogger { - // this basically mimics NewConfig, but with a custom sink - sink := zapcore.AddSync(options.Output) - - var enc zapcore.Encoder - var lvl zap.AtomicLevel - var opts []zap.Option - - if options.Console { - encCfg := zap.NewDevelopmentEncoderConfig() - if options.OutputFormat == "json" { - encCfg.CallerKey = util.GetOSEnv("KOGITO_LOGGER_CALLER_KEY", "caller") - encCfg.LevelKey = util.GetOSEnv("KOGITO_LOGGER_LEVEL_KEY", "level") - encCfg.MessageKey = util.GetOSEnv("KOGITO_LOGGER_MESSAGE_KEY", "message") - encCfg.NameKey = util.GetOSEnv("KOGITO_LOGGER_NAME_KEY", "name") - encCfg.StacktraceKey = util.GetOSEnv("KOGITO_LOGGER_STACKTRACE_KEY", "stacktrace") - encCfg.TimeKey = util.GetOSEnv("KOGITO_LOGGER_TIME_KEY", "time") - enc = zapcore.NewJSONEncoder(encCfg) - } else { - encCfg.CallerKey = util.GetOSEnv("KOGITO_LOGGER_CALLER_KEY", "") - encCfg.LevelKey = util.GetOSEnv("KOGITO_LOGGER_LEVEL_KEY", "") - encCfg.MessageKey = util.GetOSEnv("KOGITO_LOGGER_MESSAGE_KEY", encCfg.MessageKey) - encCfg.NameKey = util.GetOSEnv("KOGITO_LOGGER_NAME_KEY", "") - encCfg.StacktraceKey = util.GetOSEnv("KOGITO_LOGGER_STACKTRACE_KEY", encCfg.StacktraceKey) - encCfg.TimeKey = util.GetOSEnv("KOGITO_LOGGER_TIME_KEY", "") - enc = zapcore.NewConsoleEncoder(encCfg) - } - if options.Verbose { - lvl = zap.NewAtomicLevelAt(zap.DebugLevel) - } else { - lvl = zap.NewAtomicLevelAt(zap.InfoLevel) - } - opts = append(opts, zap.Development(), zap.AddStacktrace(zap.ErrorLevel)) - } else { - if options.Verbose { - encCfg := zap.NewDevelopmentEncoderConfig() - enc = zapcore.NewConsoleEncoder(encCfg) - lvl = zap.NewAtomicLevelAt(zap.DebugLevel) - opts = append(opts, zap.Development(), zap.AddStacktrace(zap.ErrorLevel)) - } else { - encCfg := zap.NewProductionEncoderConfig() - encCfg.TimeKey = "T" - encCfg.EncodeTime = zapcore.ISO8601TimeEncoder - enc = zapcore.NewJSONEncoder(encCfg) - lvl = zap.NewAtomicLevelAt(zap.InfoLevel) - opts = append(opts, zap.WrapCore(func(core zapcore.Core) zapcore.Core { - return zapcore.NewSamplerWithOptions(core, time.Second, 100, 100) - })) - } - } - - opts = append(opts, zap.AddCallerSkip(1), zap.ErrorOutput(sink)) - log := zap.New(zapcore.NewCore(&logzap.KubeAwareEncoder{Encoder: enc, Verbose: options.Verbose}, sink, lvl)) - log = log.WithOptions(opts...) - - return log.Sugar() +func GetLogger(name string) Logger { + logger := zap.New(zap.UseDevMode(true)) + logger.WithName(name) + return Logger{Logger: logger} } diff --git a/pkg/test/client.go b/pkg/test/client.go index cbbedc21..8f660518 100644 --- a/pkg/test/client.go +++ b/pkg/test/client.go @@ -17,7 +17,7 @@ package test import ( "context" - openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2" + openapi_v2 "github.com/googleapis/gnostic/openapiv2" routev1 "github.com/openshift/api/route/v1" "k8s.io/api/networking/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/util" ) @@ -52,7 +52,7 @@ type FakeClientBuilder struct { func NewFakeClientBuilder(initObjs ...runtime.Object) *FakeClientBuilder { s := scheme.Scheme util.Must(minimumSchemeBuilder().AddToScheme(s)) - res := []*metav1.APIResourceList{{GroupVersion: v1alpha1.SchemeGroupVersion.String()}} + res := []*metav1.APIResourceList{{GroupVersion: v1alpha1.GroupVersion.String()}} return &FakeClientBuilder{ initObjs: initObjs, diff --git a/pkg/test/client_test.go b/pkg/test/client_test.go index 8c7222df..49afdb32 100644 --- a/pkg/test/client_test.go +++ b/pkg/test/client_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" + "github.com/m88i/nexus-operator/api/v1alpha1" "github.com/m88i/nexus-operator/pkg/cluster/kubernetes" "github.com/m88i/nexus-operator/pkg/cluster/openshift" ) @@ -39,12 +39,12 @@ func TestNewFakeClientBuilder(t *testing.T) { b := NewFakeClientBuilder(nexus) // client.Client - assert.Len(t, b.scheme.KnownTypes(v1alpha1.SchemeGroupVersion), 10) - assert.Contains(t, b.scheme.KnownTypes(v1alpha1.SchemeGroupVersion), strings.Split(reflect.TypeOf(&v1alpha1.Nexus{}).String(), ".")[1]) - assert.Contains(t, b.scheme.KnownTypes(v1alpha1.SchemeGroupVersion), strings.Split(reflect.TypeOf(&v1alpha1.NexusList{}).String(), ".")[1]) + assert.Len(t, b.scheme.KnownTypes(v1alpha1.GroupVersion), 10) + assert.Contains(t, b.scheme.KnownTypes(v1alpha1.GroupVersion), strings.Split(reflect.TypeOf(&v1alpha1.Nexus{}).String(), ".")[1]) + assert.Contains(t, b.scheme.KnownTypes(v1alpha1.GroupVersion), strings.Split(reflect.TypeOf(&v1alpha1.NexusList{}).String(), ".")[1]) // discovery.DiscoveryInterface - assert.True(t, resourceListsContainsGroupVersion(b.resources, v1alpha1.SchemeGroupVersion.String())) + assert.True(t, resourceListsContainsGroupVersion(b.resources, v1alpha1.GroupVersion.String())) // initObjs assert.Len(t, b.initObjs, 1) diff --git a/pkg/test/controller_mocks.go b/pkg/test/controller_mocks.go deleted file mode 100644 index c77c5808..00000000 --- a/pkg/test/controller_mocks.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 test - -import ( - "net/http" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/record" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" - "sigs.k8s.io/controller-runtime/pkg/webhook" -) - -// NewController ... -func NewController() MockController { - return &controllerMock{} -} - -// MockController ... -type MockController interface { - controller.Controller - // GetWatchedSources gets all the sources added to the Mock - GetWatchedSources() []source.Source -} - -// controllerMock mock to handle with operator runtime internals -type controllerMock struct { - watches []source.Source -} - -func (c *controllerMock) Reconcile(reconcile.Request) (reconcile.Result, error) { - return reconcile.Result{}, nil -} - -func (c *controllerMock) Watch(src source.Source, eventhandler handler.EventHandler, predicates ...predicate.Predicate) error { - c.watches = append(c.watches, src) - return nil -} - -func (c *controllerMock) Start(stop <-chan struct{}) error { - return nil -} - -func (c *controllerMock) GetWatchedSources() []source.Source { - return c.watches -} - -// NewManager ... -func NewManager(cli client.Client) manager.Manager { - return &managerMock{scheme: runtime.NewScheme(), client: cli} -} - -type managerMock struct { - client client.Client - scheme *runtime.Scheme -} - -func (m managerMock) AddMetricsExtraHandler(path string, handler http.Handler) error { - panic("implement me") -} - -func (m managerMock) Elected() <-chan struct{} { - panic("implement me") -} - -func (m managerMock) Add(manager.Runnable) error { - return nil -} - -func (m managerMock) SetFields(interface{}) error { - return nil -} - -func (m managerMock) AddHealthzCheck(name string, check healthz.Checker) error { - panic("implement me") -} - -func (m managerMock) AddReadyzCheck(name string, check healthz.Checker) error { - panic("implement me") -} - -func (m managerMock) Start(<-chan struct{}) error { - panic("implement me") -} - -func (m managerMock) GetConfig() *rest.Config { - return nil -} - -func (m managerMock) GetScheme() *runtime.Scheme { - return m.scheme -} - -func (m managerMock) GetClient() client.Client { - return m.client -} - -func (m managerMock) GetFieldIndexer() client.FieldIndexer { - panic("implement me") -} - -func (m managerMock) GetCache() cache.Cache { - return nil -} - -func (m managerMock) GetEventRecorderFor(name string) record.EventRecorder { - return nil -} - -func (m managerMock) GetRESTMapper() meta.RESTMapper { - panic("implement me") -} - -func (m managerMock) GetAPIReader() client.Reader { - panic("implement me") -} - -func (m managerMock) GetWebhookServer() *webhook.Server { - panic("implement me") -} diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go deleted file mode 100644 index 6d2e6988..00000000 --- a/test/e2e/main_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package e2e - -import ( - "testing" - - f "github.com/operator-framework/operator-sdk/pkg/test" -) - -func TestMain(m *testing.M) { - f.MainEntry(m) -} diff --git a/test/e2e/nexus_test.go b/test/e2e/nexus_test.go deleted file mode 100644 index 75302216..00000000 --- a/test/e2e/nexus_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package e2e - -import ( - "testing" - "time" - - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/validation" - corev1 "k8s.io/api/core/v1" - - "github.com/m88i/nexus-operator/pkg/apis" - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - framework "github.com/operator-framework/operator-sdk/pkg/test" - "github.com/operator-framework/operator-sdk/pkg/test/e2eutil" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const nexusName = "nexus3" - -var ( - retryInterval = time.Second * 30 - timeout = time.Second * 720 - cleanupRetryInterval = time.Second * 1 - cleanupTimeout = time.Second * 5 - - defaultNexusSpec = func() v1alpha1.NexusSpec { - spec := v1alpha1.NexusSpec{ - AutomaticUpdate: v1alpha1.NexusAutomaticUpdate{Disabled: true}, - Replicas: 1, - Image: validation.NexusCommunityImage, - ImagePullPolicy: corev1.PullIfNotPresent, - Resources: validation.DefaultResources, - Persistence: v1alpha1.NexusPersistence{Persistent: false}, - UseRedHatImage: false, - GenerateRandomAdminPassword: false, - Networking: v1alpha1.NexusNetworking{Expose: true, NodePort: 31031, ExposeAs: v1alpha1.NodePortExposeType}, - ServiceAccountName: nexusName, - LivenessProbe: validation.DefaultProbe.DeepCopy(), - ReadinessProbe: validation.DefaultProbe.DeepCopy(), - } - spec.LivenessProbe.InitialDelaySeconds = 480 - return spec - }() -) - -func TestNexus(t *testing.T) { - nexusList := &v1alpha1.NexusList{} - err := framework.AddToFrameworkScheme(apis.AddToScheme, nexusList) - if err != nil { - t.Fatalf("failed to add custom resource scheme to framework: %v", err) - } - // run subtests - t.Run("nexus-group", func(t *testing.T) { - t.Run("Cluster", NexusCluster) - }) -} - -func NexusCluster(t *testing.T) { - t.Parallel() - ctx := framework.NewContext(t) - defer ctx.Cleanup() - err := ctx.InitializeClusterResources(&framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) - if err != nil { - t.Fatalf("failed to initialize cluster resources: %v", err) - } - t.Log("Initialized cluster resources") - namespace, err := ctx.GetOperatorNamespace() - if err != nil { - t.Fatal(err) - } - t.Logf("Operator namespace: %s", namespace) - // get global framework variables - f := framework.Global - // wait for nexus-operator to be ready - err = e2eutil.WaitForOperatorDeployment(t, f.KubeClient, namespace, "nexus-operator", 1, retryInterval, timeout) - if err != nil { - t.Fatal(err) - } - - tester := &tester{ - t: t, - f: f, - ctx: ctx, - } - - testCases := []struct { - name string - input *v1alpha1.Nexus - cleanup func() error - additionalChecks []func(nexus *v1alpha1.Nexus) error - }{ - { - name: "Smoke test: no persistence, nodeport exposure", - input: &v1alpha1.Nexus{ - ObjectMeta: metav1.ObjectMeta{ - Name: nexusName, - Namespace: namespace, - }, - Spec: defaultNexusSpec, - }, - cleanup: tester.defaultCleanup, - additionalChecks: nil, - }, - { - name: "Networking: ingress with no TLS", - input: &v1alpha1.Nexus{ - ObjectMeta: metav1.ObjectMeta{ - Name: nexusName, - Namespace: namespace, - }, - Spec: func() v1alpha1.NexusSpec { - spec := *defaultNexusSpec.DeepCopy() - spec.Networking = v1alpha1.NexusNetworking{Expose: true, ExposeAs: v1alpha1.IngressExposeType, Host: "test-example.com"} - return spec - }(), - }, - cleanup: tester.defaultCleanup, - additionalChecks: nil, - }, - { - name: "Networking: ingress with TLS secret", - input: &v1alpha1.Nexus{ - ObjectMeta: metav1.ObjectMeta{ - Name: nexusName, - Namespace: namespace, - }, - Spec: func() v1alpha1.NexusSpec { - spec := *defaultNexusSpec.DeepCopy() - spec.Networking = v1alpha1.NexusNetworking{Expose: true, ExposeAs: v1alpha1.IngressExposeType, Host: "test-example.com", TLS: v1alpha1.NexusNetworkingTLS{SecretName: "test-secret"}} - return spec - }(), - }, - cleanup: tester.defaultCleanup, - additionalChecks: nil, - }, - } - - for _, testCase := range testCases { - tester.t.Logf("Test: %s\nInput: %+v", testCase.name, testCase.input) - if err = tester.runChecks(testCase.input, testCase.additionalChecks...); err != nil { - tester.t.Fatal(err) - } - if err = testCase.cleanup(); err != nil { - tester.t.Logf("%v", err) - } - } -} diff --git a/test/e2e/tester_test.go b/test/e2e/tester_test.go deleted file mode 100644 index 98bbe3bb..00000000 --- a/test/e2e/tester_test.go +++ /dev/null @@ -1,235 +0,0 @@ -package e2e - -import ( - "context" - "reflect" - "testing" - - "github.com/m88i/nexus-operator/pkg/apis/apps/v1alpha1" - "github.com/m88i/nexus-operator/pkg/controller/nexus/resource/deployment" - "github.com/m88i/nexus-operator/pkg/controller/nexus/server" - "github.com/m88i/nexus-operator/pkg/framework" - "github.com/operator-framework/operator-sdk/pkg/test" - "github.com/operator-framework/operator-sdk/pkg/test/e2eutil" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type tester struct { - t *testing.T - f *test.Framework - ctx *test.Context -} - -func (tester *tester) defaultCleanup() error { - namespace, err := tester.ctx.GetOperatorNamespace() - if err != nil { - return err - } - return tester.f.Client.DeleteAllOf(context.TODO(), &v1alpha1.Nexus{}, client.InNamespace(namespace)) -} - -func (tester *tester) runChecks(nexus *v1alpha1.Nexus, additionalChecks ...func(nexus *v1alpha1.Nexus) error) error { - err := tester.createAndWait(nexus) - if err != nil { - return err - } - - tester.checkService(nexus) - tester.checkPVC(nexus) - tester.checkDeployment(nexus) - tester.checkServiceAccount(nexus) - tester.checkIngress(nexus) - tester.checkServerInteraction(nexus) - - for _, check := range additionalChecks { - if err = check(nexus); err != nil { - return err - } - } - return nil -} - -func (tester *tester) createAndWait(nexus *v1alpha1.Nexus) error { - // use TestCtx's create helper to create the object and add a cleanup function for the new object - err := tester.f.Client.Create(context.TODO(), nexus, &test.CleanupOptions{TestContext: tester.ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) - if err != nil { - return err - } - // wait for nexus3 to finish deployment - err = e2eutil.WaitForDeployment(tester.t, tester.f.KubeClient, nexus.Namespace, nexus.Name, int(nexus.Spec.Replicas), retryInterval, timeout) - assert.NoError(tester.t, err) - return nil -} - -func (tester *tester) checkService(nexus *v1alpha1.Nexus) { - svc := &corev1.Service{} - err := tester.f.Client.Get(context.TODO(), types.NamespacedName{Name: nexus.Name, Namespace: nexus.Namespace}, svc) - assert.NoError(tester.t, err) - assert.NotNil(tester.t, svc) - - assert.Equal(tester.t, deployment.DefaultHTTPPort, int(svc.Spec.Ports[0].Port)) - assert.Equal(tester.t, deployment.NexusServicePort, int(svc.Spec.Ports[0].TargetPort.IntVal)) - assert.Equal(tester.t, deployment.NexusPortName, svc.Spec.Ports[0].Name) - - if nexus.Spec.Networking.ExposeAs == v1alpha1.NodePortExposeType { - assert.Equal(tester.t, nexus.Spec.Networking.NodePort, svc.Spec.Ports[0].NodePort) - assert.Equal(tester.t, corev1.ServiceTypeNodePort, svc.Spec.Type) - assert.Equal(tester.t, corev1.ServiceExternalTrafficPolicyTypeCluster, svc.Spec.ExternalTrafficPolicy) - } -} - -func (tester *tester) checkPVC(nexus *v1alpha1.Nexus) { - pvc := &corev1.PersistentVolumeClaim{} - err := tester.f.Client.Get(context.TODO(), types.NamespacedName{Name: nexus.Name, Namespace: nexus.Namespace}, pvc) - - if !nexus.Spec.Persistence.Persistent { - assert.NotNil(tester.t, err) - assert.True(tester.t, errors.IsNotFound(err)) - return - } - - assert.Nil(tester.t, err) - assert.Equal(tester.t, resource.MustParse(nexus.Spec.Persistence.VolumeSize), pvc.Spec.Resources.Requests[corev1.ResourceStorage]) - - if nexus.Spec.Replicas > 1 { - assert.Equal(tester.t, corev1.ReadWriteMany, pvc.Spec.AccessModes[0]) - } else { - assert.Equal(tester.t, corev1.ReadWriteOnce, pvc.Spec.AccessModes[0]) - } - - if len(nexus.Spec.Persistence.StorageClass) > 0 { - assert.Equal(tester.t, nexus.Spec.Persistence.StorageClass, *pvc.Spec.StorageClassName) - } -} - -func (tester *tester) checkDeployment(nexus *v1alpha1.Nexus) { - d := &appsv1.Deployment{} - err := tester.f.Client.Get(context.TODO(), types.NamespacedName{Name: nexus.Name, Namespace: nexus.Namespace}, d) - assert.NoError(tester.t, err) - - assert.True(tester.t, reflect.DeepEqual(d.Spec.Template.Spec.Containers[0].Resources.Requests, nexus.Spec.Resources.Requests)) - assert.True(tester.t, reflect.DeepEqual(d.Spec.Template.Spec.Containers[0].Resources.Limits, nexus.Spec.Resources.Limits)) - - assert.Equal(tester.t, nexus.Spec.Replicas, *d.Spec.Replicas) - assert.Equal(tester.t, nexus.Spec.ServiceAccountName, d.Spec.Template.Spec.ServiceAccountName) - assert.Equal(tester.t, nexus.Spec.Image, d.Spec.Template.Spec.Containers[0].Image) - assert.True(tester.t, tester.containsJvmEnv(d)) - - if nexus.Spec.Persistence.Persistent { - assert.NotEmpty(tester.t, d.Spec.Template.Spec.Volumes) - assert.NotEmpty(tester.t, d.Spec.Template.Spec.Containers[0].VolumeMounts) - } else { - assert.Empty(tester.t, d.Spec.Template.Spec.Volumes) - assert.Empty(tester.t, d.Spec.Template.Spec.Containers[0].VolumeMounts) - } - - // here we only check if the security context has been set as we don't want to couple the business logic (and the actual values) to this test - // testing the logic is up to the unit test - if nexus.Spec.UseRedHatImage { - assert.Nil(tester.t, d.Spec.Template.Spec.SecurityContext) - } else { - assert.NotNil(tester.t, d.Spec.Template.Spec.SecurityContext) - } - - tester.checkDeploymentProbes(nexus, d) -} - -func (tester *tester) containsJvmEnv(d *appsv1.Deployment) bool { - // here we only check if the parameters have been set as we don't want to couple the calculation logic to this test - // testing the logic is up to the unit test - for _, env := range d.Spec.Template.Spec.Containers[0].Env { - if env.Name == deployment.JvmArgsEnvKey { - return true - } - } - return false -} - -func (tester *tester) checkDeploymentProbes(nexus *v1alpha1.Nexus, d *appsv1.Deployment) { - assert.Equal(tester.t, nexus.Spec.LivenessProbe.FailureThreshold, d.Spec.Template.Spec.Containers[0].LivenessProbe.FailureThreshold) - assert.Equal(tester.t, nexus.Spec.LivenessProbe.PeriodSeconds, d.Spec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds) - assert.Equal(tester.t, nexus.Spec.LivenessProbe.SuccessThreshold, d.Spec.Template.Spec.Containers[0].LivenessProbe.SuccessThreshold) - assert.Equal(tester.t, nexus.Spec.LivenessProbe.TimeoutSeconds, d.Spec.Template.Spec.Containers[0].LivenessProbe.TimeoutSeconds) - assert.Equal(tester.t, nexus.Spec.LivenessProbe.InitialDelaySeconds, d.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds) - - assert.Equal(tester.t, nexus.Spec.ReadinessProbe.FailureThreshold, d.Spec.Template.Spec.Containers[0].ReadinessProbe.FailureThreshold) - assert.Equal(tester.t, nexus.Spec.ReadinessProbe.PeriodSeconds, d.Spec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds) - assert.Equal(tester.t, nexus.Spec.ReadinessProbe.SuccessThreshold, d.Spec.Template.Spec.Containers[0].ReadinessProbe.SuccessThreshold) - assert.Equal(tester.t, nexus.Spec.ReadinessProbe.TimeoutSeconds, d.Spec.Template.Spec.Containers[0].ReadinessProbe.TimeoutSeconds) - assert.Equal(tester.t, nexus.Spec.ReadinessProbe.InitialDelaySeconds, d.Spec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds) -} - -func (tester *tester) checkServiceAccount(nexus *v1alpha1.Nexus) { - account := &corev1.ServiceAccount{} - err := tester.f.Client.Get(context.TODO(), types.NamespacedName{Name: nexus.Name, Namespace: nexus.Namespace}, account) - assert.Nil(tester.t, err) -} - -func (tester *tester) checkIngress(nexus *v1alpha1.Nexus) { - if !nexus.Spec.Networking.Expose { - return - } - - ingress := &v1beta1.Ingress{} - err := tester.f.Client.Get(context.TODO(), types.NamespacedName{Namespace: nexus.Namespace, Name: nexus.Name}, ingress) - - if nexus.Spec.Networking.ExposeAs != v1alpha1.IngressExposeType { - assert.NotNil(tester.t, err) - assert.True(tester.t, errors.IsNotFound(err)) - return - } - - assert.Nil(tester.t, err) - assert.Equal(tester.t, nexus.Spec.Networking.Host, ingress.Spec.Rules[0].Host) - assert.True(tester.t, tester.ingressPointsToCorrectService(nexus, ingress)) - - if len(nexus.Spec.Networking.TLS.SecretName) > 0 { - assert.Equal(tester.t, nexus.Spec.Networking.TLS.SecretName, ingress.Spec.TLS[0].SecretName) - assert.Contains(tester.t, ingress.Spec.TLS[0].Hosts, nexus.Spec.Networking.Host) - } -} - -func (tester *tester) ingressPointsToCorrectService(nexus *v1alpha1.Nexus, ingress *v1beta1.Ingress) bool { - for _, path := range ingress.Spec.Rules[0].IngressRuleValue.HTTP.Paths { - if path.Backend.ServiceName == nexus.Name { - return true - } - } - return false -} - -// checkServerInteraction verifies if the secret holding operator user credentials has the credentials or not -func (tester *tester) checkServerInteraction(nexus *v1alpha1.Nexus) { - tester.t.Log("Checking Nexus Server interactions") - if nexus.Spec.ServerOperations.DisableOperatorUserCreation || nexus.Spec.GenerateRandomAdminPassword { - tester.t.Log("Nexus Server interactions disabled, skipping") - return - } - err := wait.Poll(retryInterval, timeout, func() (done bool, err error) { - secret := &corev1.Secret{ObjectMeta: v1.ObjectMeta{Name: nexus.Name, Namespace: nexus.Namespace}} - err = tester.f.Client.Get(context.TODO(), framework.Key(nexus), secret) - if err != nil { - if errors.IsNotFound(err) { - tester.t.Log("Waiting for Nexus secret to be available") - return false, nil - } - return false, err - } - if len(secret.Data[server.SecretKeyUsername]) > 0 && len(secret.Data[server.SecretKeyPassword]) > 0 { - tester.t.Log("Nexus Operator credentials found! Test OK.") - return true, nil - } - tester.t.Log("Waiting for Nexus secret to have credentials") - return false, nil - }) - assert.NoError(tester.t, err) -} diff --git a/version/version.go b/version/version.go deleted file mode 100644 index 9ee7eacc..00000000 --- a/version/version.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2020 Nexus Operator and/or its authors -// -// 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 version - -var ( - // Version of the Operator :-) - Version = "0.4.0" -)