diff --git a/.gitignore b/.gitignore index a8c2512517..5d41d3ce46 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ tmp/ # ready to work samples deploy/ +__debug_bin/ diff --git a/Dockerfile b/Dockerfile index a170f3c2a8..6960dc7e02 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,9 @@ WORKDIR /workspace # Copy the Go Modules manifests COPY go.mod go.mod COPY go.sum go.sum +# Copy DBaaSProvider config +COPY config/dbaasprovider/dbaas_provider.yaml dbaas_provider.yaml + # 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 @@ -50,6 +53,7 @@ LABEL name="MongoDB Atlas Operator" \ WORKDIR / COPY --from=builder /workspace/bin/manager . COPY hack/licenses licenses +COPY --from=builder /workspace/dbaas_provider.yaml . USER 1001:0 ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index e4752ea3de..3e5c4e70d0 100644 --- a/Makefile +++ b/Makefile @@ -9,12 +9,14 @@ CONTAINER_ENGINE?=docker # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.8.0 +VERSION ?= 0.3.0 ifndef PRODUCT_VERSION PRODUCT_VERSION := $(shell git describe --tags --dirty --broken) endif +CONTAINER_ENGINE?=docker + # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "preview,fast,stable") # To re-generate a bundle for other specific channels without changing the standard setup, you can: @@ -38,17 +40,19 @@ BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) # Base registry for the operator, bundle, catalog images REGISTRY ?= quay.io/mongodb -# BUNDLE_IMG defines the image:tag used for the bundle. -# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) -BUNDLE_IMG ?= $(REGISTRY)/mongodb-atlas-controller-bundle:$(VERSION) - # Image URL to use all building/pushing image targets -IMG ?= mongodb-atlas-controller:latest -#BUNDLE_REGISTRY ?= $(REGISTRY)/mongodb-atlas-operator-bundle -OPERATOR_REGISTRY ?= $(REGISTRY)/mongodb-atlas-operator -CATALOG_REGISTRY ?= $(REGISTRY)/mongodb-atlas-catalog -OPERATOR_IMAGE ?= ${OPERATOR_REGISTRY}:${VERSION} -CATALOG_IMAGE ?= ${CATALOG_REGISTRY}:${VERSION} +IMG ?= $(REGISTRY)/mongodb-atlas-kubernetes-dbaas +OPERATOR_REGISTRY ?= $(IMG) + +OPERATOR_IMG ?= $(IMG):$(VERSION) +# OPERATOR_IMG ?= $(IMG):latest + +BUNDLE_IMG ?= $(IMG)-bundle:$(VERSION) +# BUNDLE_IMG ?= $(IMG)-bundle:latest + +CATALOG_IMG ?= $(IMG)-catalog:$(VERSION) +# CATALOG_IMG ?= ${IMG}-catalog:latest + TARGET_NAMESPACE ?= mongodb-atlas-operator-system-test # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -168,37 +172,43 @@ endef .PHONY: bundle bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files. operator-sdk generate kustomize manifests -q --apis-dir=pkg/api - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build --load-restrictor LoadRestrictionsNone config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMG) + $(KUSTOMIZE) build --load-restrictor LoadRestrictionsNone config/manifests | operator-sdk generate bundle -q --overwrite --manifests --version $(VERSION) $(BUNDLE_METADATA_OPTS) operator-sdk bundle validate ./bundle .PHONY: image image: manager ## Build the operator image - $(CONTAINER_ENGINE) build -t $(OPERATOR_IMAGE) . - $(CONTAINER_ENGINE) push $(OPERATOR_IMAGE) + $(CONTAINER_ENGINE) build -t $(OPERATOR_IMG) . + $(CONTAINER_ENGINE) push $(OPERATOR_IMG) .PHONY: bundle-build bundle-build: ## Build the bundle image. $(CONTAINER_ENGINE) build -f bundle.Dockerfile -t $(BUNDLE_IMG) . .PHONY: bundle-push -bundle-push: +bundle-push: ## Push the bundle image. $(CONTAINER_ENGINE) push $(BUNDLE_IMG) +# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). +# These images MUST exist in a registry and be pull-able. +BUNDLE_IMGS ?= $(BUNDLE_IMG) + .PHONY: catalog-build CATALOG_DIR ?= ./scripts/openshift/atlas-catalog +#catalog-build: IMG= catalog-build: ## bundle bundle-push ## Build file-based bundle - $(MAKE) image IMG=$(REGISTRY)/mongodb-atlas-operator:$(VERSION) + $(MAKE) image IMG=$(IMG) CATALOG_DIR=$(CATALOG_DIR) \ CHANNEL=$(DEFAULT_CHANNEL) \ - CATALOG_IMAGE=$(CATALOG_IMAGE) \ + CATALOG_IMAGE=$(CATALOG_IMG) \ BUNDLE_IMAGE=$(BUNDLE_IMG) \ VERSION=$(VERSION) \ + CONTAINER_ENGINE=$(CONTAINER_ENGINE) \ ./scripts/build_catalog.sh .PHONY: catalog-push catalog-push: - $(CONTAINER_ENGINE) push $(CATALOG_IMAGE) + $(CONTAINER_ENGINE) push $(CATALOG_IMG) .PHONY: build-subscription build-subscription: @@ -210,12 +220,12 @@ build-subscription: .PHONY: build-catalogsource build-catalogsource: CATALOG_DIR=$(shell dirname "$(CATALOG_DIR)") \ - CATALOG_IMAGE=$(CATALOG_IMAGE) \ + CATALOG_IMG=$(CATALOG_IMG) \ ./scripts/build_catalogsource.sh .PHONY: deploy-olm # Deploy atlas operator to the running openshift cluster with OLM -deploy-olm: export IMG=$(REGISTRY)/mongodb-atlas-operator:$(VERSION) +deploy-olm: export IMG=$(OPERATOR_IMAGE) deploy-olm: bundle-build bundle-push catalog-build catalog-push build-catalogsource build-subscription oc -n openshift-marketplace delete catalogsource mongodb-atlas-kubernetes-local --ignore-not-found oc delete namespace $(TARGET_NAMESPACE) --ignore-not-found @@ -231,7 +241,7 @@ deploy-olm: bundle-build bundle-push catalog-build catalog-push build-catalogsou .PHONY: image-push image-push: ## Push the docker image - $(CONTAINER_ENGINE) push ${IMG} + $(CONTAINER_ENGINE) push ${OPERATOR_IMG} # Additional make goals .PHONY: run-kind diff --git a/PROJECT b/PROJECT index f2bf4402e7..8608c8fe16 100644 --- a/PROJECT +++ b/PROJECT @@ -1,6 +1,6 @@ domain: mongodb.com layout: -- go.kubebuilder.io/v2 +- go.kubebuilder.io/v3 plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {} @@ -15,7 +15,33 @@ resources: group: atlas kind: AtlasDeployment path: github.com/mongodb/mongodb-atlas-kubernetes/api/v1 - version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: redhat.com + group: dbaas + kind: MongoDBAtlasConnection + path: github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas + version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: redhat.com + group: dbaas + kind: MongoDBAtlasInventory + path: github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas + version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: redhat.com + group: dbaas + kind: MongoDBAtlasInstance + path: github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas + version: v1alpha1 - api: crdVersion: v1 namespaced: true diff --git a/README.md b/README.md index 90b7f505d6..c7e1cadc95 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,200 @@ Operator support Third Party Integration. - [Mongodb Atlas Operator sample](docs/project-integration.md) - [Atlas documentation Atlas](https://docs.atlas.mongodb.com/reference/api/third-party-integration-settings/) +### Step 4. Test Database as a Service (DBaaS) on OpenShift + +The Atlas Operator is integrated with the [Red Hat Database-as-a-Service (DBaaS) Operator](https://github.com/RHEcosystemAppEng/dbaas-operator) which allows application developers to import database instances and connect to the databases through the [Service Binding Operator](https://github.com/redhat-developer/service-binding-operator). More information can be found [here](https://github.com/RHEcosystemAppEng/dbaas-operator#readme). + +Note that both the DBaaS Operator and Atlas Operator should be installed through the [Operator Lifecyle Manager (OLM)](https://github.com/operator-framework/operator-lifecycle-manager). + +**1.** Check DBaaS Registration + +If the DBaaS Operator has been deployed in the OpenShift Cluster, the Atlas Operator automatically creates a cluster level [DBaaSProvider](https://github.com/RHEcosystemAppEng/dbaas-operator/blob/main/config/crd/bases/dbaas.redhat.com_dbaasproviders.yaml) custom resource (CR) object `mongodb-atlas-registration` to automatically register itself with the DBaaS Operator. + +``` +apiVersion: dbaas.redhat.com/v1alpha1 +kind: DBaaSProvider +metadata: + labels: + related-to: dbaas-operator + type: dbaas-provider-registration + name: mongodb-atlas-registration +spec: + connectionKind: MongoDBAtlasConnection + credentialFields: + - displayName: Organization ID + key: orgId + required: true + type: string + - displayName: Public API Key + key: publicApiKey + required: true + type: string + - displayName: Private API Key + key: privateApiKey + required: true + type: maskedstring + inventoryKind: MongoDBAtlasInventory + provider: + displayDescription: Cloud-hosted MongoDB service on AWS, Azure and Google Cloud + displayName: MongoDB Atlas Cloud Database Service + icon: + base64data: + mediatype: image/png + name: Red Hat DBaaS / MongoDB Atlas +``` +If the Atlas Operator is undeployed with the OLM, the above registration CR gets cleaned up automatically. + +**2.** Check MongoDBAtlasInventory Custom Resource + +First an administrator creates a [DBaaSInventory](https://github.com/RHEcosystemAppEng/dbaas-operator/blob/main/config/crd/bases/dbaas.redhat.com_dbaasinventories.yaml) CR for MongoDB. The DBaaS Operator automatically creates a MongoDBAtlasInventory CR, and the Atlas Operator discovers the clusters and instances, and sets the result in the CR status. +Here is an example of MongoDBAtlasInventory CR. +``` +apiVersion: dbaas.redhat.com/v1alpha1 +kind: MongoDBAtlasInventory +metadata: + name: dbaas-mytest + namespace: openshift-operators + ownerReferences: + - apiVersion: dbaas.redhat.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: DBaaSInventory + name: dbaas-mytest + uid: 01f5a690-c640-462f-b6e8-ccb9db95df70 +spec: + credentialsRef: + name: my-atlas-key + namespace: openshift-operators +status: + conditions: + - lastTransitionTime: "2021-08-18T20:06:47Z" + message: Spec sync OK + reason: SyncOK + status: "True" + type: SpecSynced + instances: + - instanceID: 608df625aa94426b4169999 + instanceInfo: + dbaas-cluster1.a00aa.Srv: mongodb+srv://dbaas-cluster1.a00aa.mongodb.net + instanceSizeName: M0 + projectID: 608df5e652e1944293e11111 + projectName: Project 1 + providerName: TENANT + regionName: US_EAST_1 + name: DBaaS-Cluster1 + - instanceID: 60807282b4ab8d3b3c123456 + instanceInfo: + dbaas-cluster1.a00aa.Srv: mongodb+srv://test123.edbca.mongodb.net + instanceSizeName: M10 + projectID: 6065e15b16c0731bf3a12333 + projectName: Project 2 + providerName: AWS + regionName: US_EAST_1 + name: test + - instanceID: 12345ffbc9a90e310e642482 + instanceInfo: + dbaas-cluster1.a00aa.Srv: mongodb+srv://testcluster1.edbca.mongodb.net + instanceSizeName: M0 + projectID: 6065e15b16c0731bf3a12333 + projectName: Project 2 + providerName: TENANT + regionName: US_EAST_1 + name: DBCreatedInAtalas + - instanceID: 60b7a72f4877d05881234567 + instanceInfo: + dbaas-cluster1.a00aa.Srv: mongodb+srv://test.abcd9.mongodb.net + instanceSizeName: M10 + projectID: 60b798fea37f9f09acc12345 + projectName: mytest + providerName: AWS + regionName: US_EAST_1 + name: test +``` +**3.** Check MongoDBAtlasConnection Custom Resource + +Now the application developer can create a [DBaaSConnection](https://github.com/RHEcosystemAppEng/dbaas-operator/blob/main/config/crd/bases/dbaas.redhat.com_dbaasconnections.yaml) CR for connection to the MongoDB database instance found, the DBaaS Operator automatically creates a MongoDBAtlasConnection CR. The Atlas Operator creates a database user in Atlas for the cluster with the default database `admin`. The Atlas Operator stores the db user credentials in a kubernetes secret, and the remaining connection information in a configmap, and then updates the MongoDBAtlasConnection CR status. + +Here is an example of MongoDBAtlasConnection CR. +``` +apiVersion: dbaas.redhat.com/v1alpha1 +kind: MongoDBAtlasConnection +metadata: + name: test-dbaas-connection + namespace: test-namespace + ownerReferences: + - apiVersion: dbaas.redhat.com/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: DBaaSConnection + name: test-dbaas-connection + uid: 77193619-6ab1-43c9-acf2-a40c2cfe7703 +spec: + instanceID: 12345ffbc9a90e310e642482 + inventoryRef: + name: dbaas-mytest + namespace: openshift-operators +status: + conditions: + - lastTransitionTime: "2021-08-18T20:07:51Z" + message: "" + reason: Ready + status: "True" + type: ReadyForBinding + connectionInfoRef: + name: atlas-connection-cm-knp9z + credentialsRef: + name: atlas-db-user-5pc8b +``` +The corresponding generated secret: +``` +apiVersion: v1 +data: + password: cGFzczEyM3dAcmQ= + username: ZGJVc2VyXzEwMQ== +kind: Secret +metadata: + labels: + managed-by: atlas-operator + owner: test-dbaas-connection + owner.kind: MongoDBAtlasConnection + owner.namespace: test-namespace + name: atlas-db-user-5pc8b + namespace: test-namespace + ownerReferences: + - apiVersion: dbaas.redhat.com/v1alpha1 + blockOwnerDeletion: false + controller: true + kind: MongoDBAtlasConnection + name: test-dbaas-connection + uid: a50b06db-8fa1-45c9-9893-833a028dfccc +type: Opaque +``` +The corresponding generated configmap: +``` +apiVersion: v1 +data: + host: cluster0.ubajs.mongodb.net + provider: Red Hat DBaaS / MongoDB Atlas + srv: "true" + type: mongodb +kind: ConfigMap +metadata: + labels: + managed-by: atlas-operator + owner: test-dbaas-connection + owner.kind: MongoDBAtlasConnection + owner.namespace: test-namespace + name: atlas-connection-cm-knp9z + namespace: test-namespace + ownerReferences: + - apiVersion: dbaas.redhat.com/v1alpha1 + blockOwnerDeletion: false + controller: true + kind: MongoDBAtlasConnection + name: test-dbaas-connection + uid: a50b06db-8fa1-45c9-9893-833a028dfccc +``` ## How to Contribute Please file issues before filing PRs. For PRs to be accepted, contributors must sign diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 05931aa117..0412689591 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -1,6 +1,7 @@ FROM scratch -LABEL com.redhat.openshift.versions="v4.5-v4.10" +# RH OLM annotations +LABEL com.redhat.openshift.versions="v4.5,v4.6" LABEL com.redhat.delivery.backport=true LABEL com.redhat.delivery.operator.bundle=true @@ -13,7 +14,7 @@ LABEL operators.operatorframework.io.bundle.channels.v1=stable LABEL operators.operatorframework.io.bundle.channel.default.v1=stable LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.15.0+git LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v2 +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 # Labels for testing. LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 diff --git a/bundle/manifests/atlas.mongodb.com_atlasprojects.yaml b/bundle/manifests/atlas.mongodb.com_atlasprojects.yaml index 61c974ec6a..0f7798cf8c 100644 --- a/bundle/manifests/atlas.mongodb.com_atlasprojects.yaml +++ b/bundle/manifests/atlas.mongodb.com_atlasprojects.yaml @@ -43,6 +43,24 @@ spec: description: AtlasProjectSpec defines the desired state of Project in Atlas properties: + cloudProviderAccessRoles: + description: CloudProviderAccessRoles is a list of Cloud Provider + Access Roles configured for the current Project. + items: + properties: + iamAssumedRoleArn: + description: IamAssumedRoleArn is the ARN of the IAM role that + is assumed by the Atlas cluster. + type: string + providerName: + description: ProviderName is the name of the cloud provider. + Currently only AWS is supported. + type: string + required: + - iamAssumedRoleArn + - providerName + type: object + type: array connectionSecretRef: description: ConnectionSecret is the name of the Kubernetes Secret which contains the information about the way to connect to Atlas @@ -267,6 +285,67 @@ spec: description: Name is the name of the Project that is created in Atlas by the Operator if it doesn't exist yet. type: string + networkPeers: + description: NetworkPeers is a list of Network Peers configured for + the current Project. + items: + properties: + accepterRegionName: + description: AccepterRegionName is the provider region name + of user's vpc. + type: string + atlasCidrBlock: + description: Atlas CIDR. It needs to be set if ContainerID is + not set. + type: string + awsAccountId: + description: AccountID of the user's vpc. + type: string + azureDirectoryId: + description: AzureDirectoryID is the unique identifier for an + Azure AD directory. + type: string + azureSubscriptionId: + description: AzureSubscriptionID is the unique identifier of + the Azure subscription in which the VNet resides. + type: string + containerId: + description: ID of the network peer container. If not set, operator + will create a new container with ContainerRegion and AtlasCIDRBlock + input. + type: string + containerRegion: + description: ContainerRegion is the provider region name of + Atlas network peer container. If not set, AccepterRegionName + is used. + type: string + gcpProjectId: + description: User GCP Project ID. Its applicable only for GCP. + type: string + networkName: + description: GCP Network Peer Name. Its applicable only for + GCP. + type: string + providerName: + description: ProviderName is the name of the provider. If not + set, it will be set to "AWS". + type: string + resourceGroupName: + description: ResourceGroupName is the name of your Azure resource + group. + type: string + routeTableCidrBlock: + description: User VPC CIDR. + type: string + vnetName: + description: VNetName is name of your Azure VNet. Its applicable + only for Azure. + type: string + vpcId: + description: AWS VPC ID. + type: string + type: object + type: array privateEndpoints: description: PrivateEndpoints is a list of Private Endpoints configured for the current Project. @@ -380,6 +459,43 @@ spec: items: type: string type: array + cloudProviderAccessRoles: + description: CloudProviderAccessRoles contains a list of configured + cloud provider access roles. AWS support only + items: + properties: + atlasAWSAccountArn: + type: string + atlasAssumedRoleExternalId: + type: string + authorizedDate: + type: string + createdDate: + type: string + errorMessage: + type: string + featureUsages: + items: + properties: + featureId: + type: string + featureType: + type: string + type: object + type: array + iamAssumedRoleArn: + type: string + providerName: + type: string + roleId: + type: string + status: + type: string + required: + - atlasAssumedRoleExternalId + - providerName + type: object + type: array conditions: description: Conditions is the list of statuses showing the current state of the Atlas Custom Resource @@ -440,6 +556,72 @@ spec: id: description: The ID of the Atlas Project type: string + networkPeers: + description: The list of network peers that are configured for current + project + items: + properties: + atlasGcpProjectId: + description: ProjectID of Atlas container. Applicable only for + GCP. It's needed to add network peer connection. + type: string + atlasNetworkName: + description: Atlas Network Name. Applicable only for GCP. It's + needed to add network peer connection. + type: string + connectionId: + description: Unique identifier of the network peer connection. + Applicable only for AWS. + type: string + containerId: + description: ContainerID of Atlas network peer container. + type: string + errorMessage: + description: Error state of the network peer. Applicable only + for GCP. + type: string + errorState: + description: Error state of the network peer. Applicable only + for Azure. + type: string + errorStateName: + description: Error state of the network peer. Applicable only + for AWS. + type: string + gcpProjectId: + description: ProjectID of the user's vpc. Applicable only for + GCP. + type: string + id: + description: Unique identifier for NetworkPeer. + type: string + providerName: + description: Cloud provider for which you want to retrieve a + network peer. + type: string + region: + description: Region for which you want to create the network + peer. It isn't needed for GCP + type: string + status: + description: Status of the network peer. Applicable only for + GCP and Azure. + type: string + statusName: + description: Status of the network peer. Applicable only for + AWS. + type: string + vpc: + description: VPC is general purpose field for storing the name + of the VPC. VPC is vpcID for AWS, user networkName for GCP, + and vnetName for Azure. + type: string + required: + - id + - providerName + - region + type: object + type: array observedGeneration: description: ObservedGeneration indicates the generation of the resource specification that the Atlas Operator is aware of. The Atlas Operator diff --git a/bundle/manifests/dbaas.redhat.com_mongodbatlasconnections.yaml b/bundle/manifests/dbaas.redhat.com_mongodbatlasconnections.yaml new file mode 100644 index 0000000000..63d5c1d452 --- /dev/null +++ b/bundle/manifests/dbaas.redhat.com_mongodbatlasconnections.yaml @@ -0,0 +1,155 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator + app.kubernetes.io/name: mongodb-atlas-kubernetes-operator + name: mongodbatlasconnections.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasConnection + listKind: MongoDBAtlasConnectionList + plural: mongodbatlasconnections + singular: mongodbatlasconnection + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSConnectionSpec defines the desired state of DBaaSConnection + properties: + instanceID: + description: The ID of the instance to connect to, as seen in the + Status of the referenced DBaaSInventory + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + required: + - instanceID + - inventoryRef + type: object + status: + description: DBaaSConnectionStatus defines the observed state of DBaaSConnection + properties: + binding: + description: 'Binding exposes a secret containing the binding information + for the instance. It implements the service binding Provisioned + Service duck type. See: https://github.com/servicebinding/spec#provisioned-service' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/dbaas.redhat.com_mongodbatlasinstances.yaml b/bundle/manifests/dbaas.redhat.com_mongodbatlasinstances.yaml new file mode 100644 index 0000000000..57e2f4506d --- /dev/null +++ b/bundle/manifests/dbaas.redhat.com_mongodbatlasinstances.yaml @@ -0,0 +1,188 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator + app.kubernetes.io/name: mongodb-atlas-kubernetes-operator + name: mongodbatlasinstances.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInstance + listKind: MongoDBAtlasInstanceList + plural: mongodbatlasinstances + singular: mongodbatlasinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInstanceSpec defines the desired state of DBaaSInstance + properties: + cloudProvider: + description: Identifies the desired cloud infrastructure provider + type: string + cloudRegion: + description: Identifies the requested deployment region within the + cloud provider (e.g. us-east-1) + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + name: + description: The name of this instance in the database service + type: string + otherInstanceParams: + additionalProperties: + type: string + description: Any other provider-specific parameters related to the + instance provisioning + type: object + required: + - inventoryRef + - name + type: object + status: + description: DBaaSInstanceStatus defines the observed state of DBaaSInstance + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instanceID: + description: The ID of the instance, + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related to this + instance + type: object + phase: + default: Unknown + description: Represents the cluster provisioning phase Unknown - unknown + cluster provisioning status Pending - provisioning not yet started + Creating - provisioning in progress Updating - cluster updating + in progress Deleting - cluster deletion in progress Deleted - cluster + has been deleted Ready - cluster provisioning complete Error - cluster + provisioning with error Failed - cluster provisioning failed + enum: + - Unknown + - Pending + - Creating + - Updating + - Deleting + - Deleted + - Ready + - Error + - Failed + type: string + required: + - instanceID + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/dbaas.redhat.com_mongodbatlasinventories.yaml b/bundle/manifests/dbaas.redhat.com_mongodbatlasinventories.yaml new file mode 100644 index 0000000000..31189200ee --- /dev/null +++ b/bundle/manifests/dbaas.redhat.com_mongodbatlasinventories.yaml @@ -0,0 +1,167 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator + app.kubernetes.io/name: mongodb-atlas-kubernetes-operator + name: mongodbatlasinventories.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInventory + listKind: MongoDBAtlasInventoryList + plural: mongodbatlasinventories + singular: mongodbatlasinventory + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInventorySpec defines the Inventory Spec to be used + by provider operators + properties: + credentialsRef: + description: The Secret containing the provider-specific connection + credentials to use with its API endpoint. The format of the Secret + is specified in the provider’s operator in its DBaaSProvider CR + (CredentialFields key). The Secret must exist within the same namespace + as the Inventory. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - credentialsRef + type: object + status: + description: DBaaSInventoryStatus defines the Inventory status to be used + by provider operators + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instances: + description: A list of instances returned from querying the DB provider + items: + description: Instance defines the information of a database instance + properties: + instanceID: + description: A provider-specific identifier for this instance + in the database service. It may contain one or more pieces + of information used by the provider operator to identify the + instance on the database service. + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related + to this instance + type: object + name: + description: The name of this instance in the database service + type: string + required: + - instanceID + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml b/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml index 4297d95692..6dd65024f0 100644 --- a/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml +++ b/bundle/manifests/mongodb-atlas-kubernetes.clusterserviceversion.yaml @@ -104,45 +104,113 @@ metadata: } ] } + }, + { + "apiVersion": "dbaas.redhat.com/v1alpha1", + "kind": "MongoDBAtlasConnection", + "metadata": { + "name": "test-connection", + "namespace": "my-namespace" + }, + "spec": { + "instanceID": "606b2ffbc9a90e310e642482", + "inventoryRef": { + "name": "test-inventory", + "namespace": "mongodb-atlas-system" + } + } + }, + { + "apiVersion": "dbaas.redhat.com/v1alpha1", + "kind": "MongoDBAtlasInstance", + "metadata": { + "name": "test-instance" + }, + "spec": { + "cloudProvider": "aws", + "cloudRegion": "US_EAST_1", + "inventoryRef": { + "name": "test-inventory", + "namespace": "mongodb-atlas-system" + }, + "name": "my-cluster-free", + "otherInstanceParams": { + "instanceSizeName": "M0", + "projectName": "my-atlas-project-free" + } + } + }, + { + "apiVersion": "dbaas.redhat.com/v1alpha1", + "kind": "MongoDBAtlasInventory", + "metadata": { + "name": "test-inventory" + }, + "spec": { + "credentialsRef": { + "name": "my-atlas-key", + "namespace": "mongodb-atlas-system" + } + } } ] capabilities: Basic Install categories: Database - description: The MongoDB Atlas Kubernetes Operator enables easy management of Clusters in MongoDB Atlas - operators.operatorframework.io/builder: operator-sdk-v1.15.0+git - operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 - containerImage: mongodb/mongodb-atlas-kubernetes-operator:1.2.0 - name: mongodb-atlas-kubernetes.v1.2.0 + description: The MongoDB Atlas Kubernetes Operator enables easy management of + Clusters in MongoDB Atlas + olm.skipRange: '>=0.2.0 <0.3.0' + operators.operatorframework.io/builder: operator-sdk-v1.19.0+git + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + name: mongodb-atlas-kubernetes.v0.3.0 namespace: placeholder spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: AtlasBackupPolicy is the Schema for the atlasbackuppolicies API - displayName: Atlas Backup Policy - kind: AtlasBackupPolicy - name: atlasbackuppolicies.atlas.mongodb.com - version: v1 - - description: AtlasBackupSchedule is the Schema for the atlasbackupschedules API - displayName: Atlas Backup Schedule - kind: AtlasBackupSchedule - name: atlasbackupschedules.atlas.mongodb.com - version: v1 - - description: AtlasDatabaseUser is the Schema for the Atlas Database User API - displayName: Atlas Database User - kind: AtlasDatabaseUser - name: atlasdatabaseusers.atlas.mongodb.com - version: v1 - - description: AtlasDeployment is the Schema for the atlasdeployments API - displayName: Atlas Deployment - kind: AtlasDeployment - name: atlasdeployments.atlas.mongodb.com - version: v1 - - description: AtlasProject is the Schema for the atlasprojects API - displayName: Atlas Project - kind: AtlasProject - name: atlasprojects.atlas.mongodb.com - version: v1 + - description: AtlasBackupPolicy is the Schema for the atlasbackuppolicies API + displayName: Atlas Backup Policy + kind: AtlasBackupPolicy + name: atlasbackuppolicies.atlas.mongodb.com + version: v1 + - description: AtlasBackupSchedule is the Schema for the atlasbackupschedules + API + displayName: Atlas Backup Schedule + kind: AtlasBackupSchedule + name: atlasbackupschedules.atlas.mongodb.com + version: v1 + - description: AtlasDatabaseUser is the Schema for the Atlas Database User API + displayName: Atlas Database User + kind: AtlasDatabaseUser + name: atlasdatabaseusers.atlas.mongodb.com + version: v1 + - description: AtlasDeployment is the Schema for the atlasclusters API + displayName: Atlas Deployment + kind: AtlasDeployment + name: atlasdeployments.atlas.mongodb.com + version: v1 + - description: AtlasProject is the Schema for the atlasprojects API + displayName: Atlas Project + kind: AtlasProject + name: atlasprojects.atlas.mongodb.com + version: v1 + - description: MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections + API + displayName: Mongo DBAtlas Connection + kind: MongoDBAtlasConnection + name: mongodbatlasconnections.dbaas.redhat.com + version: v1alpha1 + - description: MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance + API + displayName: Mongo DBAtlas Instance + kind: MongoDBAtlasInstance + name: mongodbatlasinstances.dbaas.redhat.com + version: v1alpha1 + - description: MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory + API + displayName: Mongo DBAtlas Inventory + kind: MongoDBAtlasInventory + name: mongodbatlasinventories.dbaas.redhat.com + version: v1alpha1 description: | The MongoDB Atlas Operator provides a native integration between the Kubernetes orchestration platform and MongoDB Atlas — the only multi-cloud document database service that gives you the versatility you need to build sophisticated and resilient applications that can adapt to changing customer demands and market trends. @@ -254,246 +322,335 @@ spec: ``` displayName: MongoDB Atlas Operator icon: - - base64data: iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJEXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarVhtdiMpDPzPKfYIDUIIHYfP9/YGe/wtQXcnsZ1JMjP2xLQBg1CVSmLc+O/f6f7BiwIFF1ly0pQOvKJGDQUP+divsj79EdfnesVzCN8/9Lt7IKCL0NL+mtM5/+r39wK7KXjidwvldg7UjwN67hDyw0LnRmQWBTz0cyE9F6KwB/y5QNnHOpJmeX+EOnbbr5Pk/efsI7VjHcSfo4/fo8B7nbEPhTDI04HPQHEbQPbnHRUbwCe+YKKnjOe4ejxdlsAhr/x0vLPKPaJyP/lP+h9AobT7HTo+OjPd7ct+z6+d75aL3+1M7d75Qz/3oz4e5/qbs2c359inKzHBpek81HWU9YSJWCTS+lnCW/DHeJb1VryzA3sbIO9Hw44Vz+oDvD999N0XP/1YbfMNJsYwgqANoQEb68skQUOjwxk29vYzCCl1oBaoAV5Cb7ht8WtfXds1n7Fx95gZPBbzK9bs42+8P11oTqO890e+fQW7ggUFzDDk7BOzAIifF494Ofh6P74MVwKCvNycccBy1L1EZX9yy3hEC2jCREa7Y81LPxeAi7A3wxhPQOBIntgnf0gI4j38mIFPwUIZQRMqIPDMocPKEIkSwMnB9sZvxK+5gcPuhmYBCKZEAmiUCrCKEDbwR2IGhwoTR2ZOLJxZuSRKMXFKSZKJXxGSKCxJRLKolEw5Zs4pS84uay4alCCOrElFs6qWgk0LVi74dcGEUmqoVGPlmqrUXLWWBvq02LilJi27pq300KlDJ3rq0nPXXoYfoNKIg0caMvLQUSaoNmnGyTNNmXnqLDdq3m1Yn97fR81fqIWFlE2UGzX8VORawpucsGEGxEL0QFwMARA6GGZH9jEGZ9AZZocGRAUHWMkGTveGGBCMwwee/sbuDbkPuLkY/wi3cCHnDLq/gZwz6D5B7hm3F6h1yzbtILcQsjA0px6E8MOEkUvIxZLat1t3d9QCRxsxap9zbTJnSpC9Ujts4Njb6FI9zspJeXbVkeaYtbVJSEezUW6JaKAvwg/D5hQZLDanrtM00jbEY0rHKkDDT6qjjyI1Tvi0x0mumC00PWvDJgQFlzlr6JBLDpCAfhT8JmmB17ocZZ0GOWg/HHfrHjt+t10LAbGArAzLYWMFIjiYSgUyBMqQThxLoUockGq0iRauh56ughvMVW77wZ9+oOWHXtjDEyFKmyAyYgHI19rzRglrZxYvpcA/8Ec1h7rT63Q63Tw690qqSBQJdCs5llETtVGW9VzNejNAzPo0VWt1MD+hwMgT1lTWuj1MBWGlfqQ8kPXMvgMxs56QdF+17rOBX7WS9IlLzsj0nkswang2SsLdcyIt4xRwm+8UBaGTU0gRkaOh10kbtJLBoye6g78sscDpBA9P6YMn4ngidXfgQR1AIWLLjFyG1Mbw/UzR2d7Z2yfcx6EhKA+P6DfFAW1nywjatUeUGk5/Hc+t+2zgkxYhUnAuglk6BGE0m4lCmm4eaSwCwWjITao1orWjGS3EjpZENeNoxg6Qc0pZEYQv5m4m+E+rg/b47bE2dXwVCQDlNY2me6QRBA1iGCEhRbBjNe8F0L/N03a/bc8FWAUaKJ7FAsVBF7mPWO/Ahnz+XNZCdu86wOgwYwXw4fSOAb+8M1bowkooSoXgmAKCKaaBSwER/RBBCHJR5F0klsyWSyrl2vVkchv+ay0Z5IgTNARSNpvOJbKgdkog+dGr8b23CUVLwm3MXGAv9zf5i0grEqY2dchhniumDwkX78a3afXWuruDC3R9mMCg2ZH4pFQxsNVXIAEKVghKRpe2vqIfodLqTwXAD0EOsNTbjSm4FrCboDvIQtJa77P5ihzfpOrk0jpKqQEZ7DHj30T4X6IfnjjiviTJynfQ74d8NyRZ9rkzoXsbghrGJoIikuGb1hDza7FCQ/LrfeLpbnpOR3Asbg+2S4ERh9mALLv3h+dZXowU1hkdQYwG7ohDpp6qnEf9eXpzI9cWdmgiBua6CmmpVo28HNFiAtLnGDi/IqehYLLd3Urk7acMROiNULaywxE4lTNlYaszIj8MXSMIAxMLMiO81TxpLxc+CIX7plJ8UvScIGDEPQ49k2B8RYKHQut9i9BqjOQWhtomW3G6pguDF2NuDWpCnjZpyP5zL/y6dd8IhbzrPyQdZJhmjcKstRWoSBtK9xFbVKVqmeuN+i+Z/1TdVUuQfAgywAEVaqBb5jGvGCf+AbMfNsTNwZtkGeOslliVhF3371oCOWdAc1jWzoXOnfdCFO6VqDKjipiVCMkYgm2VSwIM1S8Fr33UuDLJhwg2GbEQRgIFRCgbAvlCuOD03tu7Qu8SSNxJSi3FYFjpE76mhtw+vUM+N0WU2lNeBwpqB4ofqpRdBsYiKONYcc3BfWosqbYCLxy8q5HfqNnu2s3qCbWCytHwsH1WvnPmihPU+zgkNxTMioQiqPKROhd1/PDXWS0Fn7nOvWNDLB3FmJYHN24vKtdqBTMuc/gFLogWAJRONyL636yEhYjY7Uv7T7q5vYnIXaXI4a12X+6Ezxni0lHxJpgdU+jNVbkDq+bfqkNeRT8KUJzPWBRn64tFuCcNAotWugWLirEIpXvd1MX+DaXc8K6Q/U9WkwT7ruqDnuh2+ukAQWQJ6SNBGIVWhI7g1qpdEMsDPMINBJBdGLWMKxhmwIhVoOPeYSGyrx28rx0dlxoL9WTGIj1ZjYIyEXV5UsKN/SqRUBi27+vRd9sa5fQjoqPf0ejoDEdZ4UjI0kdWVC3mRZArW4GP0hO6hmi+a2a6auawa2bU2YKyMMAD+2qGKrJ4lNuofE7Zhg1LnMnSI1IGDg0esfENVp1sQ7J0F91M8I1uCJakKNxHE/C0FNw+Ajg3QhWWmrsdcIR5ak2cp9aIA03kpImJTclWlaYGPtVWWk0HfmBnOq84dF1xglVxGWdK2GuVx4o8mvyRO7pD+0Up9evW/TleGy73BV77WqdpX0Is8iEsdgnx+yZeJ0hmIupmwlUcl5BT7SKus9BBm/ft6+xqXfwzibyq3OxgyhFHqt/IHuuMUMrBHLhVjyI/7AoDgDkkjh8GiTETsfU/ZHuEtrDMfYEAAAGFaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDQBzFX1O1UioiVhBxyFB1sSAq4qhVKEKFUCu06mBy6YfQpCFJcXEUXAsOfixWHVycdXVwFQTBDxA3NydFFynxf2mhRYwHx/14d+9x9w4QqkWmWW1jgKbbZjIeE9OZFTHwiiD60IMRdMjMMmYlKQHP8XUPH1/vojzL+9yfo0vNWgzwicQzzDBt4nXiqU3b4LxPHGYFWSU+Jx416YLEj1xX6vzGOe+ywDPDZio5RxwmFvMtrLQwK5ga8SRxRNV0yhfSdVY5b3HWimXWuCd/YSirLy9xneYg4ljAIiSIUFDGBoqwEaVVJ8VCkvZjHv4B1y+RSyHXBhg55lGCBtn1g//B726t3MR4PSkUA9pfHOdjCAjsArWK43wfO07tBPA/A1d601+qAtOfpFeaWuQI6N4GLq6bmrIHXO4A/U+GbMqu5Kcp5HLA+xl9UwbovQWCq/XeGvs4fQBS1FXiBjg4BIbzlL3m8e7O1t7+PdPo7wdVb3KbaWTEXAAADRxpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6ZDk1YjhmMjctMWM0NS00YjU1LWEwZTMtNmNmMjM0Yzk1ZWVkIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVhMGY5MTI5LWJlMDItNDVjOS1iNGU4LTU3N2MxZTBiZGJhNyIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjcyNmY4ZGFlLTM4ZTYtNGQ4Ni1hNTI4LWM0NTc4ZGE4ODA0NSIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09Ik1hYyBPUyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2MzQ4MzgwMTYyMTQ2MTMiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4yNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1YWNhZmVhMC0xZmY5LTRiMmUtYmY0NC02NTM3MzYwMGQzNjEiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTWFjIE9TKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0xMC0yMVQxODo0MDoxNiswMTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz6528V0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH5QoVESgQ+iToFAAAA8xJREFUeNrlW01PU0EUPTPV+oqb4h+wENYKXbmzsjLEKPAHwB1xQ6N7adiboBtrSAT5AaQmBpuYSN25MS17k5Zf0MemFGznungttCkf782bmTels2w6mbnnnnPv3DvzYrBhrMytIT01gz9/f5temkVv/NMUwKsg1MFEGvlizeTy3ALj9zuuGAf4T2QzydEBACwHINXzwwSOE29N7iAWqe7BsoOYsEdITx2ZigcsIupnzqh/8SC0/6Wx+aNy8yTg6X7rWsfEbu96/71JAGQzyY7n/Rg2AcZ3dQdFswA0Exs+je8KYUZ3UDQXA1bmlgFsScwkMFrEx++F4QXgPN/LaZpQR6IxiY2SO6QSGMj3Qd00jpPE5+FkgDz1B3kAMYt8sTQ8AGQzSTTHyqG83z+qcBpplVLQK4Hm2KpC473U2BzLDgcDwgY+QwFRIwP4knLjuwFRIQv0MGB5PgnntKwFAMUs0MMA53Rem/Ge25I4ufvCXgkQVrVXsSSW7JTAq7lpCJQNnK4IEJNhW2jqGdDGsrH6QrB5GyXwWMKXLoi5gdnL8dwuCXjRvy4xs0vjVGDonMa9MNlALQPiJxlJOcvruOlM2yMBzuQ3Q3Al44BFADA8lJ9LrtSKnD2wBwAhe/hhIVIZpWxiQJgG5qHkohYBoPP4q6tks2Qfh1GBzu3xhWQckM0eWgAIfprrBE+SN4LZBACTNIQzF4KO5EAnmxgQwhtckj2WMeBA8gARpqQ9sAcAAfnrbLk4QGBUsQcAHmIzXFLLrbZFDMgXS1KZoN2W1DHVwj6iUH8O4FQKPCcWc3t6AkGCTin0dpUDQPhq6OREgNixD4BmvBBYBlKNTaqpuChVD8B2wQWj98EnOrVA3hf4YHExJLb1l3FUsBeAfLEG0Bef//Y8H28FqSW2VT2p1VgNUi5QLKC4z1qCqoBYt78fkC/WfMWCwMUM21H5oFrzA4n4xrUt724xQy0fxRRVkd/LKQ0lWgHYLrgAvfQXN1vXSYAAmlUeS7VH63yxBMIVUvDdB1jX8S2BmZbYp70scNkRmXtXaQkOXN4b3FJNfbMAAEDzzoLcFRhV4TReaztOGAPAiwdPLgDh8OqUR7M6XoiaB6CbGtts4cLzwbtv1N8Z7hiv+Rsi823xzb0KRB8T7gMA3jxj59dcZoz3snBUY+VpCmD7nautXGcva2Aog8Siqa/Hov1sbuAxJZXgHC/o1Hz0Ehgsmn71/FIxaXz0AAwS8sj0ihYAcBb5CVJ9weFnwLnR1K6PHgC9FyJsFCVwq+9afAQlIITbnxXMjv+6222dh4/VtAAAAABJRU5ErkJggg== - mediatype: image/png + - base64data: iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJEXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarVhtdiMpDPzPKfYIDUIIHYfP9/YGe/wtQXcnsZ1JMjP2xLQBg1CVSmLc+O/f6f7BiwIFF1ly0pQOvKJGDQUP+divsj79EdfnesVzCN8/9Lt7IKCL0NL+mtM5/+r39wK7KXjidwvldg7UjwN67hDyw0LnRmQWBTz0cyE9F6KwB/y5QNnHOpJmeX+EOnbbr5Pk/efsI7VjHcSfo4/fo8B7nbEPhTDI04HPQHEbQPbnHRUbwCe+YKKnjOe4ejxdlsAhr/x0vLPKPaJyP/lP+h9AobT7HTo+OjPd7ct+z6+d75aL3+1M7d75Qz/3oz4e5/qbs2c359inKzHBpek81HWU9YSJWCTS+lnCW/DHeJb1VryzA3sbIO9Hw44Vz+oDvD999N0XP/1YbfMNJsYwgqANoQEb68skQUOjwxk29vYzCCl1oBaoAV5Cb7ht8WtfXds1n7Fx95gZPBbzK9bs42+8P11oTqO890e+fQW7ggUFzDDk7BOzAIifF494Ofh6P74MVwKCvNycccBy1L1EZX9yy3hEC2jCREa7Y81LPxeAi7A3wxhPQOBIntgnf0gI4j38mIFPwUIZQRMqIPDMocPKEIkSwMnB9sZvxK+5gcPuhmYBCKZEAmiUCrCKEDbwR2IGhwoTR2ZOLJxZuSRKMXFKSZKJXxGSKCxJRLKolEw5Zs4pS84uay4alCCOrElFs6qWgk0LVi74dcGEUmqoVGPlmqrUXLWWBvq02LilJi27pq300KlDJ3rq0nPXXoYfoNKIg0caMvLQUSaoNmnGyTNNmXnqLDdq3m1Yn97fR81fqIWFlE2UGzX8VORawpucsGEGxEL0QFwMARA6GGZH9jEGZ9AZZocGRAUHWMkGTveGGBCMwwee/sbuDbkPuLkY/wi3cCHnDLq/gZwz6D5B7hm3F6h1yzbtILcQsjA0px6E8MOEkUvIxZLat1t3d9QCRxsxap9zbTJnSpC9Ujts4Njb6FI9zspJeXbVkeaYtbVJSEezUW6JaKAvwg/D5hQZLDanrtM00jbEY0rHKkDDT6qjjyI1Tvi0x0mumC00PWvDJgQFlzlr6JBLDpCAfhT8JmmB17ocZZ0GOWg/HHfrHjt+t10LAbGArAzLYWMFIjiYSgUyBMqQThxLoUockGq0iRauh56ughvMVW77wZ9+oOWHXtjDEyFKmyAyYgHI19rzRglrZxYvpcA/8Ec1h7rT63Q63Tw690qqSBQJdCs5llETtVGW9VzNejNAzPo0VWt1MD+hwMgT1lTWuj1MBWGlfqQ8kPXMvgMxs56QdF+17rOBX7WS9IlLzsj0nkswang2SsLdcyIt4xRwm+8UBaGTU0gRkaOh10kbtJLBoye6g78sscDpBA9P6YMn4ngidXfgQR1AIWLLjFyG1Mbw/UzR2d7Z2yfcx6EhKA+P6DfFAW1nywjatUeUGk5/Hc+t+2zgkxYhUnAuglk6BGE0m4lCmm4eaSwCwWjITao1orWjGS3EjpZENeNoxg6Qc0pZEYQv5m4m+E+rg/b47bE2dXwVCQDlNY2me6QRBA1iGCEhRbBjNe8F0L/N03a/bc8FWAUaKJ7FAsVBF7mPWO/Ahnz+XNZCdu86wOgwYwXw4fSOAb+8M1bowkooSoXgmAKCKaaBSwER/RBBCHJR5F0klsyWSyrl2vVkchv+ay0Z5IgTNARSNpvOJbKgdkog+dGr8b23CUVLwm3MXGAv9zf5i0grEqY2dchhniumDwkX78a3afXWuruDC3R9mMCg2ZH4pFQxsNVXIAEKVghKRpe2vqIfodLqTwXAD0EOsNTbjSm4FrCboDvIQtJa77P5ihzfpOrk0jpKqQEZ7DHj30T4X6IfnjjiviTJynfQ74d8NyRZ9rkzoXsbghrGJoIikuGb1hDza7FCQ/LrfeLpbnpOR3Asbg+2S4ERh9mALLv3h+dZXowU1hkdQYwG7ohDpp6qnEf9eXpzI9cWdmgiBua6CmmpVo28HNFiAtLnGDi/IqehYLLd3Urk7acMROiNULaywxE4lTNlYaszIj8MXSMIAxMLMiO81TxpLxc+CIX7plJ8UvScIGDEPQ49k2B8RYKHQut9i9BqjOQWhtomW3G6pguDF2NuDWpCnjZpyP5zL/y6dd8IhbzrPyQdZJhmjcKstRWoSBtK9xFbVKVqmeuN+i+Z/1TdVUuQfAgywAEVaqBb5jGvGCf+AbMfNsTNwZtkGeOslliVhF3371oCOWdAc1jWzoXOnfdCFO6VqDKjipiVCMkYgm2VSwIM1S8Fr33UuDLJhwg2GbEQRgIFRCgbAvlCuOD03tu7Qu8SSNxJSi3FYFjpE76mhtw+vUM+N0WU2lNeBwpqB4ofqpRdBsYiKONYcc3BfWosqbYCLxy8q5HfqNnu2s3qCbWCytHwsH1WvnPmihPU+zgkNxTMioQiqPKROhd1/PDXWS0Fn7nOvWNDLB3FmJYHN24vKtdqBTMuc/gFLogWAJRONyL636yEhYjY7Uv7T7q5vYnIXaXI4a12X+6Ezxni0lHxJpgdU+jNVbkDq+bfqkNeRT8KUJzPWBRn64tFuCcNAotWugWLirEIpXvd1MX+DaXc8K6Q/U9WkwT7ruqDnuh2+ukAQWQJ6SNBGIVWhI7g1qpdEMsDPMINBJBdGLWMKxhmwIhVoOPeYSGyrx28rx0dlxoL9WTGIj1ZjYIyEXV5UsKN/SqRUBi27+vRd9sa5fQjoqPf0ejoDEdZ4UjI0kdWVC3mRZArW4GP0hO6hmi+a2a6auawa2bU2YKyMMAD+2qGKrJ4lNuofE7Zhg1LnMnSI1IGDg0esfENVp1sQ7J0F91M8I1uCJakKNxHE/C0FNw+Ajg3QhWWmrsdcIR5ak2cp9aIA03kpImJTclWlaYGPtVWWk0HfmBnOq84dF1xglVxGWdK2GuVx4o8mvyRO7pD+0Up9evW/TleGy73BV77WqdpX0Is8iEsdgnx+yZeJ0hmIupmwlUcl5BT7SKus9BBm/ft6+xqXfwzibyq3OxgyhFHqt/IHuuMUMrBHLhVjyI/7AoDgDkkjh8GiTETsfU/ZHuEtrDMfYEAAAGFaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDQBzFX1O1UioiVhBxyFB1sSAq4qhVKEKFUCu06mBy6YfQpCFJcXEUXAsOfixWHVycdXVwFQTBDxA3NydFFynxf2mhRYwHx/14d+9x9w4QqkWmWW1jgKbbZjIeE9OZFTHwiiD60IMRdMjMMmYlKQHP8XUPH1/vojzL+9yfo0vNWgzwicQzzDBt4nXiqU3b4LxPHGYFWSU+Jx416YLEj1xX6vzGOe+ywDPDZio5RxwmFvMtrLQwK5ga8SRxRNV0yhfSdVY5b3HWimXWuCd/YSirLy9xneYg4ljAIiSIUFDGBoqwEaVVJ8VCkvZjHv4B1y+RSyHXBhg55lGCBtn1g//B726t3MR4PSkUA9pfHOdjCAjsArWK43wfO07tBPA/A1d601+qAtOfpFeaWuQI6N4GLq6bmrIHXO4A/U+GbMqu5Kcp5HLA+xl9UwbovQWCq/XeGvs4fQBS1FXiBjg4BIbzlL3m8e7O1t7+PdPo7wdVb3KbaWTEXAAADRxpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6ZDk1YjhmMjctMWM0NS00YjU1LWEwZTMtNmNmMjM0Yzk1ZWVkIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVhMGY5MTI5LWJlMDItNDVjOS1iNGU4LTU3N2MxZTBiZGJhNyIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjcyNmY4ZGFlLTM4ZTYtNGQ4Ni1hNTI4LWM0NTc4ZGE4ODA0NSIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09Ik1hYyBPUyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2MzQ4MzgwMTYyMTQ2MTMiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4yNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1YWNhZmVhMC0xZmY5LTRiMmUtYmY0NC02NTM3MzYwMGQzNjEiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTWFjIE9TKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0xMC0yMVQxODo0MDoxNiswMTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz6528V0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH5QoVESgQ+iToFAAAA8xJREFUeNrlW01PU0EUPTPV+oqb4h+wENYKXbmzsjLEKPAHwB1xQ6N7adiboBtrSAT5AaQmBpuYSN25MS17k5Zf0MemFGznungttCkf782bmTels2w6mbnnnnPv3DvzYrBhrMytIT01gz9/f5temkVv/NMUwKsg1MFEGvlizeTy3ALj9zuuGAf4T2QzydEBACwHINXzwwSOE29N7iAWqe7BsoOYsEdITx2ZigcsIupnzqh/8SC0/6Wx+aNy8yTg6X7rWsfEbu96/71JAGQzyY7n/Rg2AcZ3dQdFswA0Exs+je8KYUZ3UDQXA1bmlgFsScwkMFrEx++F4QXgPN/LaZpQR6IxiY2SO6QSGMj3Qd00jpPE5+FkgDz1B3kAMYt8sTQ8AGQzSTTHyqG83z+qcBpplVLQK4Hm2KpC473U2BzLDgcDwgY+QwFRIwP4knLjuwFRIQv0MGB5PgnntKwFAMUs0MMA53Rem/Ge25I4ufvCXgkQVrVXsSSW7JTAq7lpCJQNnK4IEJNhW2jqGdDGsrH6QrB5GyXwWMKXLoi5gdnL8dwuCXjRvy4xs0vjVGDonMa9MNlALQPiJxlJOcvruOlM2yMBzuQ3Q3Al44BFADA8lJ9LrtSKnD2wBwAhe/hhIVIZpWxiQJgG5qHkohYBoPP4q6tks2Qfh1GBzu3xhWQckM0eWgAIfprrBE+SN4LZBACTNIQzF4KO5EAnmxgQwhtckj2WMeBA8gARpqQ9sAcAAfnrbLk4QGBUsQcAHmIzXFLLrbZFDMgXS1KZoN2W1DHVwj6iUH8O4FQKPCcWc3t6AkGCTin0dpUDQPhq6OREgNixD4BmvBBYBlKNTaqpuChVD8B2wQWj98EnOrVA3hf4YHExJLb1l3FUsBeAfLEG0Bef//Y8H28FqSW2VT2p1VgNUi5QLKC4z1qCqoBYt78fkC/WfMWCwMUM21H5oFrzA4n4xrUt724xQy0fxRRVkd/LKQ0lWgHYLrgAvfQXN1vXSYAAmlUeS7VH63yxBMIVUvDdB1jX8S2BmZbYp70scNkRmXtXaQkOXN4b3FJNfbMAAEDzzoLcFRhV4TReaztOGAPAiwdPLgDh8OqUR7M6XoiaB6CbGtts4cLzwbtv1N8Z7hiv+Rsi823xzb0KRB8T7gMA3jxj59dcZoz3snBUY+VpCmD7nautXGcva2Aog8Siqa/Hov1sbuAxJZXgHC/o1Hz0Ehgsmn71/FIxaXz0AAwS8sj0ihYAcBb5CVJ9weFnwLnR1K6PHgC9FyJsFCVwq+9afAQlIITbnxXMjv+6222dh4/VtAAAAABJRU5ErkJggg== + mediatype: image/png install: spec: clusterPermissions: - - rules: - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasbackuppolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasbackuppolicies/status - verbs: - - get - - patch - - update - - apiGroups: - - atlas.mongodb.com - resources: - - atlasbackupschedules - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasbackupschedules/status - verbs: - - get - - patch - - update - - apiGroups: - - atlas.mongodb.com - resources: - - atlasdatabaseusers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasdatabaseusers/status - verbs: - - get - - patch - - update - - apiGroups: - - atlas.mongodb.com - resources: - - atlasdeployments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasdeployments/status - verbs: - - get - - patch - - update - - apiGroups: - - atlas.mongodb.com - resources: - - atlasprojects - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - atlas.mongodb.com - resources: - - atlasprojects/status - verbs: - - get - - patch - - update - serviceAccountName: mongodb-atlas-operator + - rules: + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasbackuppolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasbackuppolicies/status + verbs: + - get + - patch + - update + - apiGroups: + - atlas.mongodb.com + resources: + - atlasbackupschedules + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasbackupschedules/status + verbs: + - get + - patch + - update + - apiGroups: + - atlas.mongodb.com + resources: + - atlasdatabaseusers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasdatabaseusers/status + verbs: + - get + - patch + - update + - apiGroups: + - atlas.mongodb.com + resources: + - atlasdeployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasdeployments/status + verbs: + - get + - patch + - update + - apiGroups: + - atlas.mongodb.com + resources: + - atlasprojects + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - atlas.mongodb.com + resources: + - atlasprojects/status + verbs: + - get + - patch + - update + - apiGroups: + - dbaas.redhat.com + resources: + - dbaasproviders + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - dbaas.redhat.com + resources: + - dbaasproviders/status + verbs: + - get + - patch + - update + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections/status + verbs: + - get + - patch + - update + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances/status + verbs: + - get + - patch + - update + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories/status + verbs: + - get + - patch + - update + serviceAccountName: mongodb-atlas-operator deployments: - - name: mongodb-atlas-operator - spec: - replicas: 1 - selector: - matchLabels: + - label: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator + app.kubernetes.io/name: mongodb-atlas-kubernetes-operator + name: mongodb-atlas-operator + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator + app.kubernetes.io/name: mongodb-atlas-kubernetes-operator + strategy: {} + template: + metadata: + labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator app.kubernetes.io/name: mongodb-atlas-kubernetes-operator - strategy: {} - template: - metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: mongodb-atlas-kubernetes-operator - app.kubernetes.io/name: mongodb-atlas-kubernetes-operator - spec: - containers: - - args: - - --atlas-domain=https://cloud.mongodb.com/ - - --leader-elect - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --log-level=info - - --log-encoder=json - command: - - /manager - env: - - name: OPERATOR_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - image: mongodb/mongodb-atlas-kubernetes-operator:1.2.0 - imagePullPolicy: Always - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 256Mi - requests: - cpu: 100m - memory: 50Mi - securityContext: - allowPrivilegeEscalation: false - serviceAccountName: mongodb-atlas-operator - terminationGracePeriodSeconds: 10 + spec: + containers: + - args: + - --atlas-domain=https://cloud.mongodb.com/ + - --leader-elect + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --log-level=info + - --log-encoder=json + command: + - /manager + env: + - name: OPERATOR_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SYNC_PERIOD_MIN + value: "180" + image: quay.io/mongodb/mongodb-atlas-kubernetes-dbaas:0.3.0 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 768Mi + requests: + cpu: 100m + memory: 50Mi + securityContext: + allowPrivilegeEscalation: false + serviceAccountName: mongodb-atlas-operator + terminationGracePeriodSeconds: 10 permissions: - - rules: - - apiGroups: - - "" - - coordination.k8s.io - resources: - - configmaps - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - serviceAccountName: mongodb-atlas-operator + - rules: + - apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: mongodb-atlas-operator strategy: deployment installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces keywords: - - MongoDB - - Atlas - - Database - - Replica Set - - Cluster + - MongoDB + - Atlas + - Database + - Replica Set + - Cluster links: - - name: MongoDB Atlas Kubernetes - url: https://github.com/mongodb/mongodb-atlas-kubernetes + - name: MongoDB Atlas Kubernetes + url: https://github.com/mongodb/mongodb-atlas-kubernetes maintainers: - - email: support@mongodb.com - name: MongoDB, Inc + - email: support@mongodb.com + name: MongoDB, Inc maturity: beta provider: name: MongoDB, Inc - version: 1.2.0 - replaces: mongodb-atlas-kubernetes.v1.1.0 + version: 0.3.0 diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index dae31a6cbe..bac154c604 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -1,4 +1,9 @@ annotations: + # RH OLM annotations + com.redhat.openshift.versions: v4.5,v4.6 + com.redhat.delivery.backport: true + com.redhat.delivery.operator.bundle: true + # Core bundle annotations. operators.operatorframework.io.bundle.mediatype.v1: registry+v1 operators.operatorframework.io.bundle.manifests.v1: manifests/ @@ -8,7 +13,7 @@ annotations: operators.operatorframework.io.bundle.channel.default.v1: stable operators.operatorframework.io.metrics.builder: operator-sdk-v1.15.0+git operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v2 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 # Annotations for testing. operators.operatorframework.io.test.mediatype.v1: scorecard+v1 diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 34e995ed5b..7ca2498ea1 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -22,6 +22,7 @@ import ( "fmt" "log" "os" + "strconv" "strings" "time" @@ -34,6 +35,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes" clientgoscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ctrl "sigs.k8s.io/controller-runtime" @@ -42,12 +44,19 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/predicate" + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + + dbaas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasconnection" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasdatabaseuser" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasdeployment" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasinstance" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasinventory" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasproject" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/connectionsecret" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/dbaasprovider" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube" // +kubebuilder:scaffold:imports @@ -65,6 +74,11 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(mdbv1.AddToScheme(scheme)) + + utilruntime.Must(dbaas.AddToScheme(scheme)) + + utilruntime.Must(dbaasv1alpha1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme atlas.ProductVersion = version @@ -89,7 +103,6 @@ func main() { logger.Sugar().Infof("MongoDB Atlas Operator version %s", version) - syncPeriod := time.Hour * 3 mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: config.MetricsAddr, @@ -98,7 +111,7 @@ func main() { HealthProbeBindAddress: config.ProbeAddr, LeaderElection: config.EnableLeaderElection, LeaderElectionID: "06d035fb.mongodb.com", - SyncPeriod: &syncPeriod, + SyncPeriod: &config.SyncPeriod, NewCache: cache.BuilderWithOptions(cache.Options{ SelectorsByObject: cache.SelectorsByObject{ &corev1.Secret{}: { @@ -122,6 +135,64 @@ func main() { watch.SelectNamespacesPredicate(config.WatchedNamespaces), // select only desired namespaces } + cfg := mgr.GetConfig() + clientset, err := kubernetes.NewForConfig(cfg) + if err != nil { + setupLog.Error(err, "unable to create clientset") + os.Exit(1) + } + + if err = (&dbaasprovider.DBaaSProviderReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Log: logger.Named("controllers").Named("DBaaSProvider").Sugar(), + Clientset: clientset, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "DBaaSProvider") + os.Exit(1) + } + + if err = (&atlasinventory.MongoDBAtlasInventoryReconciler{ + Client: mgr.GetClient(), + Log: logger.Named("controllers").Named("MongoDBAtlasInventory").Sugar(), + Scheme: mgr.GetScheme(), + AtlasDomain: config.AtlasDomain, + ResourceWatcher: watch.NewResourceWatcher(), + GlobalAPISecret: config.GlobalAPISecret, + EventRecorder: mgr.GetEventRecorderFor("MongoDBAtlasInventory"), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "MongoDBAtlasInventory") + os.Exit(1) + } + + if err = (&atlasconnection.MongoDBAtlasConnectionReconciler{ + Client: mgr.GetClient(), + Clientset: clientset, + Log: logger.Named("controllers").Named("MongoDBAtlasConnection").Sugar(), + Scheme: mgr.GetScheme(), + AtlasDomain: config.AtlasDomain, + ResourceWatcher: watch.NewResourceWatcher(), + GlobalAPISecret: config.GlobalAPISecret, + EventRecorder: mgr.GetEventRecorderFor("MongoDBAtlasConnection"), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "MongoDBAtlasConnection") + os.Exit(1) + } + + if err = (&atlasinstance.MongoDBAtlasInstanceReconciler{ + Client: mgr.GetClient(), + Clientset: clientset, + Log: logger.Named("controllers").Named("MongoDBAtlasInstance").Sugar(), + Scheme: mgr.GetScheme(), + AtlasDomain: config.AtlasDomain, + ResourceWatcher: watch.NewResourceWatcher(), + GlobalAPISecret: config.GlobalAPISecret, + EventRecorder: mgr.GetEventRecorderFor("MongoDBAtlasInstance"), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "MongoDBAtlasInstance") + os.Exit(1) + } + if err = (&atlasdeployment.AtlasDeploymentReconciler{ Client: mgr.GetClient(), Log: logger.Named("controllers").Named("AtlasDeployment").Sugar(), @@ -191,6 +262,7 @@ type Config struct { GlobalAPISecret client.ObjectKey LogLevel string LogEncoder string + SyncPeriod time.Duration } // ParseConfiguration fills the 'OperatorConfig' from the flags passed to the program @@ -230,6 +302,12 @@ func parseConfiguration() Config { config.Namespace = watchedNamespace } + syncPeriodMin, _ := strconv.Atoi(os.Getenv("SYNC_PERIOD_MIN")) + if syncPeriodMin <= 0 { + syncPeriodMin = 180 // default to 180 minutes (3 hours) + setupLog.Info("SYNC_PERIOD_MIN is missing. Default " + strconv.Itoa(syncPeriodMin) + " is used") + } + config.SyncPeriod = time.Minute * time.Duration(syncPeriodMin) return config } diff --git a/config/crd/bases/dbaas.redhat.com_mongodbatlasconnections.yaml b/config/crd/bases/dbaas.redhat.com_mongodbatlasconnections.yaml new file mode 100644 index 0000000000..957082437c --- /dev/null +++ b/config/crd/bases/dbaas.redhat.com_mongodbatlasconnections.yaml @@ -0,0 +1,153 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasconnections.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasConnection + listKind: MongoDBAtlasConnectionList + plural: mongodbatlasconnections + singular: mongodbatlasconnection + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSConnectionSpec defines the desired state of DBaaSConnection + properties: + instanceID: + description: The ID of the instance to connect to, as seen in the + Status of the referenced DBaaSInventory + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + required: + - instanceID + - inventoryRef + type: object + status: + description: DBaaSConnectionStatus defines the observed state of DBaaSConnection + properties: + binding: + description: 'Binding exposes a secret containing the binding information + for the instance. It implements the service binding Provisioned + Service duck type. See: https://github.com/servicebinding/spec#provisioned-service' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/bases/dbaas.redhat.com_mongodbatlasinstances.yaml b/config/crd/bases/dbaas.redhat.com_mongodbatlasinstances.yaml new file mode 100644 index 0000000000..322a20d014 --- /dev/null +++ b/config/crd/bases/dbaas.redhat.com_mongodbatlasinstances.yaml @@ -0,0 +1,186 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasinstances.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInstance + listKind: MongoDBAtlasInstanceList + plural: mongodbatlasinstances + singular: mongodbatlasinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInstanceSpec defines the desired state of DBaaSInstance + properties: + cloudProvider: + description: Identifies the desired cloud infrastructure provider + type: string + cloudRegion: + description: Identifies the requested deployment region within the + cloud provider (e.g. us-east-1) + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + name: + description: The name of this instance in the database service + type: string + otherInstanceParams: + additionalProperties: + type: string + description: Any other provider-specific parameters related to the + instance provisioning + type: object + required: + - inventoryRef + - name + type: object + status: + description: DBaaSInstanceStatus defines the observed state of DBaaSInstance + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instanceID: + description: The ID of the instance, + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related to this + instance + type: object + phase: + default: Unknown + description: Represents the cluster provisioning phase Unknown - unknown + cluster provisioning status Pending - provisioning not yet started + Creating - provisioning in progress Updating - cluster updating + in progress Deleting - cluster deletion in progress Deleted - cluster + has been deleted Ready - cluster provisioning complete Error - cluster + provisioning with error Failed - cluster provisioning failed + enum: + - Unknown + - Pending + - Creating + - Updating + - Deleting + - Deleted + - Ready + - Error + - Failed + type: string + required: + - instanceID + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/bases/dbaas.redhat.com_mongodbatlasinventories.yaml b/config/crd/bases/dbaas.redhat.com_mongodbatlasinventories.yaml new file mode 100644 index 0000000000..0539b7a944 --- /dev/null +++ b/config/crd/bases/dbaas.redhat.com_mongodbatlasinventories.yaml @@ -0,0 +1,165 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasinventories.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInventory + listKind: MongoDBAtlasInventoryList + plural: mongodbatlasinventories + singular: mongodbatlasinventory + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInventorySpec defines the Inventory Spec to be used + by provider operators + properties: + credentialsRef: + description: The Secret containing the provider-specific connection + credentials to use with its API endpoint. The format of the Secret + is specified in the provider’s operator in its DBaaSProvider CR + (CredentialFields key). The Secret must exist within the same namespace + as the Inventory. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - credentialsRef + type: object + status: + description: DBaaSInventoryStatus defines the Inventory status to be used + by provider operators + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instances: + description: A list of instances returned from querying the DB provider + items: + description: Instance defines the information of a database instance + properties: + instanceID: + description: A provider-specific identifier for this instance + in the database service. It may contain one or more pieces + of information used by the provider operator to identify the + instance on the database service. + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related + to this instance + type: object + name: + description: The name of this instance in the database service + type: string + required: + - instanceID + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index a90df641f1..e31a4ff423 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -7,6 +7,9 @@ resources: - bases/atlas.mongodb.com_atlasdatabaseusers.yaml - bases/atlas.mongodb.com_atlasbackuppolicies.yaml - bases/atlas.mongodb.com_atlasbackupschedules.yaml + - bases/dbaas.redhat.com_mongodbatlasconnections.yaml + - bases/dbaas.redhat.com_mongodbatlasinventories.yaml + - bases/dbaas.redhat.com_mongodbatlasinstances.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: diff --git a/config/crd/patches/cainjection_in_atlasclusters.yaml b/config/crd/patches/cainjection_in_atlasclusters.yaml deleted file mode 100644 index 91dccd6122..0000000000 --- a/config/crd/patches/cainjection_in_atlasclusters.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# 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: atlasclusters.mongodb.com diff --git a/config/crd/patches/webhook_in_atlasclusters.yaml b/config/crd/patches/webhook_in_atlasclusters.yaml deleted file mode 100644 index a06d33b218..0000000000 --- a/config/crd/patches/webhook_in_atlasclusters.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# 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: atlasclusters.mongodb.com -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/dbaasprovider/dbaas_provider.yaml b/config/dbaasprovider/dbaas_provider.yaml new file mode 100644 index 0000000000..0819f94a02 --- /dev/null +++ b/config/dbaasprovider/dbaas_provider.yaml @@ -0,0 +1,66 @@ +apiVersion: dbaas.redhat.com/v1alpha1 +kind: DBaaSProvider +metadata: + name: mongodb-atlas-registration + labels: + related-to: dbaas-operator + type: dbaas-provider-registration +spec: + provider: + name: Red Hat DBaaS / MongoDB Atlas + displayName: MongoDB Atlas Cloud Database Service + displayDescription: Cloud-hosted MongoDB service on AWS, Azure and Google Cloud + icon: + base64data: iVBORw0KGgoAAAANSUhEUgAAAH8AAAB/CAYAAADGvR0TAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4ggYEhkp9JVi8gAAFENJREFUeNrtnXmcVeV5x7/Pe86dGUZQUdwAo4Kaam1cUAdm3DAYl1ZjmmhMYkUlkMYtMVVrVExqY7q4oabNp6EuMdpEq8ZGpf1oJCbKJgxqlWiIgIrACCgimwJznv5xlvue5d65dxjsvXPP4+d4t3OB+/7e37O/7wsNKhdNv9iZ8uqNQgOLadhfLnLA7CV/OOrT/3JMDn7D/XDh02s3bRr/h4ufz8FvNOnu1s9v2rL5/EZW+06j/eCJT09i1Pijdhb46ZpNGwa4Jw4x7097+9mGtHyN+KMn/fob/yyYK998byWLV727FXQPgfcXXjIjV/v9Uc7/nwkATHhq4t+q6pWKUjAOgroCf73wkhkc+KOOnPn9dwJceIkx5k6DwRjDyg/XsmD52+Eg7LHwkhkrc+b3Izl32nkAnDftgkcV7kRBUVQVxxhAw1ufOfBHHaaR2N+vwf/KE+fS7W0Z8LVp5z2t6BcIQPfhViSu9w4BLlt4yQxG3NmRg1/v8vO/uB/EmY3qOFDUC3iuiiq4xsHXBOAB3cptI+/s+KvFl87ggAaYAP3S5n/pV18WjNnBUZllxBwiAo44CIIYgxHBiMP6jzcxd8kixFIBAp7AV/546YyHcubXoXy03gVPf6noIaGS93xLT6DxAcU1DhIMQngJGFUe3P+OjhMB9r+jI2d+PciZj30JcUWkW6Yb5AQxBgeDiGCMYDCIBMw3ho82b2XOooUx5lviASe9cdmM6Tnz60AeO/NhdKveBHqCRgh6Edsjex+8doz0RIxn9r+j41BfA7TnzK9VGff0WbSu964V4QdGDIJgQpYHjyImYL/giKFblecXvo6RcsOgHrDHG5fNXN3fwHf7yw9pWbe1DZEbQNBoVvvPNHxHFSR8D1Q1dp/lECS14//uf0f7/t3CRuPBom/NzMGvFTnl4TP2VHS2IqAB3AKqgieKo4IHGAkifFVUFNcxKIogKdA1/rgXMGvJpTMPzW1+jcjJD5/u2y7hwZDJSRB9WIvve9FzP9YPX3kUn2vxFqR4fWbk7e33Aoy8vX/Y/7ot6Y576DSePutJTn749O+DjAd82y0SZe5EAk0QvCcUH0FA4K33VvvvV/bXHrbLqXu/suhbM1/LHb7/RznxodMwyJ+ImFccEdd36ASDH8b5Dl8Q3gVhXuj8SfC+4zg8+9rve3D40h4gMAp4sd5tf92q/elnT0PR/0Q914spdgJ1roE61+i1F5mAwMUT6S1h7u8PTl/dgj/2wVNvVThEAzx8e2/bdBJef2jMLd9Atbd//cEjb29/LAf/E5ZjfzGK439xyi6q+o2wQqfqUXT4Am8+8Nw8y7FLagXdtn/K50dMaT8OYMSU9hz8T0KeO6cTD+9nCq2hCbYJrBnPovvs/H4vma9avICHARZ/e2YO/ichHf9x0qkopyVr82GDBpE2KDZtqHWvhpogeL+lUCgJbtaVkN1GTGmfmqv97SyjH/hsyNfvpZMwCdWeUuqhdogS/CXB7oWcO2JK+3Bf/Y/Jwd8eMvtrzzD6gc8eC9rmqaXC1c/RqfoFHE81075HvgCWBthWq+//qS2gj+bM386i8IiStu+R8leNWXjb67dDvMgxrBp8zbgAOGrElDFfWPztWTn4fS2j7h/LkQ+ceKaiu0VAaqjOk2zGsvvF19ZDZPfRLPi1zFVWrgUYeduYHPy+ksPvH0vnub9B4W+8BGsjSGL2PAGVxplP4vt+Sb9igKMsjxDL+yPKqJG3jTl50eWzcvD7Sl489zccdv/Yg1T1mBg3LeRDhnuZXr+t/hNaQqHgOj1CngQ7OU+s4tCjAPvVCfvrQu2r6r1gVd80bs9Dey+AemrX7YqRgGrC69fIfJRgcnRF0YD1b7Avay607nfbmDPZsiUHf1vlT+87nkN+dsLexTRu3JVTjSduvIR6Twd8dhRgpX9LMzle6q3EMKheseSqeex36+gc/G2RBef9FlRPUWj1U7aaAEIDmy4Z6t1iOxpL+GA5gl4Gm8uC3HMWqGO/W0cftuQ7s3Pweyv73ndcyObJIavjSRvbU/fifrpGjVsxb59EgFecPGWZ3Jss0L/Wg9qv6Xr+gfcd1+bAbCeozTviPwrghvV6kUSzZrGG74hBwH8UgwiEzZ2OGFzH4dW3l7Fu00d9NhDBn7MROBh4a3ENa4CaVvuiXBxT82qHepbXL/HQL5b0EUmVedmGDJ/0cAXSCpyyuMZVf002cI786bEItCi021k5FX/4QxstqsWmXJGiLRcJ7vcfRSRKBdjNnapUFOb1LkJhMvBvuc2vUhaNfw6FQQojwyXVWM4YqjGvH5VEsVaLqd6MeN+2/64xlTA5Ow9ouQJe4lIYtu8tozty8HshnuqXvXj1naxcnP/cSyV80l4/VnJHoySPY6RH+kehnw2uVhT+fScHv3dyeXzwNeq/KC7FSoIdDwND0KP2bdUMSONM9rJY3Pty75H73jK6NQe/CtnvnvbBqowopmxJlWHTGkFT+Xs0I0ljN3daKrsS+98L+RSwRw5+hTL87na6VcbZ9hrNAFATmT6NR/Hx9K4mcoPxhVzbK4YOUsaX5uBXKO9cOBPfyy9n7232B80cVi9fmA3ESvhkNXdq34CbeVnz7KIc/OrkzzwbSEtd26ocqy+PhJOX8vpJN3d621DGreKrzfvc3HZYDn6lMTJ6UBHwEKSMjpykVlAt7fVnNHdGwEp5FvcMdrF+4GVcwMn73NyWg9+TDLtrtKMwFEpU5EJHzvrQixie5QymJ0LsDnuVZkUTMwvsHhVBx1tXzMkzfD1JNzLWsRmugooPsETZPcW/R2IFHN+DV8LQXVRRMUEKMPxMYgma0kxOmgoyzEdFmT6Aw3O1X5mM1WTEZoVu8UZMUmVem9BRCZdkG1eyEuBFXUAVMrks2BlFwOH73tS2Yw5+z2p1XFaRxqvI609z1s7yxU2HWhpfKmZ0T+X80DE0iQs4Kwe/Z/APTa6viK27s7J1ttdfbXOnJl35KsEtBXJ2TUABPSG3+WVkt7vaBgEFjaJ38JDAvqeZLyWehyAhQf+eiNXNE34mUcyvHiWrOJKeHxW7hQk5Jge/7JjJEBXfsfMiFoWUlcBpI3Lo1C7hkiz9UtxtJ6jrq6eokZRLJ71SgVrFXYL6qd5c7ZeRnYNwO8bwLAcs+VnKS1dKNnfaWT9T0ZYsPS/gKH4ieMHVHT33P9v7prYhOfglxIMhsZ46jdttuxQbX2xZfXNn2LpdcA3lV+lkAV0EtzsGspSLFATIwS/DsB2ChFtmNi9ksO39q/auuTMxfcpyPQ10hUo/mUhQHZTb/AwZPLUNYGcPMBQ3SkRBRYNuHX9m+EkeuyYnMTNgYuz3k0Rhy5f/OnQnQ21h+mKnDog2dSw5AXbJmZ8haybOQWFgejPEeMq2VJnXs5o7PXvcJavM62f7wnu9Sku7qki5q/y3BRiQg196bAfGnTVSS6/CnL5nq2dNLse2l2dZSR6NL+UuklIqA3vbf2IhB78MO7I8+hAkz4/YYuCFyzPC1TZZzZ3JvF9sJU/vmdwbGZiDX1r20MTOKWECx4uFcHFVrclevNhzDxL782BNKlNFzN7LjKU9iWtqkUxNJXkUXS+RI1bcDtlDMYHjpgkl7QXungabK4f7Knqov8LW2mhRk16/KK5r+gTgWGhaJ1Jj4LNOiDdlSjHHl1nmdaLPLc/fXqhhfU+iFR69a9hUa+ZplQpDtq+CqX/wSXFeLIb7QHsKjhAu0wlCQaxVPFb6N4rrJbg1SPwE6/3K9fFpKSZrDwCXvFcBNufgl5bV9vq7MMZPTweNGjnsoo79WTSVxAT2XvxCj81+wDHGdyQrZW85nd+zfJQ7fGXC/axxTfbc99Tc6VmsVs06REGjtK+UOGcnc+lWun+cKto+FFifM7+EeMqHRgJeBupcokRN0fe3tYOHX5zRmMkAzQKagP1Blg8tbuci2Wq6r2Vdzvwyah8oEcRlLbDKDKeKmoH4Hj6aTA6FMWTyeI3t55mtzcEvLe96mraimuq5tdV9Vmt3Yv+9jOROBLZsH7AzNm9SD97PwS+lEye9sCL8N6l1SEKsBaua5s4UlzXe3FltvFYZyLGyrtX7Lx6szMEvP5wvJ7N0sRi/THNnvAwbP1ghy2RUw/keQSZ74YclH6y4eu7WHPzy8lRy1L2kzdf4ku2wuTOaJJa697dlIb7lOumNmtKTJ35FUUCPK3pKNoXU3LGstQj+Q1piG1UyGJ+eFOk0bkyD2Dt3EqzBz4CqsrV5Ve3P+1QOfo92f+48YItmeP3pHn57V83k2XiasXmTvcwqDPO0t0yu9qf9Mge/Uruv2RF3chdNz8rwkfAPsvbwKf4hyZp+KTb3TYj3znfnrRr+D0fm4FcgL0SJnxJePwn7H2/uJHHAAtnNnfKJxfevArzz3Xk5+OVk0E+OAvh1qbNtyYj9yzd3SvxbGt+fY/NWb/vpr+JKn85aZFgt2nyAx1KAa7H33o6hY15/LOGTbACLO4ihryCS7BDoE7CT5mR6Dn7lE0CBB2MnY2Tw39um5s7q9+Cs8uQtW57Mwa9ObshKxKQOTbK47SXUf1ZzZywrCGwtofarBLec/Peya+ZtzcGvzu4vAV2qatvrDJ/cbu4kq7kzWeaNr+CNFmv2DdBZ8v1aZVetqn3WTZq7ybaVqdCbnps7S63vKzqF2tdAJ2UVsGDYD4+sSfBdaluuBh0fdubYnTqVNHfaZ+l4QStX6Cs4wfKfrVs9ZPv11M5fds28DTnze6H6102a2wU8mqnuS2yhni7zxhs8U3F/H1O/mBZWgB/WMrNqFvx1k+aGtv8GoDt5nl6m1x9L4JMq83qprKHS3e31GdhiOQ0Kbyy7Zt7vht84Kge/97LlZdClWXbf9vq9MsmfeEtXMczzAM+rDtwkyF54kSr1XgHwzrWdNTuyQh3IoJ8cdQzIc0b83nuDf7iC/drgvzYIjpHgeBWJ3ncQRARXgvtFcI1h2dtr6e7W9IBoOrNQhYFYA4wAPlhew+CbOgCedZPmPg88kQJBExk7SLR3pb38ZCa/e4sXi/GSTK66P9e/bll+bWdNA19HzD8a4EgR5orFcqF44FLI5kgDBIctOYGWcAIN4QQHNUnwuHTxB7339rNnxOrl13XuVg/jWhcnaq6b9ALrJr0wT5VfJcc9eyl3afarlfDxVCtlcjXl/OupE6mrI9SBs4H3SjV3UqK5UxNef/i1yNb3Sa8GAB8CU4f+YFRdDKZTT8hvfnxZd8sZwzYDp/gLMHwTQGACwv31JEjoiP+/xD3BcxG8bmXj2s29Nn4Zq3qOX35d59J101fkzN8esnbiC1OAWSFjk2pd1Gr7DmieLvMG3+khxq/wDL3w739i2XWdc4bVCevrEvydph4N8OcKG8s1dybbvWJl3lDtJ1ZoVnKsWtbqoOCMnosBll3XmYO/ndm/RtGrifFZMxI6JZo7g46eJnVioGeBXOqkrcT6/jNWTO58e6+/H1VX4yj1CP5OU49m7cQXGDy17QGBrxoJbHxWwkfEP1c3CgWLCZ8dNxZYvPK9aCMH6d3OGtMFxinoismdOfifhAT79g0E3jbCYBMAKhG4xcfoEGYER8LJIQzd0MpLq7p8h7B3of1moKVrcqfW4xiaegV/zcQ5rJk4Zz1whMLmrNZtteZ3uA9nsblTGZKxLV7lob0CjO2a3Kl71pm6r3vwQ/avmTjnTYGz00uxrJbu1N59/n+70lqy8aOcqxcUiW/smtw5E6CrztR9vwB/zcQ57DK1jfe+Pue/QCfan3lJniaaOz1gT7NDopOnCK4Em7IaDS+iS5Qfd02ef92QG4+o5+GrryRPlmx6fBm7/nsb7319zvwdzhg+FGFUmPAJfYAw4SPi+/Xhhk0dW4ay6OP32aAfR/UB0R5P0J4DfHHQ2L303cnz63rshH4mQ+4a/YhB/jL0+p0gCnCCvXfcwPFTUa7aeDRPbvgjszYsrdTpWwAcvvz6+Vv6w1iZfga8rJ4w+4vA42o5eGGyx473W9XFxfCZAXvSXaLAkzjQ4RWFY/sL8P0O/NUTZuvud41h5YRZZwC/S2b2bH9gL28gHsrQwo4MMG7ZjReAJQptmtgtrN7FpR/K7neNoQXGfgyPKZxerAKGXb7K8O5BYPxunt0Lg3hnc8m9kuYDY7uun7+pv42T6W8/aOWEWaycMIuPwevyNcDP7eSMBrt47OPthAq4jsMRA4exVb0spf8ydI+mxrZQy8HvQbomzGLoXWNYPmHmVxWuDIEHKOAwmBbECCKGk4ccxGB3QBTxB3H8j4FRXde/vKXr+vmag19nsnzCLIbd3c6yC2feDHxToRtgR68JFx94YwweylUjPkerFEB1M8qVXde/eBHB/f1VhAaSfe7p2FeQBQfozq3neAfhOAWaCk00NTXT3NyCNLXwT68/fvBzl097ba+/O5wV33uxX4+HaRTgP3V3B29dMOPNN2X50GO6h/mt38ZEl2NcWp3Cxc9dPu21S+/5Zr8HvuGYH8rUqVfc6zru+EKhiaZCE81NLTS3DFjluk0HGnE+OPGkCxtiHNxGBN8x5hERM96IwTEOxnEwxv39uM9N/KCRxsE0IvjGOAuNMVt8le/gOC6OcZ9tuHGgIUWXGuNsdYyDBPbecZyXcvAbQM6/4B83OkZWi3FwHRfHdTGOuzQHv2FUvzsj8vSdAq5bWJGD3zDgm07HMRingOO67DBghw9y8BvH43/diIPruriOi1tokhz8BvL4HccNVT5OoUAOfqP8cMdd5YPv4LpNFNzmHPxGkTPOvHyN4zg+8wtNNLe05OA3GPspuAUKhSYU2TkHv4Gk4BQ8t9BEU6GZ5qbmQTn4jeTxu4WX3EKBQnMzheaW3XPwG0Se++0DtB97zqjWloG7NhVa7m5pGjCYXBpHXlsQ3wZ/w/plDfX7/w9sJTyL9hMvGQAAAABJRU5ErkJggg== + mediatype: image/png + inventoryKind: MongoDBAtlasInventory + connectionKind: MongoDBAtlasConnection + instanceKind: MongoDBAtlasInstance + allowsFreeTrial: true + externalProvisionURL: https://www.mongodb.com/atlas/database + externalProvisionDescription: Follow the MongoDB Atlas procedure [Create a New Cluster|https://docs.atlas.mongodb.com/tutorial/create-new-cluster/] to create a new paid cluster + credentialFields: + - key: orgId + displayName: Organization ID + type: string + required: true + helpText: You can find the Organization ID from the Organization Settings page on your MongoDB account home page. + - key: publicApiKey + displayName: Public API Key + type: string + required: true + helpText: You can find the Public API Key from the API Keys tab on the Organization Access Manager page from your MongoDB account home page + - key: privateApiKey + displayName: Private API Key + type: maskedstring + required: true + helpText: You can find the Private API Key from the API Keys tab on the Organization Access Manager page from your MongoDB account home page. + instanceParameterSpecs: + - name: clusterName + displayName: Cluster Name + type: string + required: true + - name: ProjectName + displayName: Atlas Project Name + type: string + required: true + - name: clusterType + displayName: Cluster Type + type: string + required: false + defaultValue: Shared + - name: providerName + displayName: Cloud Provider + type: string + required: false + defaultValue: AWS + - name: regionName + displayName: Cloud Region + type: string + required: false + defaultValue: US_EAST_1 + - name: instanceSizeName + displayName: Cluster Size Name + type: string + required: false + defaultValue: M0 diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 54ca60636c..663424c267 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -7,5 +7,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: mongodb-atlas-controller - newTag: latest + newName: quay.io/mongodb/mongodb-atlas-kubernetes-dbaas + newTag: 0.3.0 diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index d93c255488..5927218198 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -19,13 +19,13 @@ spec: serviceAccountName: operator containers: - command: - - /manager + - /manager args: - - "--leader-elect" - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--log-level=info" - - "--log-encoder=json" + - "--leader-elect" + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" + - "--log-level=info" + - "--log-encoder=json" image: controller:latest name: manager securityContext: @@ -46,7 +46,7 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 768Mi requests: cpu: 100m memory: 50Mi @@ -59,4 +59,6 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + - name: SYNC_PERIOD_MIN + value: 180 terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/mongodb-atlas-kubernetes.clusterserviceversion.yaml b/config/manifests/bases/mongodb-atlas-kubernetes.clusterserviceversion.yaml index 7e05a93d5b..4a55fefc31 100644 --- a/config/manifests/bases/mongodb-atlas-kubernetes.clusterserviceversion.yaml +++ b/config/manifests/bases/mongodb-atlas-kubernetes.clusterserviceversion.yaml @@ -7,37 +7,57 @@ metadata: categories: Database description: The MongoDB Atlas Kubernetes Operator enables easy management of Clusters in MongoDB Atlas + olm.skipRange: '>=0.2.0 <0.3.0' name: mongodb-atlas-kubernetes.v0.0.0 namespace: placeholder spec: - apiservicedefinitions: { } + apiservicedefinitions: {} customresourcedefinitions: owned: - - description: AtlasDeployment is the Schema for the atlasclusters API - displayName: Atlas Deployment - kind: AtlasDeployment - name: atlasdeployments.atlas.mongodb.com - version: v1 - - description: AtlasDatabaseUser is the Schema for the Atlas Database User API - displayName: Atlas Database User - kind: AtlasDatabaseUser - name: atlasdatabaseusers.atlas.mongodb.com - version: v1 - - description: AtlasProject is the Schema for the atlasprojects API - displayName: Atlas Project - kind: AtlasProject - name: atlasprojects.atlas.mongodb.com - version: v1 - - description: AtlasBackupSchedule is the Schema for the atlasbackupschedule API - displayName: Atlas Backup Schedule - kind: AtlasBackupSchedule - name: atlasbackupschedules.atlas.mongodb.com - version: v1 - - description: AtlasBackupPolicy is the Schema for the atlasbackuppolicy API - displayName: Atlas Backup Policy - kind: AtlasBackupPolicy - name: atlasbackuppolicies.atlas.mongodb.com - version: v1 + - description: AtlasDeployment is the Schema for the atlasclusters API + displayName: Atlas Deployment + kind: AtlasDeployment + name: atlasdeployments.atlas.mongodb.com + version: v1 + - description: AtlasBackupPolicy is the Schema for the atlasbackuppolicies API + displayName: Atlas Backup Policy + kind: AtlasBackupPolicy + name: atlasbackuppolicies.atlas.mongodb.com + version: v1 + - description: AtlasBackupSchedule is the Schema for the atlasbackupschedules + API + displayName: Atlas Backup Schedule + kind: AtlasBackupSchedule + name: atlasbackupschedules.atlas.mongodb.com + version: v1 + - description: AtlasDatabaseUser is the Schema for the Atlas Database User API + displayName: Atlas Database User + kind: AtlasDatabaseUser + name: atlasdatabaseusers.atlas.mongodb.com + version: v1 + - description: AtlasProject is the Schema for the atlasprojects API + displayName: Atlas Project + kind: AtlasProject + name: atlasprojects.atlas.mongodb.com + version: v1 + - description: MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections + API + displayName: Mongo DBAtlas Connection + kind: MongoDBAtlasConnection + name: mongodbatlasconnections.dbaas.redhat.com + version: v1alpha1 + - description: MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance + API + displayName: Mongo DBAtlas Instance + kind: MongoDBAtlasInstance + name: mongodbatlasinstances.dbaas.redhat.com + version: v1alpha1 + - description: MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory + API + displayName: Mongo DBAtlas Inventory + kind: MongoDBAtlasInventory + name: mongodbatlasinventories.dbaas.redhat.com + version: v1alpha1 description: | The MongoDB Atlas Operator provides a native integration between the Kubernetes orchestration platform and MongoDB Atlas — the only multi-cloud document database service that gives you the versatility you need to build sophisticated and resilient applications that can adapt to changing customer demands and market trends. @@ -149,33 +169,33 @@ spec: ``` displayName: MongoDB Atlas Operator icon: - - base64data: iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJEXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarVhtdiMpDPzPKfYIDUIIHYfP9/YGe/wtQXcnsZ1JMjP2xLQBg1CVSmLc+O/f6f7BiwIFF1ly0pQOvKJGDQUP+divsj79EdfnesVzCN8/9Lt7IKCL0NL+mtM5/+r39wK7KXjidwvldg7UjwN67hDyw0LnRmQWBTz0cyE9F6KwB/y5QNnHOpJmeX+EOnbbr5Pk/efsI7VjHcSfo4/fo8B7nbEPhTDI04HPQHEbQPbnHRUbwCe+YKKnjOe4ejxdlsAhr/x0vLPKPaJyP/lP+h9AobT7HTo+OjPd7ct+z6+d75aL3+1M7d75Qz/3oz4e5/qbs2c359inKzHBpek81HWU9YSJWCTS+lnCW/DHeJb1VryzA3sbIO9Hw44Vz+oDvD999N0XP/1YbfMNJsYwgqANoQEb68skQUOjwxk29vYzCCl1oBaoAV5Cb7ht8WtfXds1n7Fx95gZPBbzK9bs42+8P11oTqO890e+fQW7ggUFzDDk7BOzAIifF494Ofh6P74MVwKCvNycccBy1L1EZX9yy3hEC2jCREa7Y81LPxeAi7A3wxhPQOBIntgnf0gI4j38mIFPwUIZQRMqIPDMocPKEIkSwMnB9sZvxK+5gcPuhmYBCKZEAmiUCrCKEDbwR2IGhwoTR2ZOLJxZuSRKMXFKSZKJXxGSKCxJRLKolEw5Zs4pS84uay4alCCOrElFs6qWgk0LVi74dcGEUmqoVGPlmqrUXLWWBvq02LilJi27pq300KlDJ3rq0nPXXoYfoNKIg0caMvLQUSaoNmnGyTNNmXnqLDdq3m1Yn97fR81fqIWFlE2UGzX8VORawpucsGEGxEL0QFwMARA6GGZH9jEGZ9AZZocGRAUHWMkGTveGGBCMwwee/sbuDbkPuLkY/wi3cCHnDLq/gZwz6D5B7hm3F6h1yzbtILcQsjA0px6E8MOEkUvIxZLat1t3d9QCRxsxap9zbTJnSpC9Ujts4Njb6FI9zspJeXbVkeaYtbVJSEezUW6JaKAvwg/D5hQZLDanrtM00jbEY0rHKkDDT6qjjyI1Tvi0x0mumC00PWvDJgQFlzlr6JBLDpCAfhT8JmmB17ocZZ0GOWg/HHfrHjt+t10LAbGArAzLYWMFIjiYSgUyBMqQThxLoUockGq0iRauh56ughvMVW77wZ9+oOWHXtjDEyFKmyAyYgHI19rzRglrZxYvpcA/8Ec1h7rT63Q63Tw690qqSBQJdCs5llETtVGW9VzNejNAzPo0VWt1MD+hwMgT1lTWuj1MBWGlfqQ8kPXMvgMxs56QdF+17rOBX7WS9IlLzsj0nkswang2SsLdcyIt4xRwm+8UBaGTU0gRkaOh10kbtJLBoye6g78sscDpBA9P6YMn4ngidXfgQR1AIWLLjFyG1Mbw/UzR2d7Z2yfcx6EhKA+P6DfFAW1nywjatUeUGk5/Hc+t+2zgkxYhUnAuglk6BGE0m4lCmm4eaSwCwWjITao1orWjGS3EjpZENeNoxg6Qc0pZEYQv5m4m+E+rg/b47bE2dXwVCQDlNY2me6QRBA1iGCEhRbBjNe8F0L/N03a/bc8FWAUaKJ7FAsVBF7mPWO/Ahnz+XNZCdu86wOgwYwXw4fSOAb+8M1bowkooSoXgmAKCKaaBSwER/RBBCHJR5F0klsyWSyrl2vVkchv+ay0Z5IgTNARSNpvOJbKgdkog+dGr8b23CUVLwm3MXGAv9zf5i0grEqY2dchhniumDwkX78a3afXWuruDC3R9mMCg2ZH4pFQxsNVXIAEKVghKRpe2vqIfodLqTwXAD0EOsNTbjSm4FrCboDvIQtJa77P5ihzfpOrk0jpKqQEZ7DHj30T4X6IfnjjiviTJynfQ74d8NyRZ9rkzoXsbghrGJoIikuGb1hDza7FCQ/LrfeLpbnpOR3Asbg+2S4ERh9mALLv3h+dZXowU1hkdQYwG7ohDpp6qnEf9eXpzI9cWdmgiBua6CmmpVo28HNFiAtLnGDi/IqehYLLd3Urk7acMROiNULaywxE4lTNlYaszIj8MXSMIAxMLMiO81TxpLxc+CIX7plJ8UvScIGDEPQ49k2B8RYKHQut9i9BqjOQWhtomW3G6pguDF2NuDWpCnjZpyP5zL/y6dd8IhbzrPyQdZJhmjcKstRWoSBtK9xFbVKVqmeuN+i+Z/1TdVUuQfAgywAEVaqBb5jGvGCf+AbMfNsTNwZtkGeOslliVhF3371oCOWdAc1jWzoXOnfdCFO6VqDKjipiVCMkYgm2VSwIM1S8Fr33UuDLJhwg2GbEQRgIFRCgbAvlCuOD03tu7Qu8SSNxJSi3FYFjpE76mhtw+vUM+N0WU2lNeBwpqB4ofqpRdBsYiKONYcc3BfWosqbYCLxy8q5HfqNnu2s3qCbWCytHwsH1WvnPmihPU+zgkNxTMioQiqPKROhd1/PDXWS0Fn7nOvWNDLB3FmJYHN24vKtdqBTMuc/gFLogWAJRONyL636yEhYjY7Uv7T7q5vYnIXaXI4a12X+6Ezxni0lHxJpgdU+jNVbkDq+bfqkNeRT8KUJzPWBRn64tFuCcNAotWugWLirEIpXvd1MX+DaXc8K6Q/U9WkwT7ruqDnuh2+ukAQWQJ6SNBGIVWhI7g1qpdEMsDPMINBJBdGLWMKxhmwIhVoOPeYSGyrx28rx0dlxoL9WTGIj1ZjYIyEXV5UsKN/SqRUBi27+vRd9sa5fQjoqPf0ejoDEdZ4UjI0kdWVC3mRZArW4GP0hO6hmi+a2a6auawa2bU2YKyMMAD+2qGKrJ4lNuofE7Zhg1LnMnSI1IGDg0esfENVp1sQ7J0F91M8I1uCJakKNxHE/C0FNw+Ajg3QhWWmrsdcIR5ak2cp9aIA03kpImJTclWlaYGPtVWWk0HfmBnOq84dF1xglVxGWdK2GuVx4o8mvyRO7pD+0Up9evW/TleGy73BV77WqdpX0Is8iEsdgnx+yZeJ0hmIupmwlUcl5BT7SKus9BBm/ft6+xqXfwzibyq3OxgyhFHqt/IHuuMUMrBHLhVjyI/7AoDgDkkjh8GiTETsfU/ZHuEtrDMfYEAAAGFaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDQBzFX1O1UioiVhBxyFB1sSAq4qhVKEKFUCu06mBy6YfQpCFJcXEUXAsOfixWHVycdXVwFQTBDxA3NydFFynxf2mhRYwHx/14d+9x9w4QqkWmWW1jgKbbZjIeE9OZFTHwiiD60IMRdMjMMmYlKQHP8XUPH1/vojzL+9yfo0vNWgzwicQzzDBt4nXiqU3b4LxPHGYFWSU+Jx416YLEj1xX6vzGOe+ywDPDZio5RxwmFvMtrLQwK5ga8SRxRNV0yhfSdVY5b3HWimXWuCd/YSirLy9xneYg4ljAIiSIUFDGBoqwEaVVJ8VCkvZjHv4B1y+RSyHXBhg55lGCBtn1g//B726t3MR4PSkUA9pfHOdjCAjsArWK43wfO07tBPA/A1d601+qAtOfpFeaWuQI6N4GLq6bmrIHXO4A/U+GbMqu5Kcp5HLA+xl9UwbovQWCq/XeGvs4fQBS1FXiBjg4BIbzlL3m8e7O1t7+PdPo7wdVb3KbaWTEXAAADRxpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6ZDk1YjhmMjctMWM0NS00YjU1LWEwZTMtNmNmMjM0Yzk1ZWVkIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVhMGY5MTI5LWJlMDItNDVjOS1iNGU4LTU3N2MxZTBiZGJhNyIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjcyNmY4ZGFlLTM4ZTYtNGQ4Ni1hNTI4LWM0NTc4ZGE4ODA0NSIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09Ik1hYyBPUyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2MzQ4MzgwMTYyMTQ2MTMiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4yNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1YWNhZmVhMC0xZmY5LTRiMmUtYmY0NC02NTM3MzYwMGQzNjEiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTWFjIE9TKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0xMC0yMVQxODo0MDoxNiswMTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz6528V0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH5QoVESgQ+iToFAAAA8xJREFUeNrlW01PU0EUPTPV+oqb4h+wENYKXbmzsjLEKPAHwB1xQ6N7adiboBtrSAT5AaQmBpuYSN25MS17k5Zf0MemFGznungttCkf782bmTels2w6mbnnnnPv3DvzYrBhrMytIT01gz9/f5temkVv/NMUwKsg1MFEGvlizeTy3ALj9zuuGAf4T2QzydEBACwHINXzwwSOE29N7iAWqe7BsoOYsEdITx2ZigcsIupnzqh/8SC0/6Wx+aNy8yTg6X7rWsfEbu96/71JAGQzyY7n/Rg2AcZ3dQdFswA0Exs+je8KYUZ3UDQXA1bmlgFsScwkMFrEx++F4QXgPN/LaZpQR6IxiY2SO6QSGMj3Qd00jpPE5+FkgDz1B3kAMYt8sTQ8AGQzSTTHyqG83z+qcBpplVLQK4Hm2KpC473U2BzLDgcDwgY+QwFRIwP4knLjuwFRIQv0MGB5PgnntKwFAMUs0MMA53Rem/Ge25I4ufvCXgkQVrVXsSSW7JTAq7lpCJQNnK4IEJNhW2jqGdDGsrH6QrB5GyXwWMKXLoi5gdnL8dwuCXjRvy4xs0vjVGDonMa9MNlALQPiJxlJOcvruOlM2yMBzuQ3Q3Al44BFADA8lJ9LrtSKnD2wBwAhe/hhIVIZpWxiQJgG5qHkohYBoPP4q6tks2Qfh1GBzu3xhWQckM0eWgAIfprrBE+SN4LZBACTNIQzF4KO5EAnmxgQwhtckj2WMeBA8gARpqQ9sAcAAfnrbLk4QGBUsQcAHmIzXFLLrbZFDMgXS1KZoN2W1DHVwj6iUH8O4FQKPCcWc3t6AkGCTin0dpUDQPhq6OREgNixD4BmvBBYBlKNTaqpuChVD8B2wQWj98EnOrVA3hf4YHExJLb1l3FUsBeAfLEG0Bef//Y8H28FqSW2VT2p1VgNUi5QLKC4z1qCqoBYt78fkC/WfMWCwMUM21H5oFrzA4n4xrUt724xQy0fxRRVkd/LKQ0lWgHYLrgAvfQXN1vXSYAAmlUeS7VH63yxBMIVUvDdB1jX8S2BmZbYp70scNkRmXtXaQkOXN4b3FJNfbMAAEDzzoLcFRhV4TReaztOGAPAiwdPLgDh8OqUR7M6XoiaB6CbGtts4cLzwbtv1N8Z7hiv+Rsi823xzb0KRB8T7gMA3jxj59dcZoz3snBUY+VpCmD7nautXGcva2Aog8Siqa/Hov1sbuAxJZXgHC/o1Hz0Ehgsmn71/FIxaXz0AAwS8sj0ihYAcBb5CVJ9weFnwLnR1K6PHgC9FyJsFCVwq+9afAQlIITbnxXMjv+6222dh4/VtAAAAABJRU5ErkJggg== - mediatype: image/png + - base64data: iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJEXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarVhtdiMpDPzPKfYIDUIIHYfP9/YGe/wtQXcnsZ1JMjP2xLQBg1CVSmLc+O/f6f7BiwIFF1ly0pQOvKJGDQUP+divsj79EdfnesVzCN8/9Lt7IKCL0NL+mtM5/+r39wK7KXjidwvldg7UjwN67hDyw0LnRmQWBTz0cyE9F6KwB/y5QNnHOpJmeX+EOnbbr5Pk/efsI7VjHcSfo4/fo8B7nbEPhTDI04HPQHEbQPbnHRUbwCe+YKKnjOe4ejxdlsAhr/x0vLPKPaJyP/lP+h9AobT7HTo+OjPd7ct+z6+d75aL3+1M7d75Qz/3oz4e5/qbs2c359inKzHBpek81HWU9YSJWCTS+lnCW/DHeJb1VryzA3sbIO9Hw44Vz+oDvD999N0XP/1YbfMNJsYwgqANoQEb68skQUOjwxk29vYzCCl1oBaoAV5Cb7ht8WtfXds1n7Fx95gZPBbzK9bs42+8P11oTqO890e+fQW7ggUFzDDk7BOzAIifF494Ofh6P74MVwKCvNycccBy1L1EZX9yy3hEC2jCREa7Y81LPxeAi7A3wxhPQOBIntgnf0gI4j38mIFPwUIZQRMqIPDMocPKEIkSwMnB9sZvxK+5gcPuhmYBCKZEAmiUCrCKEDbwR2IGhwoTR2ZOLJxZuSRKMXFKSZKJXxGSKCxJRLKolEw5Zs4pS84uay4alCCOrElFs6qWgk0LVi74dcGEUmqoVGPlmqrUXLWWBvq02LilJi27pq300KlDJ3rq0nPXXoYfoNKIg0caMvLQUSaoNmnGyTNNmXnqLDdq3m1Yn97fR81fqIWFlE2UGzX8VORawpucsGEGxEL0QFwMARA6GGZH9jEGZ9AZZocGRAUHWMkGTveGGBCMwwee/sbuDbkPuLkY/wi3cCHnDLq/gZwz6D5B7hm3F6h1yzbtILcQsjA0px6E8MOEkUvIxZLat1t3d9QCRxsxap9zbTJnSpC9Ujts4Njb6FI9zspJeXbVkeaYtbVJSEezUW6JaKAvwg/D5hQZLDanrtM00jbEY0rHKkDDT6qjjyI1Tvi0x0mumC00PWvDJgQFlzlr6JBLDpCAfhT8JmmB17ocZZ0GOWg/HHfrHjt+t10LAbGArAzLYWMFIjiYSgUyBMqQThxLoUockGq0iRauh56ughvMVW77wZ9+oOWHXtjDEyFKmyAyYgHI19rzRglrZxYvpcA/8Ec1h7rT63Q63Tw690qqSBQJdCs5llETtVGW9VzNejNAzPo0VWt1MD+hwMgT1lTWuj1MBWGlfqQ8kPXMvgMxs56QdF+17rOBX7WS9IlLzsj0nkswang2SsLdcyIt4xRwm+8UBaGTU0gRkaOh10kbtJLBoye6g78sscDpBA9P6YMn4ngidXfgQR1AIWLLjFyG1Mbw/UzR2d7Z2yfcx6EhKA+P6DfFAW1nywjatUeUGk5/Hc+t+2zgkxYhUnAuglk6BGE0m4lCmm4eaSwCwWjITao1orWjGS3EjpZENeNoxg6Qc0pZEYQv5m4m+E+rg/b47bE2dXwVCQDlNY2me6QRBA1iGCEhRbBjNe8F0L/N03a/bc8FWAUaKJ7FAsVBF7mPWO/Ahnz+XNZCdu86wOgwYwXw4fSOAb+8M1bowkooSoXgmAKCKaaBSwER/RBBCHJR5F0klsyWSyrl2vVkchv+ay0Z5IgTNARSNpvOJbKgdkog+dGr8b23CUVLwm3MXGAv9zf5i0grEqY2dchhniumDwkX78a3afXWuruDC3R9mMCg2ZH4pFQxsNVXIAEKVghKRpe2vqIfodLqTwXAD0EOsNTbjSm4FrCboDvIQtJa77P5ihzfpOrk0jpKqQEZ7DHj30T4X6IfnjjiviTJynfQ74d8NyRZ9rkzoXsbghrGJoIikuGb1hDza7FCQ/LrfeLpbnpOR3Asbg+2S4ERh9mALLv3h+dZXowU1hkdQYwG7ohDpp6qnEf9eXpzI9cWdmgiBua6CmmpVo28HNFiAtLnGDi/IqehYLLd3Urk7acMROiNULaywxE4lTNlYaszIj8MXSMIAxMLMiO81TxpLxc+CIX7plJ8UvScIGDEPQ49k2B8RYKHQut9i9BqjOQWhtomW3G6pguDF2NuDWpCnjZpyP5zL/y6dd8IhbzrPyQdZJhmjcKstRWoSBtK9xFbVKVqmeuN+i+Z/1TdVUuQfAgywAEVaqBb5jGvGCf+AbMfNsTNwZtkGeOslliVhF3371oCOWdAc1jWzoXOnfdCFO6VqDKjipiVCMkYgm2VSwIM1S8Fr33UuDLJhwg2GbEQRgIFRCgbAvlCuOD03tu7Qu8SSNxJSi3FYFjpE76mhtw+vUM+N0WU2lNeBwpqB4ofqpRdBsYiKONYcc3BfWosqbYCLxy8q5HfqNnu2s3qCbWCytHwsH1WvnPmihPU+zgkNxTMioQiqPKROhd1/PDXWS0Fn7nOvWNDLB3FmJYHN24vKtdqBTMuc/gFLogWAJRONyL636yEhYjY7Uv7T7q5vYnIXaXI4a12X+6Ezxni0lHxJpgdU+jNVbkDq+bfqkNeRT8KUJzPWBRn64tFuCcNAotWugWLirEIpXvd1MX+DaXc8K6Q/U9WkwT7ruqDnuh2+ukAQWQJ6SNBGIVWhI7g1qpdEMsDPMINBJBdGLWMKxhmwIhVoOPeYSGyrx28rx0dlxoL9WTGIj1ZjYIyEXV5UsKN/SqRUBi27+vRd9sa5fQjoqPf0ejoDEdZ4UjI0kdWVC3mRZArW4GP0hO6hmi+a2a6auawa2bU2YKyMMAD+2qGKrJ4lNuofE7Zhg1LnMnSI1IGDg0esfENVp1sQ7J0F91M8I1uCJakKNxHE/C0FNw+Ajg3QhWWmrsdcIR5ak2cp9aIA03kpImJTclWlaYGPtVWWk0HfmBnOq84dF1xglVxGWdK2GuVx4o8mvyRO7pD+0Up9evW/TleGy73BV77WqdpX0Is8iEsdgnx+yZeJ0hmIupmwlUcl5BT7SKus9BBm/ft6+xqXfwzibyq3OxgyhFHqt/IHuuMUMrBHLhVjyI/7AoDgDkkjh8GiTETsfU/ZHuEtrDMfYEAAAGFaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDQBzFX1O1UioiVhBxyFB1sSAq4qhVKEKFUCu06mBy6YfQpCFJcXEUXAsOfixWHVycdXVwFQTBDxA3NydFFynxf2mhRYwHx/14d+9x9w4QqkWmWW1jgKbbZjIeE9OZFTHwiiD60IMRdMjMMmYlKQHP8XUPH1/vojzL+9yfo0vNWgzwicQzzDBt4nXiqU3b4LxPHGYFWSU+Jx416YLEj1xX6vzGOe+ywDPDZio5RxwmFvMtrLQwK5ga8SRxRNV0yhfSdVY5b3HWimXWuCd/YSirLy9xneYg4ljAIiSIUFDGBoqwEaVVJ8VCkvZjHv4B1y+RSyHXBhg55lGCBtn1g//B726t3MR4PSkUA9pfHOdjCAjsArWK43wfO07tBPA/A1d601+qAtOfpFeaWuQI6N4GLq6bmrIHXO4A/U+GbMqu5Kcp5HLA+xl9UwbovQWCq/XeGvs4fQBS1FXiBjg4BIbzlL3m8e7O1t7+PdPo7wdVb3KbaWTEXAAADRxpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2ltcC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6ZDk1YjhmMjctMWM0NS00YjU1LWEwZTMtNmNmMjM0Yzk1ZWVkIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVhMGY5MTI5LWJlMDItNDVjOS1iNGU4LTU3N2MxZTBiZGJhNyIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjcyNmY4ZGFlLTM4ZTYtNGQ4Ni1hNTI4LWM0NTc4ZGE4ODA0NSIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09Ik1hYyBPUyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2MzQ4MzgwMTYyMTQ2MTMiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4yNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1YWNhZmVhMC0xZmY5LTRiMmUtYmY0NC02NTM3MzYwMGQzNjEiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTWFjIE9TKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0xMC0yMVQxODo0MDoxNiswMTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz6528V0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAB3RJTUUH5QoVESgQ+iToFAAAA8xJREFUeNrlW01PU0EUPTPV+oqb4h+wENYKXbmzsjLEKPAHwB1xQ6N7adiboBtrSAT5AaQmBpuYSN25MS17k5Zf0MemFGznungttCkf782bmTels2w6mbnnnnPv3DvzYrBhrMytIT01gz9/f5temkVv/NMUwKsg1MFEGvlizeTy3ALj9zuuGAf4T2QzydEBACwHINXzwwSOE29N7iAWqe7BsoOYsEdITx2ZigcsIupnzqh/8SC0/6Wx+aNy8yTg6X7rWsfEbu96/71JAGQzyY7n/Rg2AcZ3dQdFswA0Exs+je8KYUZ3UDQXA1bmlgFsScwkMFrEx++F4QXgPN/LaZpQR6IxiY2SO6QSGMj3Qd00jpPE5+FkgDz1B3kAMYt8sTQ8AGQzSTTHyqG83z+qcBpplVLQK4Hm2KpC473U2BzLDgcDwgY+QwFRIwP4knLjuwFRIQv0MGB5PgnntKwFAMUs0MMA53Rem/Ge25I4ufvCXgkQVrVXsSSW7JTAq7lpCJQNnK4IEJNhW2jqGdDGsrH6QrB5GyXwWMKXLoi5gdnL8dwuCXjRvy4xs0vjVGDonMa9MNlALQPiJxlJOcvruOlM2yMBzuQ3Q3Al44BFADA8lJ9LrtSKnD2wBwAhe/hhIVIZpWxiQJgG5qHkohYBoPP4q6tks2Qfh1GBzu3xhWQckM0eWgAIfprrBE+SN4LZBACTNIQzF4KO5EAnmxgQwhtckj2WMeBA8gARpqQ9sAcAAfnrbLk4QGBUsQcAHmIzXFLLrbZFDMgXS1KZoN2W1DHVwj6iUH8O4FQKPCcWc3t6AkGCTin0dpUDQPhq6OREgNixD4BmvBBYBlKNTaqpuChVD8B2wQWj98EnOrVA3hf4YHExJLb1l3FUsBeAfLEG0Bef//Y8H28FqSW2VT2p1VgNUi5QLKC4z1qCqoBYt78fkC/WfMWCwMUM21H5oFrzA4n4xrUt724xQy0fxRRVkd/LKQ0lWgHYLrgAvfQXN1vXSYAAmlUeS7VH63yxBMIVUvDdB1jX8S2BmZbYp70scNkRmXtXaQkOXN4b3FJNfbMAAEDzzoLcFRhV4TReaztOGAPAiwdPLgDh8OqUR7M6XoiaB6CbGtts4cLzwbtv1N8Z7hiv+Rsi823xzb0KRB8T7gMA3jxj59dcZoz3snBUY+VpCmD7nautXGcva2Aog8Siqa/Hov1sbuAxJZXgHC/o1Hz0Ehgsmn71/FIxaXz0AAwS8sj0ihYAcBb5CVJ9weFnwLnR1K6PHgC9FyJsFCVwq+9afAQlIITbnxXMjv+6222dh4/VtAAAAABJRU5ErkJggg== + mediatype: image/png install: spec: deployments: null strategy: "" installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces keywords: - - MongoDB - - Atlas - - Database - - Replica Set - - Cluster + - MongoDB + - Atlas + - Database + - Replica Set + - Cluster links: - - name: MongoDB Atlas Kubernetes - url: https://github.com/mongodb/mongodb-atlas-kubernetes + - name: MongoDB Atlas Kubernetes + url: https://github.com/mongodb/mongodb-atlas-kubernetes maintainers: - - email: support@mongodb.com - name: MongoDB, Inc + - email: support@mongodb.com + name: MongoDB, Inc maturity: beta provider: name: MongoDB, Inc diff --git a/config/rbac/clusterwide/role.yaml b/config/rbac/clusterwide/role.yaml index 42d11dc3bc..c0cb079bd2 100644 --- a/config/rbac/clusterwide/role.yaml +++ b/config/rbac/clusterwide/role.yaml @@ -24,6 +24,14 @@ rules: - patch - update - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch - apiGroups: - atlas.mongodb.com resources: @@ -124,3 +132,83 @@ rules: - get - patch - update +- apiGroups: + - dbaas.redhat.com + resources: + - dbaasproviders + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - dbaasproviders/status + verbs: + - get + - patch + - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections/status + verbs: + - get + - patch + - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances/status + verbs: + - get + - patch + - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories/status + verbs: + - get + - patch + - update diff --git a/config/rbac/namespaced/role.yaml b/config/rbac/namespaced/role.yaml index 4de45f98fe..0adec15c40 100644 --- a/config/rbac/namespaced/role.yaml +++ b/config/rbac/namespaced/role.yaml @@ -125,3 +125,63 @@ rules: - get - patch - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasconnections/status + verbs: + - get + - patch + - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinstances/status + verbs: + - get + - patch + - update +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - dbaas.redhat.com + resources: + - mongodbatlasinventories/status + verbs: + - get + - patch + - update diff --git a/config/samples/dbaas_v1alpha1_atlasconnection.yaml b/config/samples/dbaas_v1alpha1_atlasconnection.yaml new file mode 100644 index 0000000000..876ee75c00 --- /dev/null +++ b/config/samples/dbaas_v1alpha1_atlasconnection.yaml @@ -0,0 +1,10 @@ +apiVersion: dbaas.redhat.com/v1alpha1 +kind: MongoDBAtlasConnection +metadata: + name: test-connection + namespace: my-namespace +spec: + inventoryRef: + name: test-inventory + namespace: mongodb-atlas-system + instanceID: 606b2ffbc9a90e310e642482 diff --git a/config/samples/dbaas_v1alpha1_atlasinstance.yaml b/config/samples/dbaas_v1alpha1_atlasinstance.yaml new file mode 100644 index 0000000000..4253ffaff4 --- /dev/null +++ b/config/samples/dbaas_v1alpha1_atlasinstance.yaml @@ -0,0 +1,14 @@ +apiVersion: dbaas.redhat.com/v1alpha1 +kind: MongoDBAtlasInstance +metadata: + name: test-instance +spec: + inventoryRef: + name: test-inventory + namespace: mongodb-atlas-system + name: my-cluster-free + cloudProvider: aws + cloudRegion: US_EAST_1 + otherInstanceParams: + projectName: my-atlas-project-free + instanceSizeName: M0 diff --git a/config/samples/dbaas_v1alpha1_atlasinventory.yaml b/config/samples/dbaas_v1alpha1_atlasinventory.yaml new file mode 100644 index 0000000000..423fd4e4ee --- /dev/null +++ b/config/samples/dbaas_v1alpha1_atlasinventory.yaml @@ -0,0 +1,8 @@ +apiVersion: dbaas.redhat.com/v1alpha1 +kind: MongoDBAtlasInventory +metadata: + name: test-inventory +spec: + credentialsRef: + name: my-atlas-key + namespace: mongodb-atlas-system \ No newline at end of file diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index b0ab33f306..a5bfa246b4 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -7,4 +7,7 @@ resources: - atlas_v1_atlasdatabaseuser.yaml - atlas_v1_atlasbackuppolicy.yaml - atlas_v1_atlasbackupschedule.yaml + - dbaas_v1alpha1_atlasconnection.yaml + - dbaas_v1alpha1_atlasinventory.yaml + - dbaas_v1alpha1_atlasinstance.yaml # +kubebuilder:scaffold:manifestskustomizesamples diff --git a/deploy/crds/dbaas.redhat.com_mongodbatlasconnections.yaml b/deploy/crds/dbaas.redhat.com_mongodbatlasconnections.yaml new file mode 100644 index 0000000000..cbbce2e39d --- /dev/null +++ b/deploy/crds/dbaas.redhat.com_mongodbatlasconnections.yaml @@ -0,0 +1,161 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasconnections.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasConnection + listKind: MongoDBAtlasConnectionList + plural: mongodbatlasconnections + singular: mongodbatlasconnection + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSConnectionSpec defines the desired state of DBaaSConnection + properties: + instanceID: + description: The ID of the instance to connect to, as seen in the + Status of the referenced DBaaSInventory + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + required: + - instanceID + - inventoryRef + type: object + status: + description: DBaaSConnectionStatus defines the observed state of DBaaSConnection + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + connectionInfoRef: + description: A ConfigMap holding non-sensitive information needed + for connecting to the DB instance + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + credentialsRef: + description: Secret holding the credentials needed for accessing the + DB instance + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/crds/dbaas.redhat.com_mongodbatlasinstances.yaml b/deploy/crds/dbaas.redhat.com_mongodbatlasinstances.yaml new file mode 100644 index 0000000000..cfd942e7a4 --- /dev/null +++ b/deploy/crds/dbaas.redhat.com_mongodbatlasinstances.yaml @@ -0,0 +1,173 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasinstances.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInstance + listKind: MongoDBAtlasInstanceList + plural: mongodbatlasinstances + singular: mongodbatlasinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInstanceSpec defines the desired state of DBaaSInstance + properties: + cloudProvider: + description: Identifies the desired cloud infrastructure provider + type: string + cloudRegion: + description: Identifies the requested deployment region within the + cloud provider (e.g. us-east-1) + type: string + inventoryRef: + description: A reference to the relevant DBaaSInventory CR + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + name: + description: The name of this instance in the database service + type: string + otherInstanceParams: + additionalProperties: + type: string + description: Any other provider-specific parameters related to the + instance provisioning + type: object + required: + - inventoryRef + - name + type: object + status: + description: DBaaSInstanceStatus defines the observed state of DBaaSInstance + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instanceID: + description: The ID of the instance, + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related to this + instance + type: object + phase: + description: Represents the cluster provisioning phase Pending - provisioning + not yet started Creating - provisioning in progress Updating - cluster + updating in progress Deleting - cluster deletion in progress Deleted + - cluster has been deleted Ready - cluster provisioning complete + type: string + required: + - instanceID + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/crds/dbaas.redhat.com_mongodbatlasinventories.yaml b/deploy/crds/dbaas.redhat.com_mongodbatlasinventories.yaml new file mode 100644 index 0000000000..f251e92ffd --- /dev/null +++ b/deploy/crds/dbaas.redhat.com_mongodbatlasinventories.yaml @@ -0,0 +1,167 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: mongodbatlasinventories.dbaas.redhat.com +spec: + group: dbaas.redhat.com + names: + kind: MongoDBAtlasInventory + listKind: MongoDBAtlasInventoryList + plural: mongodbatlasinventories + singular: mongodbatlasinventory + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DBaaSInventorySpec defines the Inventory Spec to be used + by provider operators + properties: + credentialsRef: + description: The Secret containing the provider-specific connection + credentials to use with its API endpoint. The format of the Secret + is specified in the provider’s operator in its DBaaSProvider CR + (CredentialFields key). It is recommended to place the Secret in + a namespace with limited accessibility. + properties: + name: + description: The name for object of known type + type: string + namespace: + description: The namespace where object of known type is stored + type: string + required: + - name + type: object + required: + - credentialsRef + type: object + status: + description: DBaaSInventoryStatus defines the Inventory status to be used + by provider operators + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + instances: + description: A list of instances returned from querying the DB provider + items: + properties: + instanceID: + description: A provider-specific identifier for this instance + in the database service. It may contain one or more pieces + of information used by the provider operator to identify the + instance on the database service. + type: string + instanceInfo: + additionalProperties: + type: string + description: Any other provider-specific information related + to this instance + type: object + name: + description: The name of this instance in the database service + type: string + required: + - instanceID + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/go.mod b/go.mod index 88fc525780..6ce4199ed4 100644 --- a/go.mod +++ b/go.mod @@ -7,13 +7,16 @@ require ( github.com/Azure/go-autorest/autorest v0.11.24 github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 github.com/Azure/go-autorest/autorest/to v0.4.0 + github.com/RHEcosystemAppEng/dbaas-operator v1.0.1-0.20220829191729-018de64ac56f github.com/aws/aws-sdk-go v1.44.16 github.com/fatih/structtag v1.2.0 + github.com/fgrosse/zaptest v1.1.0 github.com/go-logr/zapr v1.2.3 github.com/google/go-cmp v0.5.7 + github.com/google/uuid v1.3.0 + github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-multierror v1.1.1 github.com/mongodb-forks/digest v1.0.4 - github.com/mxschmitt/playwright-go v0.1400.0 github.com/onsi/ginkgo/v2 v2.1.4 github.com/onsi/gomega v1.19.0 github.com/pborman/uuid v1.2.1 @@ -22,12 +25,14 @@ require ( go.mongodb.org/atlas v0.16.0 go.mongodb.org/mongo-driver v1.8.3 go.uber.org/zap v1.21.0 + golang.org/x/text v0.3.7 google.golang.org/api v0.70.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.23.4 - k8s.io/apimachinery v0.23.4 - k8s.io/client-go v0.23.4 - sigs.k8s.io/controller-runtime v0.11.1 + k8s.io/api v0.23.5 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 + k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 + sigs.k8s.io/controller-runtime v0.11.2 ) require ( @@ -41,7 +46,6 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect @@ -55,10 +59,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/gnostic v0.5.5 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -80,7 +81,6 @@ require ( github.com/xdg-go/scram v1.1.0 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect - go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect @@ -89,23 +89,21 @@ require ( golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf // indirect - google.golang.org/grpc v1.44.0 // indirect google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.23.4 // indirect - k8s.io/component-base v0.23.4 // indirect + k8s.io/apiextensions-apiserver v0.23.5 // indirect + k8s.io/component-base v0.23.5 // indirect k8s.io/klog/v2 v2.40.1 // indirect k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/RHEcosystemAppEng/dbaas-operator => github.com/xieshenzh/dbaas-operator v1.0.1-0.20220907182015-12def45fad1d diff --git a/go.sum b/go.sum index f61819b490..02b4ca87aa 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,19 @@ +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.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= 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.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= @@ -29,11 +34,19 @@ cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2Z cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +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/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/bigtable v1.3.0/go.mod h1:z5EyKrPE8OQmeg4h5MNdKvuSnI9CCT49Ki3f23aBzio= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= @@ -46,81 +59,227 @@ cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v58.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v66.0.0+incompatible h1:bmmC38SlE8/E81nNADlgmVGurPWMHDX2YNXVQMrBpEE= github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.21/go.mod h1:Do/yuMSW/13ayUkcVREpsMHGG+MvV81uzSCFgYPj4tM= github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHqeUGso5qm2BqqE= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.16/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= +github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A= github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 h1:P6bYXFoao05z5uhOQzbC3Qd8JqF3jUoocoTeIxkp2cA= github.com/Azure/go-autorest/autorest/azure/auth v0.5.11/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/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/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.16.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= +github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= 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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/RHsyseng/operator-utils v1.4.9/go.mod h1:LjFIMqr7OOliHrRz1sqqFvHbdqsNlxZkSbK1cfOWinQ= +github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= +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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +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/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apache/arrow/go/arrow v0.0.0-20200601151325-b2287a20f230/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0= +github.com/apache/arrow/go/arrow v0.0.0-20200923215132-ac86123a3f01/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.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.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= 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/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +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-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/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.29.16/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= +github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.40.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.41.7/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go v1.44.16 h1:6voHuNZZNWo71MdNlym4eRlcogTeTSk9Ipo6qDJWzoU= github.com/aws/aws-sdk-go v1.44.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= +github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +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/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bonitoo-io/go-sql-bigquery v0.3.4-1.4.0/go.mod h1:J4Y6YJm0qTWB9aFziB7cPeSyc6dOZFyJdteSeybVpXQ= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/c-bata/go-prompt v0.2.4-0.20200321140817-d043be076398/go.mod h1:Fd2OKZ3h6UdKxcSflqFDkUpTbTKwrtLbvtCp3eVuTEs= +github.com/cactus/go-statsd-client/statsd v0.0.0-20191106001114-12b4e2b38748/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= 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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= 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/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +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/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -130,33 +289,169 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/containerd v1.2.10/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.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= +github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= +github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= +github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= +github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +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/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= -github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= 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/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= +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/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= 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/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.69.1/go.mod h1:epPuOzTOOJujNo0nduDj2D5O1zu8cSpp9R+DdN0W9I0= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +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/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/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/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -164,70 +459,271 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.9/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.1/go.mod h1:txg5va2Qkip90uYoSKH+nkAAmXrb2j3iq4FLwdrCbXQ= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fgrosse/zaptest v1.1.0 h1:sK9hP0/xBoNX5qfFo3KWFluDXfc809APomI1QXuYELA= +github.com/fgrosse/zaptest v1.1.0/go.mod h1:vMnRSul6kW7kIUXZgnZZcDwyTn8k49ODfAULL8nmL5w= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/foxcpp/go-mockdns v0.0.0-20201212160233-ede2f9158d15/go.mod h1:tPg4cp4nseejPd+UKxtCVQ2hUxNTZ7qQZJa7CLriIeo= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +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/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= +github.com/go-chi/chi v4.1.0+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/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.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= +github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/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/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/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/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= +github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.19.29/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= +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.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.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.7/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.9/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= +github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/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/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.20.3/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +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.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/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.5/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.5/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/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-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-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.11/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= +github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +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/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.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= +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/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -239,6 +735,7 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -257,21 +754,26 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 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/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -280,6 +782,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -295,6 +798,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -305,9 +809,15 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +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.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -315,109 +825,276 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +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.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss= +github.com/gophercloud/gophercloud v0.22.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +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.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= 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/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= 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/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= 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/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= 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-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/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-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +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.2/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.2.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/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= 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.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hetznercloud/hcloud-go v1.32.0/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME= +github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/flux v0.65.0/go.mod h1:BwN2XG2lMszOoquQaFdPET8FRQfrXiZsWmcMO9rkaVY= +github.com/influxdata/flux v0.131.0/go.mod h1:CKvnYe6FHpTj/E0YGI7TcOZdGiYHoToOPSnoa12RtKI= +github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69/go.mod h1:pwymjR6SrP3gD3pRj9RJwdl1j5s3doEEV8gS4X9qSzA= +github.com/influxdata/influxdb v1.8.0/go.mod h1:SIzcnsjaHRFpmlxpJ4S3NT64qtEKYweNTUMb/vh0OMQ= +github.com/influxdata/influxdb v1.9.5/go.mod h1:4uPVvcry9KWQVWLxyT9641qpkRXUBN+xa0MJFFNNLKo= +github.com/influxdata/influxdb-client-go/v2 v2.3.1-0.20210518120617-5d1fff431040/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxql v1.1.0/go.mod h1:KpVI7okXjK6PRi3Z5B+mtKZli+R1DnZgb3N+tzevNgo= +github.com/influxdata/influxql v1.1.1-0.20210223160523-b6ab99450c93/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/pkg-config v0.2.8/go.mod h1:EMS7Ll0S4qkzDk53XS3Z72/egBsPInt+BeRxb0WeSwk= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/tdigest v0.0.2-0.20210216194612-fc98d27c9e8b/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +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/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +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/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 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/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/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/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= +github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3TDYCcsFy9hpqb0= 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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +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/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4= github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.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.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linode/linodego v1.1.0/go.mod h1:x/7+BoaKd4unViBmS2umdjYyVAmpFtBtEXZ0wou7FYQ= +github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= +github.com/lyft/protoc-gen-star v0.5.1/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +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/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 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-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +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.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +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.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37/go.mod h1:dYWq+UWoFCDY1TndvFUQuhBbIYmZpjreC8adEAx93zE= +github.com/mileusna/useragent v0.0.0-20190129205925-3e331f0949a5/go.mod h1:JWhYAp2EXqUtsxTKdeGlY8Wp44M7VxThC9FEoNGi2IE= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= 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-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/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 v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= 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= @@ -428,119 +1105,294 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mongodb-forks/digest v1.0.4 h1:9FrGTc7MGAchgaQBcXBnEwUM/Oo8obW7OGWxnsSvZ64= github.com/mongodb-forks/digest v1.0.4/go.mod h1:eHRfgovT+dvSFfltrOa27hy1oR/rcwyDdp5H1ZQxEMA= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= 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/mxschmitt/playwright-go v0.1400.0 h1:HL8dbxcVEobE+pNjASeYGJJRmd4+9gyu/51XO7d3qF0= -github.com/mxschmitt/playwright-go v0.1400.0/go.mod h1:kUvZFgMneRGknVLtC2DKQ42lhZiCmWzxgBdGwjC0vkw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= 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/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.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/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +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/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +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/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/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/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/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/openlyinc/pointy v1.1.2 h1:LywVV2BWC5Sp5v7FoP4bUD+2Yn5k0VNeRbU5vq9jUMY= github.com/openlyinc/pointy v1.1.2/go.mod h1:w2Sytx+0FVuMKn37xpXIAyBNhFNBIJGR/v2m7ik1WtM= +github.com/openshift/api v0.0.0-20210521075222-e273a339932a/go.mod h1:izBmoXbUu3z5kUa4FjZhvekTsyzIWiOoaIgJiZBBMQs= +github.com/openshift/api v0.0.0-20210910062324-a41d3573a3ba/go.mod h1:izBmoXbUu3z5kUa4FjZhvekTsyzIWiOoaIgJiZBBMQs= +github.com/openshift/build-machinery-go v0.0.0-20210423112049-9415d7ebd33e/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142/go.mod h1:fjS8r9mqDVsPb5td3NehsNOAWa4uiFkYEfVZioQ2gH0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= +github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= +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.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/operator-framework/api v0.10.5/go.mod h1:tV0BUNvly7szq28ZPBXhjp1Sqg5yHCOeX19ui9K4vjI= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 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/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= 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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03/go.mod h1:Z9+Ul5bCbBKnbCvdOWbLqTHhJiYV414CURZJba6L8qA= 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/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.50.0/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.57.0/go.mod h1:tflNO6iwG09icVcOe2VfhC73fmtKSKT1aNXYnVtAumU= +github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= +github.com/prometheus/alertmanager v0.23.0/go.mod h1:0MLTrjQI8EuVmvykEhcfr/7X0xmaDAZrqMgxIq3OXHk= +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.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/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.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/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +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/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= +github.com/prometheus/exporter-toolkit v0.6.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= +github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= +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-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 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/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.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/prometheus v0.0.0-20200609090129-a6600f564e3c/go.mod h1:S5n0C6tSgdnwWshBUceRx5G1OsjLv/EeZ9t3wIfEtsY= +github.com/prometheus/prometheus v1.8.2-0.20211105201321-411021ada9ab/go.mod h1:ZJuc8Ryf9icwMGB68aSEfw2YVSWuY3Ljrl/WCVqXeYc= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rhobs/observability-operator v0.0.13/go.mod h1:RsOqxJs3KZL7bD0Kaq5R9Opsh+9c7aoVILiXXigrztc= 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.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= +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/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +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/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= +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-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/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.6/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/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/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/snowflakedb/gosnowflake v1.3.13/go.mod h1:6nfka9aTXkUNha1p1cjeeyjDvcyh7jfjp0l8kGpDBok= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= 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.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag 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/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -551,10 +1403,49 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +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/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber-go/tally v3.3.15+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= +github.com/uber/athenadriver v1.1.4/go.mod h1:tQjho4NzXw55LGfSZEcETuYydpY1vtmixUabHkC1K/E= +github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +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/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= @@ -562,7 +1453,19 @@ github.com/xdg-go/scram v1.1.0 h1:d70R37I0HrDLsafRrMBXyrD4lmQbCHE873t00Vr0gm0= github.com/xdg-go/scram v1.1.0/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/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/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xieshenzh/dbaas-operator v1.0.1-0.20220907182015-12def45fad1d h1:tcEA7bSl8tdgl7JBmpCWCBoQKA7f2ajEj42Regxu5oQ= +github.com/xieshenzh/dbaas-operator v1.0.1-0.20220907182015-12def45fad1d/go.mod h1:5yvviv5SMNVM9Ns9Y3xMaBrzb7EgMfq5uROehQ+R7/Y= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= @@ -573,8 +1476,15 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +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/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= @@ -584,8 +1494,21 @@ go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD0 go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.mongodb.org/atlas v0.16.0 h1:IqnDuK3XAZUgJ5lPHc4v4z4B8F6mvsS37O4ck7tOYVc= go.mongodb.org/atlas v0.16.0/go.mod h1:lQhRHIxc6jQHEK3/q9WLu/SdBkPj2fQYhjLGUF6Z3U8= +go.mongodb.org/mongo-driver v1.0.3/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.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.2/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -606,7 +1529,12 @@ go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -616,32 +1544,76 @@ go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.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/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/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-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-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-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-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-20190701094942-4def268fd1a4/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -651,6 +1623,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 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= @@ -663,6 +1636,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= @@ -673,29 +1647,44 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/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-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +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-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -703,29 +1692,40 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL 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/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-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -737,6 +1737,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -748,6 +1750,7 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= @@ -755,6 +1758,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -763,6 +1767,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180620133508-ad87a3a340fa/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -770,53 +1776,103 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h 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-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-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-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-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/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-20190626150813-e07cf5db2756/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-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -830,10 +1886,13 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -845,10 +1904,15 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -859,33 +1923,52 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/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-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-20190114222345-bf090417da8b/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= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-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-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-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-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-20190920225731-5eefd052ad72/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-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -893,8 +1976,12 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn 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-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -903,15 +1990,21 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304024140-c4206d458c3f/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200721032237-77f530d86f9a/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -929,6 +2022,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 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= @@ -937,6 +2031,15 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +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.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= @@ -948,6 +2051,8 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= @@ -967,12 +2072,14 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6 google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0 h1:67zQnAE0T2rB0A3CwLSas0K+SbVzSxP+zTLkQLexeiw= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -980,33 +2087,45 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/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-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-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +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-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200420144010-e5e8543f8aeb/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1015,6 +2134,7 @@ google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1039,6 +2159,8 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= @@ -1048,15 +2170,23 @@ google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf h1:SVYXkUz2yZS9FWb2Gm8ivSlbNQzL2Z/NpPKE3RG2jWk= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= 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.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/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= @@ -1091,42 +2221,60 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 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.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.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/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/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/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 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.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.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/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= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +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= @@ -1134,54 +2282,173 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg= -k8s.io/api v0.23.4 h1:85gnfXQOWbJa1SiWGpE9EEtHs0UVvDyIsSMpEtl2D4E= -k8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI= -k8s.io/apiextensions-apiserver v0.23.0/go.mod h1:xIFAEEDlAZgpVBl/1VSjGDmLoXAWRG40+GsWhKhAxY4= -k8s.io/apiextensions-apiserver v0.23.4 h1:AFDUEu/yEf0YnuZhqhIFhPLPhhcQQVuR1u3WCh0rveU= -k8s.io/apiextensions-apiserver v0.23.4/go.mod h1:TWYAKymJx7nLMxWCgWm2RYGXHrGlVZnxIlGnvtfYu+g= -k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc= -k8s.io/apimachinery v0.23.4 h1:fhnuMd/xUL3Cjfl64j5ULKZ1/J9n8NuQEgNL+WXWfdM= -k8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apiserver v0.23.0/go.mod h1:Cec35u/9zAepDPPFyT+UMrgqOCjgJ5qtfVJDxjZYmt4= -k8s.io/apiserver v0.23.4/go.mod h1:A6l/ZcNtxGfPSqbFDoxxOjEjSKBaQmE+UTveOmMkpNc= -k8s.io/client-go v0.23.0/go.mod h1:hrDnpnK1mSr65lHHcUuIZIXDgEbzc7/683c6hyG4jTA= -k8s.io/client-go v0.23.4 h1:YVWvPeerA2gpUudLelvsolzH7c2sFoXXR5wM/sWqNFU= -k8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0= -k8s.io/code-generator v0.23.0/go.mod h1:vQvOhDXhuzqiVfM/YHp+dmg10WDZCchJVObc9MvowsE= -k8s.io/code-generator v0.23.4/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= -k8s.io/component-base v0.23.0/go.mod h1:DHH5uiFvLC1edCpvcTDV++NKULdYYU6pR9Tt3HIKMKI= -k8s.io/component-base v0.23.4 h1:SziYh48+QKxK+ykJ3Ejqd98XdZIseVBG7sBaNLPqy6M= -k8s.io/component-base v0.23.4/go.mod h1:8o3Gg8i2vnUXGPOwciiYlkSaZT+p+7gA9Scoz8y4W4E= +k8s.io/api v0.17.5/go.mod h1:0zV5/ungglgy2Rlm3QK8fbxkXVs+BSJWpJP/+8gUVLY= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= +k8s.io/api v0.22.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU= +k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= +k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= +k8s.io/api v0.23.5 h1:zno3LUiMubxD/V1Zw3ijyKO3wxrhbUF1Ck+VjBvfaoA= +k8s.io/api v0.23.5 h1:zno3LUiMubxD/V1Zw3ijyKO3wxrhbUF1Ck+VjBvfaoA= +k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= +k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= +k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= +k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= +k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c= +k8s.io/apiextensions-apiserver v0.23.5 h1:5SKzdXyvIJKu+zbfPc3kCbWpbxi+O+zdmAJBm26UJqI= +k8s.io/apiextensions-apiserver v0.23.5 h1:5SKzdXyvIJKu+zbfPc3kCbWpbxi+O+zdmAJBm26UJqI= +k8s.io/apiextensions-apiserver v0.23.5/go.mod h1:ntcPWNXS8ZPKN+zTXuzYMeg731CP0heCTl6gYBxLcuQ= +k8s.io/apiextensions-apiserver v0.23.5/go.mod h1:ntcPWNXS8ZPKN+zTXuzYMeg731CP0heCTl6gYBxLcuQ= +k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= +k8s.io/apimachinery v0.22.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.23.5 h1:Va7dwhp8wgkUPWsEXk6XglXWU4IKYLKNlv8VkX7SDM0= +k8s.io/apimachinery v0.23.5 h1:Va7dwhp8wgkUPWsEXk6XglXWU4IKYLKNlv8VkX7SDM0= +k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= +k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400= +k8s.io/apiserver v0.23.5/go.mod h1:7wvMtGJ42VRxzgVI7jkbKvMbuCbVbgsWFT7RyXiRNTw= +k8s.io/apiserver v0.23.5/go.mod h1:7wvMtGJ42VRxzgVI7jkbKvMbuCbVbgsWFT7RyXiRNTw= +k8s.io/cli-runtime v0.22.0/go.mod h1:An6zELQ7udUI0GaXvkuMqyopPA14dIgNqpH8cZu1vig= +k8s.io/client-go v0.17.5/go.mod h1:S8uZpBpjJJdEH/fEyxcqg7Rn0P5jH+ilkgBHjriSmNo= +k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= +k8s.io/client-go v0.22.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg= +k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= +k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= +k8s.io/client-go v0.23.5 h1:zUXHmEuqx0RY4+CsnkOn5l0GU+skkRXKGJrhmE2SLd8= +k8s.io/client-go v0.23.5 h1:zUXHmEuqx0RY4+CsnkOn5l0GU+skkRXKGJrhmE2SLd8= +k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= +k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= +k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= +k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= +k8s.io/code-generator v0.23.5/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= +k8s.io/code-generator v0.23.5/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= +k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= +k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo= +k8s.io/component-base v0.23.5 h1:8qgP5R6jG1BBSXmRYW+dsmitIrpk8F/fPEvgDenMCCE= +k8s.io/component-base v0.23.5 h1:8qgP5R6jG1BBSXmRYW+dsmitIrpk8F/fPEvgDenMCCE= +k8s.io/component-base v0.23.5/go.mod h1:c5Nq44KZyt1aLl0IpHX82fhsn84Sb0jjzwjpcA42bY0= +k8s.io/component-base v0.23.5/go.mod h1:c5Nq44KZyt1aLl0IpHX82fhsn84Sb0jjzwjpcA42bY0= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +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-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +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 v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.20.0/go.mod h1:Gm8eSIfQN6457haJuPaMxZw4wyP5k+ykPFlrhQDvhvw= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.40.1 h1:P4RRucWk/lFOlDdkAr3mc7iWFkgKrZY9qZMAgek06S4= k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200316234421-82d701f24f9d/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf h1:M9XBsiMslw2lb2ZzglC0TOkBPK5NQi0/noUrdnoFwUg= k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27/go.mod h1:tq2nT0Kx7W+/f2JVE+zxYtUhdjuELJkVpNz+x/QN5R4= -sigs.k8s.io/controller-runtime v0.11.1 h1:7YIHT2QnHJArj/dk9aUkYhfqfK5cIxPOX5gPECfdZLU= -sigs.k8s.io/controller-runtime v0.11.1/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= +sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= +sigs.k8s.io/controller-runtime v0.10.0/go.mod h1:GCdh6kqV6IY4LK0JLwX0Zm6g233RtVGdb/f0+KSfprg= +sigs.k8s.io/controller-runtime v0.11.2 h1:H5GTxQl0Mc9UjRJhORusqfJCIjBO8UtUxGggCwL1rLA= +sigs.k8s.io/controller-runtime v0.11.2 h1:H5GTxQl0Mc9UjRJhORusqfJCIjBO8UtUxGggCwL1rLA= +sigs.k8s.io/controller-runtime v0.11.2/go.mod h1:P6QCzrEjLaZGqHsfd+os7JQ+WFZhvB8MRFsn4dWF7O4= +sigs.k8s.io/controller-runtime v0.11.2/go.mod h1:P6QCzrEjLaZGqHsfd+os7JQ+WFZhvB8MRFsn4dWF7O4= +sigs.k8s.io/controller-tools v0.6.0/go.mod h1:baRMVPrctU77F+rfAuH2uPqW93k6yQnZA2dhUOr7ihc= +sigs.k8s.io/instrumentation-tools v0.0.0-20220105214747-a4543a98c7e8/go.mod h1:gybXrX1QWZIi3rdVvVqrHDpBOb/U2UZEFG7pR4YJe3Y= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= +sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= +sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE= +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/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/pkg/api/dbaas/info.go b/pkg/api/dbaas/info.go new file mode 100644 index 0000000000..4c3a767980 --- /dev/null +++ b/pkg/api/dbaas/info.go @@ -0,0 +1,36 @@ +/* +Copyright 2021 MongoDB. + +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 dbaas contains API Schema definitions for the dbaas.redhat.com v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=dbaas.redhat.com +package dbaas + +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: "dbaas.redhat.com", 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/api/dbaas/mongodbatlasconnection_types.go b/pkg/api/dbaas/mongodbatlasconnection_types.go new file mode 100644 index 0000000000..339459be42 --- /dev/null +++ b/pkg/api/dbaas/mongodbatlasconnection_types.go @@ -0,0 +1,115 @@ +/* +Copyright 2021. +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 dbaas + +import ( + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + CloudProviderKey = "providerName" + CloudRegionKey = "regionName" + ProjectIDKey = "projectID" + ProjectNameKey = "projectName" + ProvisionPhaseKey = "state" + InstanceSizeNameKey = "instanceSizeName" + ClusterNameKey = "clusterName" + + ConnectionStringsStandardSrvKey = "connectionStringsStandardSrv" + InstanceIDKey = "instanceID" + HostKey = "host" + SrvKey = "srv" + ProviderKey = "provider" + Provider = "rhoda/mongodb atlas" + ServiceBindingTypeKey = "type" + ServiceBindingType = "mongodb" + DefaultDatabase = "admin" +) + +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +groupName:=dbaas.redhat.com +// +versionName:=v1alpha1 + +// MongoDBAtlasConnection is the Schema for the MongoDBAtlasConnections API +type MongoDBAtlasConnection struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec dbaasv1alpha1.DBaaSConnectionSpec `json:"spec,omitempty"` + Status dbaasv1alpha1.DBaaSConnectionStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// MongoDBAtlasConnectionList contains a list of MongoDBAtlasConnection +type MongoDBAtlasConnectionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MongoDBAtlasConnection `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MongoDBAtlasConnection{}, &MongoDBAtlasConnectionList{}) +} + +// SetConnectionCondition sets a condition on the status object. If the condition already +// exists, it will be replaced. SetCondition does not update the resource in +// the cluster. +func SetConnectionCondition(conn *MongoDBAtlasConnection, condType string, status metav1.ConditionStatus, reason, msg string) { + now := metav1.Now() + for i := range conn.Status.Conditions { + if conn.Status.Conditions[i].Type == condType { + var lastTransitionTime metav1.Time + if conn.Status.Conditions[i].Status != status { + lastTransitionTime = now + } else { + lastTransitionTime = conn.Status.Conditions[i].LastTransitionTime + } + conn.Status.Conditions[i] = metav1.Condition{ + LastTransitionTime: lastTransitionTime, + Type: condType, + Status: status, + Reason: reason, + Message: msg, + } + return + } + } + + // If the condition does not exist, + // initialize the lastTransitionTime + conn.Status.Conditions = append(conn.Status.Conditions, metav1.Condition{ + LastTransitionTime: now, + Type: condType, + Status: status, + Reason: reason, + Message: msg, + }) +} + +// GetConnectionCondition return the condition with the passed condition type from +// the status object. If the condition is not already present, return nil +func GetConnectionCondition(conn *MongoDBAtlasConnection, condType string) *metav1.Condition { + for i := range conn.Status.Conditions { + if conn.Status.Conditions[i].Type == condType { + return &conn.Status.Conditions[i] + } + } + return nil +} diff --git a/pkg/api/dbaas/mongodbatlasinstance_types.go b/pkg/api/dbaas/mongodbatlasinstance_types.go new file mode 100644 index 0000000000..45e04d4a39 --- /dev/null +++ b/pkg/api/dbaas/mongodbatlasinstance_types.go @@ -0,0 +1,96 @@ +/* +Copyright 2022. +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 dbaas + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +groupName:=dbaas.redhat.com +// +versionName:=v1alpha1 + +// MongoDBAtlasInstance is the Schema for the MongoDBAtlasInstance API +type MongoDBAtlasInstance struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec dbaasv1alpha1.DBaaSInstanceSpec `json:"spec,omitempty"` + Status dbaasv1alpha1.DBaaSInstanceStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// MongoDBAtlasInstanceList contains a list of DBaaSInstances +type MongoDBAtlasInstanceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MongoDBAtlasInstance `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MongoDBAtlasInstance{}, &MongoDBAtlasInstanceList{}) +} + +// +k8s:deepcopy-gen=false + +// SetInstanceCondition sets a condition on the status object. If the condition already +// exists, it will be replaced. SetCondition does not update the resource in +// the cluster. +func SetInstanceCondition(inv *MongoDBAtlasInstance, condType string, status metav1.ConditionStatus, reason, msg string) { + now := metav1.Now() + for i := range inv.Status.Conditions { + if inv.Status.Conditions[i].Type == condType { + var lastTransitionTime metav1.Time + if inv.Status.Conditions[i].Status != status { + lastTransitionTime = now + } else { + lastTransitionTime = inv.Status.Conditions[i].LastTransitionTime + } + inv.Status.Conditions[i] = metav1.Condition{ + LastTransitionTime: lastTransitionTime, + Status: status, + Type: condType, + Reason: reason, + Message: msg, + } + return + } + } + + // If the condition does not exist, + // initialize the lastTransitionTime + inv.Status.Conditions = append(inv.Status.Conditions, metav1.Condition{ + LastTransitionTime: now, + Type: condType, + Status: status, + Reason: reason, + Message: msg, + }) +} + +// GetInstanceCondition return the condition with the passed condition type from +// the status object. If the condition is not already present, return nil +func GetInstanceCondition(inv *MongoDBAtlasInstance, condType string) *metav1.Condition { + for i := range inv.Status.Conditions { + if inv.Status.Conditions[i].Type == condType { + return &inv.Status.Conditions[i] + } + } + return nil +} diff --git a/pkg/api/dbaas/mongodbatlasinventory_types.go b/pkg/api/dbaas/mongodbatlasinventory_types.go new file mode 100644 index 0000000000..12f2dca917 --- /dev/null +++ b/pkg/api/dbaas/mongodbatlasinventory_types.go @@ -0,0 +1,107 @@ +/* +Copyright 2021. +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 dbaas + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + + kube "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +groupName:=dbaas.redhat.com +// +versionName:=v1alpha1 + +// MongoDBAtlasInventory is the Schema for the MongoDBAtlasInventory API +type MongoDBAtlasInventory struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec dbaasv1alpha1.DBaaSInventorySpec `json:"spec,omitempty"` + Status dbaasv1alpha1.DBaaSInventoryStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// MongoDBAtlasInventoryList contains a list of DBaaSInventories +type MongoDBAtlasInventoryList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MongoDBAtlasInventory `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MongoDBAtlasInventory{}, &MongoDBAtlasInventoryList{}) +} + +func (p *MongoDBAtlasInventory) ConnectionSecretObjectKey() *client.ObjectKey { + if p.Spec.CredentialsRef != nil { + key := kube.ObjectKey(p.Namespace, p.Spec.CredentialsRef.Name) + return &key + } + return nil +} + +// +k8s:deepcopy-gen=false + +// SetInventoryCondition sets a condition on the status object. If the condition already +// exists, it will be replaced. SetCondition does not update the resource in +// the cluster. +func SetInventoryCondition(inv *MongoDBAtlasInventory, condType string, status metav1.ConditionStatus, reason, msg string) { + now := metav1.Now() + for i := range inv.Status.Conditions { + if inv.Status.Conditions[i].Type == condType { + var lastTransitionTime metav1.Time + if inv.Status.Conditions[i].Status != status { + lastTransitionTime = now + } else { + lastTransitionTime = inv.Status.Conditions[i].LastTransitionTime + } + inv.Status.Conditions[i] = metav1.Condition{ + LastTransitionTime: lastTransitionTime, + Status: status, + Type: condType, + Reason: reason, + Message: msg, + } + return + } + } + + // If the condition does not exist, + // initialize the lastTransitionTime + inv.Status.Conditions = append(inv.Status.Conditions, metav1.Condition{ + LastTransitionTime: now, + Type: condType, + Status: status, + Reason: reason, + Message: msg, + }) +} + +// GetInventoryCondition return the condition with the passed condition type from +// the status object. If the condition is not already present, return nil +func GetInventoryCondition(inv *MongoDBAtlasInventory, condType string) *metav1.Condition { + for i := range inv.Status.Conditions { + if inv.Status.Conditions[i].Type == condType { + return &inv.Status.Conditions[i] + } + } + return nil +} diff --git a/pkg/api/dbaas/zz_generated.deepcopy.go b/pkg/api/dbaas/zz_generated.deepcopy.go new file mode 100644 index 0000000000..83be9ecef3 --- /dev/null +++ b/pkg/api/dbaas/zz_generated.deepcopy.go @@ -0,0 +1,195 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright (C) MongoDB, Inc. 2020-present. + +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 +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package dbaas + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasConnection) DeepCopyInto(out *MongoDBAtlasConnection) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasConnection. +func (in *MongoDBAtlasConnection) DeepCopy() *MongoDBAtlasConnection { + if in == nil { + return nil + } + out := new(MongoDBAtlasConnection) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasConnection) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasConnectionList) DeepCopyInto(out *MongoDBAtlasConnectionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MongoDBAtlasConnection, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasConnectionList. +func (in *MongoDBAtlasConnectionList) DeepCopy() *MongoDBAtlasConnectionList { + if in == nil { + return nil + } + out := new(MongoDBAtlasConnectionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasConnectionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasInstance) DeepCopyInto(out *MongoDBAtlasInstance) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasInstance. +func (in *MongoDBAtlasInstance) DeepCopy() *MongoDBAtlasInstance { + if in == nil { + return nil + } + out := new(MongoDBAtlasInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasInstance) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasInstanceList) DeepCopyInto(out *MongoDBAtlasInstanceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MongoDBAtlasInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasInstanceList. +func (in *MongoDBAtlasInstanceList) DeepCopy() *MongoDBAtlasInstanceList { + if in == nil { + return nil + } + out := new(MongoDBAtlasInstanceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasInstanceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasInventory) DeepCopyInto(out *MongoDBAtlasInventory) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasInventory. +func (in *MongoDBAtlasInventory) DeepCopy() *MongoDBAtlasInventory { + if in == nil { + return nil + } + out := new(MongoDBAtlasInventory) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasInventory) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MongoDBAtlasInventoryList) DeepCopyInto(out *MongoDBAtlasInventoryList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MongoDBAtlasInventory, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MongoDBAtlasInventoryList. +func (in *MongoDBAtlasInventoryList) DeepCopy() *MongoDBAtlasInventoryList { + if in == nil { + return nil + } + out := new(MongoDBAtlasInventoryList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MongoDBAtlasInventoryList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/pkg/api/v1/atlasproject_types.go b/pkg/api/v1/atlasproject_types.go index c1ad7d2833..6d33685463 100644 --- a/pkg/api/v1/atlasproject_types.go +++ b/pkg/api/v1/atlasproject_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -141,6 +142,43 @@ func (p *AtlasProject) X509SecretObjectKey() *client.ObjectKey { return nil } +func (p *AtlasProject) GetCondition(condType status.ConditionType) *status.Condition { + for _, cond := range p.Status.Conditions { + if cond.Type == condType { + return &cond + } + } + return nil +} + +// CheckConditions check AtlasProject conditions +// First check if ReadyType condition exists and is True +// Then check if a condition of ProjectReadyType, DeploymentReadyType, IPAccessListReadyType or PrivateEndpointReadyType condition exists and is False +// returns nil otherwise +func (p *AtlasProject) CheckConditions() *status.Condition { + cond := p.GetCondition(status.ReadyType) + if cond != nil && cond.Status == corev1.ConditionTrue { + return cond + } + cond = p.GetCondition(status.ProjectReadyType) + if cond != nil && cond.Status == corev1.ConditionFalse { + return cond + } + cond = p.GetCondition(status.DeploymentReadyType) + if cond != nil && cond.Status == corev1.ConditionFalse { + return cond + } + cond = p.GetCondition(status.IPAccessListReadyType) + if cond != nil && cond.Status == corev1.ConditionFalse { + return cond + } + cond = p.GetCondition(status.PrivateEndpointReadyType) + if cond != nil && cond.Status == corev1.ConditionFalse { + return cond + } + return nil +} + // ************************************ Builder methods ************************************************* func NewProject(namespace, name, nameInAtlas string) *AtlasProject { diff --git a/pkg/api/v1/status/condition.go b/pkg/api/v1/status/condition.go index e232384e18..ea2b2e797e 100644 --- a/pkg/api/v1/status/condition.go +++ b/pkg/api/v1/status/condition.go @@ -54,6 +54,11 @@ const ( DatabaseUserReadyType ConditionType = "DatabaseUserReady" ) +// MongoDBAtlasInstanceInventoryUpdateFail condition reason +const ( + MongoDBAtlasInstanceInventoryUpdateFail string = "Fail to update inventory" +) + // Condition describes the state of an Atlas Custom Resource at a certain point. type Condition struct { // Type of Atlas Custom Resource condition. diff --git a/pkg/controller/atlas/client.go b/pkg/controller/atlas/client.go index 9055d3e180..378f4e5583 100644 --- a/pkg/controller/atlas/client.go +++ b/pkg/controller/atlas/client.go @@ -28,7 +28,7 @@ func Client(atlasDomain string, connection Connection, log *zap.SugaredLogger) ( if err != nil { return mongodbatlas.Client{}, err } - client.UserAgent = fmt.Sprintf("%s/%s (%s;%s)", "MongoDBAtlasKubernetesOperator", ProductVersion, runtime.GOOS, runtime.GOARCH) + client.UserAgent = fmt.Sprintf("%s/%s (%s;%s)", "MongoDBAtlasKubernetesOperatorRHODA", ProductVersion, runtime.GOOS, runtime.GOARCH) return *client, nil } diff --git a/pkg/controller/atlas/client_test.go b/pkg/controller/atlas/client_test.go index 63b2325171..235d00deee 100644 --- a/pkg/controller/atlas/client_test.go +++ b/pkg/controller/atlas/client_test.go @@ -14,5 +14,5 @@ func TestClientUserAgent(t *testing.T) { atlas.ProductVersion = "v1.2.3-testing" c, err := atlas.Client("https://cloud.mongodb.com", atlas.Connection{}, nil) require.NoError(err) - require.Regexp(`^MongoDBAtlasKubernetesOperator/v1\.2\.3-testing \(\w+;\w+\)$`, c.UserAgent) + require.Regexp(`^MongoDBAtlasKubernetesOperatorRHODA/v1\.2\.3-testing \(\w+;\w+\)$`, c.UserAgent) } diff --git a/pkg/controller/atlasconnection/atlasconnection_controller.go b/pkg/controller/atlasconnection/atlasconnection_controller.go new file mode 100644 index 0000000000..a2596bc4aa --- /dev/null +++ b/pkg/controller/atlasconnection/atlasconnection_controller.go @@ -0,0 +1,442 @@ +/* +Copyright 2021 MongoDB. + +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 atlasconnection + +import ( + "context" + cryptorand "crypto/rand" + "errors" + "fmt" + "math/big" + "math/rand" + "strings" + "time" + + "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + + apiErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/record" + ptr "k8s.io/utils/pointer" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/source" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.mongodb.org/atlas/mongodbatlas" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube" +) + +const ( + DBUserNameKey = "username" + DBPasswordKey = "password" + digits = "0123456789" + specials = "~=+%^*/()[]{}/!@#$?|" + all = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + digits + specials +) + +// MongoDBAtlasConnectionReconciler reconciles a MongoDBAtlasConnection object +type MongoDBAtlasConnectionReconciler struct { + Client client.Client + Clientset kubernetes.Interface + AtlasClient *mongodbatlas.Client + watch.ResourceWatcher + Log *zap.SugaredLogger + Scheme *runtime.Scheme + AtlasDomain string + GlobalAPISecret client.ObjectKey + EventRecorder record.EventRecorder +} + +// Dev note: duplicate the permissions in both sections below to generate both Role and ClusterRoles + +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasconnections,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasconnections/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch + +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasconnections,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasconnections/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",namespace=default,resources=secrets,verbs=get;list;watch + +func (r *MongoDBAtlasConnectionReconciler) Reconcile(cx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = cx + log := r.Log.With("MongoDBAtlasConnection", req.NamespacedName) + + conn := &dbaas.MongoDBAtlasConnection{} + if err := r.Client.Get(cx, req.NamespacedName, conn); err != nil { + if apiErrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("MongoDBAtlasConnection resource not found, has been deleted") + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching MongoDBAtlasConnection for reconcile") + return ctrl.Result{}, err + } + + if isReadyForBinding(conn) && conn.Status.Binding != nil { + // For this release, the InstanceID is mutable, so no reconciliation is needed. + return ctrl.Result{}, nil + } + + // This update will make sure the status is always updated in case of any errors or successful result + defer func(c *dbaas.MongoDBAtlasConnection) { + err := r.Client.Status().Update(cx, c) + if err != nil { + log.Infof("Could not update resource status:%v", err) + } + }(conn) + + inventory := &dbaas.MongoDBAtlasInventory{} + namespace := conn.Spec.InventoryRef.Namespace + if len(namespace) == 0 { + // Namespace is not populated in InventoryRef, default to the request's namespace + namespace = req.Namespace + } + if err := r.Client.Get(cx, types.NamespacedName{Namespace: namespace, Name: conn.Spec.InventoryRef.Name}, inventory); err != nil { + if apiErrors.IsNotFound(err) { + // The corresponding inventory is not found, no reqeue. + log.Info("MongoDBAtlasInventory resource not found, has been deleted") + result := workflow.InProgress(workflow.MongoDBAtlasConnectionInventoryNotFound, "inventory not found") + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching MongoDBAtlasInventory") + return ctrl.Result{}, err + } + + if !isInventoryReady(inventory) { + // The corresponding inventory is not ready yet, requeue + result := workflow.InProgress(workflow.MongoDBAtlasConnectionInventoryNotReady, "inventory not ready") + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + // Requeue + return result.ReconcileResult(), errors.New("inventory not ready") + } + + // Retrieve the instance from inventory based on instanceID + instance := getInstance(inventory, conn.Spec.InstanceID) + if instance == nil { + result := workflow.Terminate(workflow.MongoDBAtlasConnectionInstanceIDNotFound, "Atlas database instance not found") + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + // No further reconciliation needed + return result.ReconcileResult(), nil + } + + projectID := instance.InstanceInfo[dbaas.ProjectIDKey] + + if conn.Status.Binding == nil { + // Generate a db username and password + dbUserName := fmt.Sprintf("atlas-db-user-%v", time.Now().UnixNano()) + dbPassword := generatePassword() + // Create the db user in Atlas + res, err := r.createDBUserInAtlas(conn, projectID, dbUserName, dbPassword, inventory, log) + if err != nil { + return res, err + } + + // Now create a secret to store the password locally + secret := getOwnedSecret(conn, dbUserName, dbPassword, instance.InstanceInfo[dbaas.ConnectionStringsStandardSrvKey]) + secretCreated, err := r.Clientset.CoreV1().Secrets(req.Namespace).Create(context.Background(), secret, metav1.CreateOptions{}) + if err != nil { + // Clean up the db user in atlas that was just created + _ = r.deleteDBUserFromAtlas(instance.InstanceInfo[dbaas.ProjectIDKey], dbUserName, inventory, log) + result := workflow.Terminate(workflow.MongoDBAtlasConnectionBackendError, err.Error()) + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return ctrl.Result{}, fmt.Errorf("failed to create secret:%w", err) + } + conn.Status.Binding = &corev1.LocalObjectReference{Name: secretCreated.Name} + } + + // Update the status + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionTrue, "Ready", "") + return ctrl.Result{}, nil +} + +func (r *MongoDBAtlasConnectionReconciler) SetupWithManager(mgr ctrl.Manager) error { + c, err := controller.New("MongoDBAtlasConnection", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource MongoDBAtlasConnection & handle delete separately + err = c.Watch(&source.Kind{Type: &dbaas.MongoDBAtlasConnection{}}, &watch.EventHandlerWithDelete{Controller: r}, watch.CommonPredicates()) + if err != nil { + return err + } + + // Watch for Connection Secrets + err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, watch.NewSecretHandler(r.WatchedResources)) + if err != nil { + return err + } + return nil +} + +// Delete implements a handler for the Delete event. +func (r *MongoDBAtlasConnectionReconciler) Delete(e event.DeleteEvent) error { + conn, ok := e.Object.(*dbaas.MongoDBAtlasConnection) + if !ok { + r.Log.Errorf("Ignoring malformed Delete() call (expected type %T, got %T)", &dbaas.MongoDBAtlasConnection{}, e.Object) + return nil + } + log := r.Log.With("MongoDBAtlasConnection", kube.ObjectKeyFromObject(conn)) + log.Infow("-> Starting MongoDBAtlasConnection deletion", "spec", conn.Spec) + _ = r.deleteDBUser(conn, log) + return nil +} + +func (r *MongoDBAtlasConnectionReconciler) deleteDBUser(conn *dbaas.MongoDBAtlasConnection, log *zap.SugaredLogger) error { + if conn.Status.Binding == nil { + log.Infow("No credentialsRef provided. Nothing to delete.") + return nil + } + secret, err := r.getSecret(conn.Namespace, conn.Status.Binding.Name) + if err != nil { + if apiErrors.IsNotFound(err) { + log.Infow("No secret found for db user credentials. Deletion done.") + return nil + } + return err // For retry + } + + // Retrieve the db username from the secret + dbUserName := "" + dbUser, ok := secret.Data[DBUserNameKey] + if !ok { + log.Infow("No db usernmae found for deletion. Deletion done.") + return nil + } + dbUserName = string(dbUser) + + // The corresponding inventory and instanceID in the Spec are immutable, so we can determine the + // project ID from the instances in the inventory based on the instanceID. + // First find the corresponding inventory + inventory := &dbaas.MongoDBAtlasInventory{} + if err := r.Client.Get(context.Background(), types.NamespacedName{Namespace: conn.Namespace, Name: conn.Spec.InventoryRef.Name}, inventory); err != nil { + if apiErrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("MongoDBAtlasInventory resource not found, has been deleted") + return nil + } + log.Error(err, "Error fetching MongoDBAtlasInventory") + return err + } + + if !isInventoryReady(inventory) { + // The corresponding inventory is not ready yet + // Nothing to clean up + return nil + } + + // Retrieve the instance from inventory based on instanceID + instance := getInstance(inventory, conn.Spec.InstanceID) + if instance == nil { + log.Infow("No instance found in the inventory. Deletion done.") + return nil + } + + // Get the projectID from the status + projectID, ok := instance.InstanceInfo[dbaas.ProjectIDKey] + if !ok { + log.Infow("No projectID found. Deletion done.") + return nil + } + + // Now delete the db user from Atlas + if err := r.deleteDBUserFromAtlas(projectID, dbUserName, inventory, log); err != nil { + log.Errorf("Failed to remove db user from Atlas: %s", err) + return err + } + + // db user secret and connectioninfo configmap are automatically deleted based on owner references + return nil +} + +// getSecret gets a secret object +func (r *MongoDBAtlasConnectionReconciler) getSecret(namespace, name string) (*corev1.Secret, error) { + return r.Clientset.CoreV1().Secrets(namespace).Get(context.Background(), name, metav1.GetOptions{}) +} + +// createDBUserInAtlas create the database user in Atlas +func (r *MongoDBAtlasConnectionReconciler) createDBUserInAtlas(conn *dbaas.MongoDBAtlasConnection, projectID, dbUserName, dbPassword string, inventory *dbaas.MongoDBAtlasInventory, log *zap.SugaredLogger) (ctrl.Result, error) { + dbUser := &mongodbatlas.DatabaseUser{ + DatabaseName: dbaas.DefaultDatabase, + GroupID: projectID, + Roles: []mongodbatlas.Role{ + { + DatabaseName: dbaas.DefaultDatabase, + RoleName: "readWriteAnyDatabase", + }, + }, + Username: dbUserName, + Password: dbPassword, + } + + atlasConnection, err := atlas.ReadConnection(log, r.Client, r.GlobalAPISecret, inventory.ConnectionSecretObjectKey()) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasConnectionAuthenticationError, err.Error()) + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), err + } + + atlasClient := r.AtlasClient + if atlasClient == nil { + cl, err := atlas.Client(r.AtlasDomain, atlasConnection, log) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasConnectionBackendError, err.Error()) + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + atlasClient = &cl + } + + // Try to create the db user + if _, _, err := atlasClient.DatabaseUsers.Create(context.Background(), projectID, dbUser); err != nil { + result := workflow.Terminate(workflow.DatabaseUserNotCreatedInAtlas, err.Error()) + dbaas.SetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return ctrl.Result{}, err + } + return ctrl.Result{}, nil +} + +// deleteDBUserFromAtlas delete database user from Atlas +func (r *MongoDBAtlasConnectionReconciler) deleteDBUserFromAtlas(projectID, dbUserName string, inventory *dbaas.MongoDBAtlasInventory, log *zap.SugaredLogger) error { + atlasConnection, err := atlas.ReadConnection(log, r.Client, r.GlobalAPISecret, inventory.ConnectionSecretObjectKey()) + if err != nil { + return err + } + + atlasClient := r.AtlasClient + if atlasClient == nil { + cl, err := atlas.Client(r.AtlasDomain, atlasConnection, log) + if err != nil { + return fmt.Errorf("cannot build Atlas client: %w", err) + } + atlasClient = &cl + } + + _, err = atlasClient.DatabaseUsers.Delete(context.Background(), "admin", projectID, dbUserName) + if err != nil { + log.Errorw("Cannot delete Atlas database user", "error", err) + return fmt.Errorf("failed to delete Atlas database user %s: %w", dbUserName, err) + } + return nil +} + +// getHost retrieves host from the standard srv connection string +func getHost(connectionStringStandardSrv string) string { + tokens := strings.Split(connectionStringStandardSrv, "//") + var host string + if len(tokens) < 2 { + host = connectionStringStandardSrv + } else { + host = tokens[1] + } + return host +} + +// getOwnedSecret returns a secret object for database credentials with ownership set +func getOwnedSecret(connection *dbaas.MongoDBAtlasConnection, username, password, connectionStringStandardSrv string) *corev1.Secret { + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "atlas-db-user-", + Namespace: connection.Namespace, + Labels: map[string]string{ + "managed-by": "atlas-operator", + "owner": connection.Name, + "owner.kind": connection.Kind, + "owner.namespace": connection.Namespace, + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: connection.GetUID(), + APIVersion: "dbaas.redhat.com/v1alpha1", + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "MongoDBAtlasConnection", + Name: connection.Name, + }, + }, + }, + Type: corev1.SecretType(fmt.Sprintf("servicebinding.io/%s", dbaas.ServiceBindingType)), + Data: map[string][]byte{ + DBUserNameKey: []byte(username), + DBPasswordKey: []byte(password), + dbaas.ProviderKey: []byte(dbaas.Provider), + dbaas.ServiceBindingTypeKey: []byte(dbaas.ServiceBindingType), + dbaas.HostKey: []byte(getHost(connectionStringStandardSrv)), + dbaas.SrvKey: []byte("true"), + }, + } +} + +// isReadyForBinding is the MongoDBAtlasConnection ready for binding already? +func isReadyForBinding(conn *dbaas.MongoDBAtlasConnection) bool { + cond := dbaas.GetConnectionCondition(conn, dbaasv1alpha1.DBaaSConnectionProviderSyncType) + return cond != nil && cond.Status == metav1.ConditionTrue +} + +// isInventoryReady is the MongoDBAtlasInvenotry ready? +func isInventoryReady(inventory *dbaas.MongoDBAtlasInventory) bool { + cond := dbaas.GetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType) + return cond != nil && cond.Status == metav1.ConditionTrue +} + +// getInstance returns an instance from the inventory based on instanceID +func getInstance(inventory *dbaas.MongoDBAtlasInventory, instanceID string) *dbaasv1alpha1.Instance { + for _, instance := range inventory.Status.Instances { + if instance.InstanceID == instanceID { + // Found the instance based on its ID + return &instance + } + } + return nil +} + +// generatePassword generates a random password with at least one digit and one special character. +func generatePassword() string { + length := 8 + buf := make([]byte, length) + buf[0] = digits[getRandInt(len(digits))] + buf[1] = specials[getRandInt(len(specials))] + for i := 2; i < length; i++ { + buf[i] = all[getRandInt(len(all))] + } + rand.Shuffle(len(buf), func(i, j int) { + buf[i], buf[j] = buf[j], buf[i] + }) + return string(buf) // E.g. "3i[g0|)z" +} + +func getRandInt(s int) int64 { + result, _ := cryptorand.Int(cryptorand.Reader, big.NewInt(int64(s))) + return result.Int64() +} diff --git a/pkg/controller/atlasconnection/atlasconnection_test.go b/pkg/controller/atlasconnection/atlasconnection_test.go new file mode 100644 index 0000000000..81c3b89225 --- /dev/null +++ b/pkg/controller/atlasconnection/atlasconnection_test.go @@ -0,0 +1,549 @@ +// Copyright 2021 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package atlasconnection + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/fgrosse/zaptest" + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + krand "k8s.io/apimachinery/pkg/util/rand" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + k8sfake "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/kubernetes/scheme" + k8sfakecorev1 "k8s.io/client-go/kubernetes/typed/core/v1/fake" + ktesting "k8s.io/client-go/testing" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.mongodb.org/atlas/mongodbatlas" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube" +) + +const ( + // baseURLPath is a non-empty Client.BaseURL path to use during tests, + // to ensure relative URLs are used for all endpoints. + baseURLPath = "/api-v1" +) + +var simulateAtlasDBUserDeleteFailure = false + +// setupMockAltasServer sets up a test HTTP server along with a mongodbatlas.Client that is +// configured to talk to that test server. Tests should register handlers on +// mux which provide mock responses for the API method being tested. +func setupMockAltasServer() (client *mongodbatlas.Client, teardown func()) { + // mux is the HTTP request multiplexer used with the test server. + router := mux.NewRouter() + + // We want to ensure that tests catch mistakes where the endpoint URL is + // specified as absolute rather than relative. It only makes a difference + // when there's a non-empty base URL path. So, use that. + apiHandler := http.NewServeMux() + apiHandler.Handle(baseURLPath+"/", http.StripPrefix(baseURLPath, router)) + + router.HandleFunc("/api/atlas/v1.0/groups/{group-id}/databaseUsers/{db}/{user}", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + groupID, ok := vars["group-id"] + if !ok { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "group-id is missing in parameters") + return + } + _, ok = vars["db"] + if !ok { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "db is missing in parameters") + return + } + _, ok = vars["user"] + if !ok { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "user is missing in parameters") + return + } + if simulateAtlasDBUserDeleteFailure { + // Simulates a db deletion failure + w.WriteHeader(http.StatusNotFound) + fmt.Fprintf(w, "{\"detail\":\"An invalid group ID %s was specified.\",\"error\":404,\"errorCode\":\"INVALID_GROUP_ID\",\"parameters\":[\"%s\"],\"reason\":\"Not Found\"}", groupID, groupID) + } else { + w.WriteHeader(http.StatusOK) + } + }).Methods(http.MethodDelete) + + router.HandleFunc("/api/atlas/v1.0/groups/{group-id}/databaseUsers", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + groupID, ok := vars["group-id"] + if !ok { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprint(w, "group-id is missing in parameters") + return + } + data, err := ioutil.ReadFile(fmt.Sprintf("../../../test/e2e/data/atlasdatabaseuserresp_%s.json", groupID)) + if err == nil { + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(data)) + } else { + // Simulates a db creation failure + w.WriteHeader(http.StatusNotFound) + fmt.Fprintf(w, "{\"detail\":\"An invalid group ID %s was specified.\",\"error\":404,\"errorCode\":\"INVALID_GROUP_ID\",\"parameters\":[\"%s\"],\"reason\":\"Not Found\"}", groupID, groupID) + } + }).Methods(http.MethodPost) + + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + // client is the Atlas client being tested and is + // configured to use test server. + client = mongodbatlas.NewClient(nil) + u, _ := url.Parse(server.URL + baseURLPath + "/") + client.BaseURL = u + + return client, server.Close +} + +func TestAtlasConnectionReconcile(t *testing.T) { + s := scheme.Scheme + utilruntime.Must(scheme.AddToScheme(s)) + utilruntime.Must(mdbv1.AddToScheme(s)) + utilruntime.Must(dbaas.AddToScheme(s)) + + atlasClient, teardown := setupMockAltasServer() + defer teardown() + + logger := zaptest.Logger(t) + + testCase := map[string]struct { + createConnection bool + secretCreateFail bool + instanceID string + expectedRequeue bool + expectedErrString string + expectedStatus string + expectedReason string + inventoryReason string + inventoryStatus string + instancesPath string + }{ + "Nominal": { + createConnection: true, + secretCreateFail: false, + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + expectedRequeue: false, + expectedStatus: "True", + expectedReason: "Ready", + }, + "ConnectionCRNotFound": { + createConnection: false, + secretCreateFail: false, + instanceID: "70b7a72f4877d05880c487", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedRequeue: false, + }, + "InstanceIDNotFound": { + createConnection: true, + secretCreateFail: false, + instanceID: "70b7a72f4877d05880c487efmissing", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + expectedRequeue: false, + expectedStatus: "False", + expectedReason: "InstanceIDNotFound", + }, + "InventoryNotFound": { + createConnection: true, + secretCreateFail: false, + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + expectedRequeue: false, + expectedStatus: "False", + expectedReason: "InventoryNotFound", + }, + "SecretCreateFail": { + createConnection: true, + secretCreateFail: true, + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "failed to create secret", + expectedRequeue: false, + expectedStatus: "False", + expectedReason: "BackendError", + }, + "AtlasDBUserCreateFail": { + createConnection: true, + secretCreateFail: false, + instanceID: "60b7a72f4877d05880c487d2", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + expectedRequeue: false, + expectedStatus: "False", + expectedReason: "DatabaseUserNotCreatedInAtlas", + }, + } + + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + instances := []dbaasv1alpha1.Instance{} + if len(tc.instancesPath) > 0 { + data, err := ioutil.ReadFile("../../../test/e2e/data/atlasinventoryexpected.json") + assert.NoError(t, err) + err = json.Unmarshal(data, &instances) + assert.NoError(t, err) + } + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("secret-%s", tcName), + Namespace: "dbaas-operator", + }, + Data: map[string][]byte{ + "orgId": []byte("testorgid"), + "privateApiKey": []byte("testprivatekey"), + "publicApiKey": []byte("testpublickey"), + }, + } + + inventory := &dbaas.MongoDBAtlasInventory{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInventory", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInventorySpec{ + CredentialsRef: &dbaasv1alpha1.LocalObjectReference{ + Name: fmt.Sprintf("secret-%s", tcName), + }, + }, + Status: dbaasv1alpha1.DBaaSInventoryStatus{ + Conditions: []metav1.Condition{ + { + LastTransitionTime: metav1.Now(), + Status: metav1.ConditionStatus(tc.inventoryStatus), + Reason: tc.inventoryReason, + Type: dbaasv1alpha1.DBaaSInventoryProviderSyncType, + }, + }, + Instances: instances, + }, + } + + connection := &dbaas.MongoDBAtlasConnection{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasConnection", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("connection-%s", tcName), + Namespace: "myproject", + }, + Spec: dbaasv1alpha1.DBaaSConnectionSpec{ + InventoryRef: dbaasv1alpha1.NamespacedName{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + InstanceID: tc.instanceID, + }, + } + objs := []runtime.Object{secret} + if tcName != "InventoryNotFound" { + objs = append(objs, inventory) + } + if tc.createConnection { + objs = append(objs, connection) + } + + // Create a fake client with the objects + client := fake.NewClientBuilder().WithRuntimeObjects(objs...).WithScheme(s).Build() + + // Mock request to simulate Reconcile() being called on an event for a + // watched resource . + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: connection.Name, + Namespace: connection.Namespace, + }, + } + + // Create a fake clientset + clientSet := k8sfake.NewSimpleClientset() + // Fake clientset does not generate resource names based on GenerateName, + // so we add reactor to generate such names when a secret is created + clientSet.PrependReactor("create", "secrets", GenerateNameReactor) + // Simulate secret creationg failures + if tc.secretCreateFail { + clientSet.CoreV1().(*k8sfakecorev1.FakeCoreV1).PrependReactor("create", "secrets", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &corev1.Secret{}, errors.New("Error creating secret") + }) + } + r := &MongoDBAtlasConnectionReconciler{ + Client: client, + Clientset: clientSet, + AtlasClient: atlasClient, + Scheme: s, + Log: logger.Sugar(), + ResourceWatcher: watch.NewResourceWatcher(), + } + + res, err := r.Reconcile(context.Background(), req) + if err != nil { + assert.Contains(t, err.Error(), tc.expectedErrString) + } + assert.Equal(t, tc.expectedRequeue, res.Requeue) + connectionUpdated := &dbaas.MongoDBAtlasConnection{} + err = client.Get(context.Background(), + types.NamespacedName{ + Name: connection.Name, + Namespace: connection.Namespace, + }, connectionUpdated) + if tcName == "ConnectionCRNotFound" { + assert.True(t, apiErrors.IsNotFound(err)) + // Special case: the CR does not exist + // No further checking is needed + return + } + assert.NoError(t, err) + assert.NotEmpty(t, connectionUpdated.Status) + assert.Equal(t, tc.expectedStatus, string(connectionUpdated.Status.Conditions[0].Status)) + assert.Equal(t, tc.expectedReason, connectionUpdated.Status.Conditions[0].Reason) + if isReadyForBinding(connectionUpdated) { + assert.NotNil(t, connectionUpdated.Status.Binding) + assert.NotEmpty(t, connectionUpdated.Status.Binding.Name) + } else { + assert.Nil(t, connectionUpdated.Status.Binding) + } + }) + } +} + +func TestDBUserDelete(t *testing.T) { + s := scheme.Scheme + utilruntime.Must(scheme.AddToScheme(s)) + utilruntime.Must(mdbv1.AddToScheme(s)) + utilruntime.Must(dbaas.AddToScheme(s)) + + atlasClient, teardown := setupMockAltasServer() + defer teardown() + + logger := zaptest.Logger(t) + + testCase := map[string]struct { + instanceID string + expectedErrString string + inventoryReason string + inventoryStatus string + instancesPath string + }{ + "Nominal": { + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + }, + "InstanceIDNotFound": { + instanceID: "70b7a72f4877d05880c487efmissing", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + }, + "InventoryNotFound": { + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + }, + "AtlasDBUserDeleteFail": { + instanceID: "70b7a72f4877d05880c487ef", + inventoryReason: "SyncOK", + inventoryStatus: "True", + instancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "failed to delete Atlas database user", + }, + } + + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + instances := []dbaasv1alpha1.Instance{} + if len(tc.instancesPath) > 0 { + data, err := ioutil.ReadFile("../../../test/e2e/data/atlasinventoryexpected.json") + assert.NoError(t, err) + err = json.Unmarshal(data, &instances) + assert.NoError(t, err) + } + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("secret-%s", tcName), + Namespace: "dbaas-operator", + }, + Data: map[string][]byte{ + "orgId": []byte("testorgid"), + "privateApiKey": []byte("testprivatekey"), + "publicApiKey": []byte("testpublickey"), + }, + } + + inventory := &dbaas.MongoDBAtlasInventory{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInventory", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInventorySpec{ + CredentialsRef: &dbaasv1alpha1.LocalObjectReference{ + Name: fmt.Sprintf("secret-%s", tcName), + }, + }, + Status: dbaasv1alpha1.DBaaSInventoryStatus{ + Conditions: []metav1.Condition{ + { + LastTransitionTime: metav1.Now(), + Status: metav1.ConditionStatus(tc.inventoryStatus), + Reason: tc.inventoryReason, + Type: dbaasv1alpha1.DBaaSInventoryProviderSyncType, + }, + }, + Instances: instances, + }, + } + connection := &dbaas.MongoDBAtlasConnection{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasConnection", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("connection-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSConnectionSpec{ + InventoryRef: dbaasv1alpha1.NamespacedName{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + InstanceID: tc.instanceID, + }, + } + objs := []runtime.Object{secret, connection} + if tcName != "InventoryNotFound" { + objs = append(objs, inventory) + } + + if tcName == "AtlasDBUserDeleteFail" { + simulateAtlasDBUserDeleteFailure = true + } else { + simulateAtlasDBUserDeleteFailure = false + } + // Create a fake client with the objects + client := fake.NewClientBuilder().WithRuntimeObjects(objs...).WithScheme(s).Build() + + // Create a fake clientset + clientSet := k8sfake.NewSimpleClientset() + // Fake clientset does not generate resource names based on GenerateName, + // so we add reactor to generate such names when a secret is created + clientSet.PrependReactor("create", "secrets", GenerateNameReactor) + + r := &MongoDBAtlasConnectionReconciler{ + Client: client, + Clientset: clientSet, + AtlasClient: atlasClient, + Scheme: s, + Log: logger.Sugar(), + ResourceWatcher: watch.NewResourceWatcher(), + } + // Mock request + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: connection.Name, + Namespace: connection.Namespace, + }, + } + + log := r.Log.With("MongoDBAtlasConnection", kube.ObjectKeyFromObject(connection)) + _, err := r.Reconcile(context.Background(), req) + assert.NoError(t, err) + connectionUpdated := &dbaas.MongoDBAtlasConnection{} + err = client.Get(context.Background(), + types.NamespacedName{ + Name: connection.Name, + Namespace: connection.Namespace, + }, connectionUpdated) + assert.NoError(t, err) + + // Check db user deletion + err = r.deleteDBUser(connectionUpdated, log) + if err != nil { + assert.Contains(t, err.Error(), tc.expectedErrString) + } else { + assert.NoError(t, err) + } + }) + } +} + +// GenerateNameReactor sets the metav1.Name of an object, if metav1.GenerateName was used. +// It returns "handled" == false, so the test client can continue to the next ReactionFunc. +func GenerateNameReactor(action ktesting.Action) (bool, runtime.Object, error) { + obj := action.(ktesting.CreateAction).GetObject().(client.Object) + if obj.GetName() == "" && obj.GetGenerateName() != "" { + obj.SetName(fmt.Sprintf("%s%s", obj.GetGenerateName(), krand.String(8))) + } + return false, nil, nil +} diff --git a/pkg/controller/atlasdeployment/deployment.go b/pkg/controller/atlasdeployment/deployment.go index 7bfc4f572a..6bcf6119fa 100644 --- a/pkg/controller/atlasdeployment/deployment.go +++ b/pkg/controller/atlasdeployment/deployment.go @@ -54,8 +54,11 @@ func ensureDeploymentState(ctx *workflow.Context, project *mdbv1.AtlasProject, d case "UPDATING", "REPAIRING": return atlasDeployment, workflow.InProgress(workflow.DeploymentUpdating, "deployment is updating") - // TODO: add "DELETING", "DELETED", handle 404 on delete + case "DELETING": + return atlasDeployment, workflow.InProgress(workflow.DeploymentDeleting, "deployment is being deleted") + case "DELETED": + return atlasDeployment, workflow.InProgress(workflow.DeploymentDeleted, "deployment has been deleted") default: return atlasDeployment, workflow.Terminate(workflow.Internal, fmt.Sprintf("unknown deployment state %q", atlasDeployment.StateName)) } diff --git a/pkg/controller/atlasinstance/atlasinstance_controller.go b/pkg/controller/atlasinstance/atlasinstance_controller.go new file mode 100644 index 0000000000..f5129e6c6c --- /dev/null +++ b/pkg/controller/atlasinstance/atlasinstance_controller.go @@ -0,0 +1,496 @@ +/* +Copyright 2022 MongoDB. + +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 atlasinstance + +import ( + "context" + "errors" + "fmt" + "strings" + + "go.uber.org/zap" + + corev1 "k8s.io/api/core/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/record" + ptr "k8s.io/utils/pointer" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/source" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.mongodb.org/atlas/mongodbatlas" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/project" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/provider" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlasinventory" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/customresource" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/util/kube" +) + +// MongoDBAtlasInstanceReconciler reconciles a MongoDBAtlasInstance object +type MongoDBAtlasInstanceReconciler struct { + Client client.Client + Clientset kubernetes.Interface + AtlasClient *mongodbatlas.Client + watch.ResourceWatcher + Log *zap.SugaredLogger + Scheme *runtime.Scheme + AtlasDomain string + GlobalAPISecret client.ObjectKey + EventRecorder record.EventRecorder +} + +type InstanceData struct { + ProjectName string + ClusterName string + ProviderName string + RegionName string + InstanceSizeName string +} + +const ( + DBaaSInstanceNameLabel = "dbaas.redhat.com/instance-name" + DBaaSInstanceNamespaceLabel = "dbaas.redhat.com/instance-namespace" + FreeClusterFailed = "CANNOT_CREATE_FREE_CLUSTER_VIA_PUBLIC_API" + ClusterAlreadyExistsInAtlas = "ClusterAlreadyExistsInAtlas" + ClusterAlreadyExistsInAtlasMsg = "Can not create the cluster as it already exists in Atlas" +) + +// Dev note: duplicate the permissions in both sections below to generate both Role and ClusterRoles + +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasinstances,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasinstances/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch + +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasinstances,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasinstances/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",namespace=default,resources=secrets,verbs=get;list;watch + +func (r *MongoDBAtlasInstanceReconciler) Reconcile(cx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = cx + log := r.Log.With("MongoDBAtlasInstance", req.NamespacedName) + log.Info("Reconciling MongoDBAtlasInstance") + + inst := &dbaas.MongoDBAtlasInstance{} + if err := r.Client.Get(cx, req.NamespacedName, inst); err != nil { + if apiErrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("MongoDBAtlasInstance resource not found, has been deleted") + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching MongoDBAtlasInstance for reconcile") + return ctrl.Result{}, err + } + + // This update will make sure the status is always updated in case of any errors or successful result + defer func(c *dbaas.MongoDBAtlasInstance) { + err := r.Client.Status().Update(context.Background(), c) + if err != nil { + log.Infof("Could not update resource status:%v", err) + } + }(inst) + + inventory := &dbaas.MongoDBAtlasInventory{} + namespace := inst.Spec.InventoryRef.Namespace + if len(namespace) == 0 { + // Namespace is not populated in InventoryRef, default to the request's namespace + namespace = req.Namespace + } + if err := r.Client.Get(cx, types.NamespacedName{Namespace: namespace, Name: inst.Spec.InventoryRef.Name}, inventory); err != nil { + if apiErrors.IsNotFound(err) { + // The corresponding inventory is not found, no reqeue. + log.Info("MongoDBAtlasInventory resource not found, has been deleted") + result := workflow.InProgress(workflow.MongoDBAtlasInstanceInventoryNotFound, "inventory not found") + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching MongoDBAtlasInventory") + return ctrl.Result{}, err + } + instData, err := getInstanceData(log, inst) + if err != nil { + log.Error(err, "Invalid parameters") + return ctrl.Result{}, err + } + + atlasProject, err := r.reconcileAtlasProject(cx, inst, instData, inventory) + if err != nil { + log.Error(err, "Failed to reconcile Atlas Project") + return ctrl.Result{}, err + } + atlasProjectCond := atlasProject.CheckConditions() + if atlasProjectCond == nil || atlasProjectCond.Type == status.IPAccessListReadyType { // AtlasProject reconciliation still on going + log.Infof("Atlas Project for instance:%v/%v is not ready. Requeue to retry.", inst.Namespace, inst.Name) + // Set phase to Pending + inst.Status.Phase = dbaasv1alpha1.InstancePhasePending + // Requeue to try again + return ctrl.Result{Requeue: true}, nil + } + if atlasProjectCond.Status == corev1.ConditionFalse { // AtlasProject reconciliation failed + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, atlasProjectCond.Reason, atlasProjectCond.Message) + // Do not requeue + return ctrl.Result{}, nil + } + // Now proceed to provision the cluster + return r.reconcileAtlasDeployment(cx, log, inst, instData, inventory, atlasProject) +} + +func (r *MongoDBAtlasInstanceReconciler) reconcileAtlasDeployment(cx context.Context, log *zap.SugaredLogger, inst *dbaas.MongoDBAtlasInstance, instData *InstanceData, inventory *dbaas.MongoDBAtlasInventory, atlasProject *v1.AtlasProject) (ctrl.Result, error) { + if atlasProject == nil { + return ctrl.Result{}, errors.New("there is no Atlas Project used to provision atlas cluster") + } + atlasConn, err := atlas.ReadConnection(log, r.Client, r.GlobalAPISecret, inventory.ConnectionSecretObjectKey()) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasInventoryInputError, err.Error()) + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + atlasClient := r.AtlasClient + if atlasClient == nil { + cl, err := atlas.Client(r.AtlasDomain, atlasConn, log) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasInventoryInputError, err.Error()) + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + atlasClient = &cl + } + + atlasDeployment := getOwnedAtlasDeployment(inst) + if err := r.Client.Get(cx, types.NamespacedName{Namespace: atlasDeployment.Namespace, Name: atlasDeployment.Name}, atlasDeployment); err != nil { + if apiErrors.IsNotFound(err) { // The AtlasDeployment CR does not exist + // If the instance has been previously associated with an AtlasCluster CR, its phase is not in pending status (ie, is in creating, updating or ready) + // This allows the operator to migrate from a previous AtlasCluster CR to an AtlasDeployment CR + if len(inst.Status.Phase) == 0 || inst.Status.Phase == dbaasv1alpha1.InstancePhasePending || inst.Status.Phase == dbaasv1alpha1.InstancePhaseUnknown { + _, result := atlasinventory.GetClusterInfo(atlasClient, atlasProject.Spec.Name, inst.Spec.Name) + if result.IsOk() { + // The cluster already exists in Atlas. Mark provisioning phase as failed and return + inst.Status.Phase = dbaasv1alpha1.InstancePhaseFailed + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, ClusterAlreadyExistsInAtlas, ClusterAlreadyExistsInAtlasMsg) + // No requeue + return ctrl.Result{}, nil + } + } else { + log.Info("This instance has been reconciled previously but no AtlasDeployment CR is found. Creating a new AtlasDeployment CR.") + } + } else { + return ctrl.Result{}, err + } + } + _, err = controllerutil.CreateOrUpdate(cx, r.Client, atlasDeployment, instanceMutateFn(atlasProject, atlasDeployment, instData)) + if err != nil { + log.Error(err, "Failed to create or update AtlasDeployment resource") + return ctrl.Result{}, err + } + + // Update the status + if err := r.Client.Get(cx, types.NamespacedName{Namespace: atlasDeployment.Namespace, Name: atlasDeployment.Name}, atlasDeployment); err != nil { + if apiErrors.IsNotFound(err) { + // The corresponding AtlasDeployment is not found, no reqeue. + log.Info("AtlasDeployment resource not found, has been deleted") + result := workflow.InProgress(workflow.MongoDBAtlasInstanceClusterNotFound, "AtlasDeployment not found") + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching AtlasDeployment") + return ctrl.Result{}, err + } + + result := setInstanceStatusWithDeploymentInfo(atlasClient, inst, atlasDeployment, instData.ProjectName) + if !result.IsOk() { + log.Infof("Error setting instance status: %v", result.Message()) + return ctrl.Result{}, errors.New(result.Message()) + } + return ctrl.Result{}, nil +} + +func (r *MongoDBAtlasInstanceReconciler) SetupWithManager(mgr ctrl.Manager) error { + c, err := controller.New("MongoDBAtlasInstance", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource MongoDBAtlasInstance & handle delete separately + err = c.Watch(&source.Kind{Type: &dbaas.MongoDBAtlasInstance{}}, + &watch.EventHandlerWithDelete{Controller: r}, + watch.CommonPredicates()) + if err != nil { + return err + } + + if err != nil { + return err + } + + // Watch for dependent AtlasDeployment resource + err = c.Watch( + &source.Kind{ + Type: &v1.AtlasDeployment{}, + }, + &handler.EnqueueRequestForOwner{ + OwnerType: &dbaas.MongoDBAtlasInstance{}, + IsController: true, + }, + ) + if err != nil { + return err + } + return nil +} + +// getAtlasProject returns an AtlasProject CR +func (r *MongoDBAtlasInstanceReconciler) getAtlasProject(cx context.Context, inst *dbaas.MongoDBAtlasInstance) (atlasProject *v1.AtlasProject, err error) { + atlasProjectList := &v1.AtlasProjectList{} + opts := &client.ListOptions{ + LabelSelector: labels.SelectorFromSet(map[string]string{ + DBaaSInstanceNameLabel: inst.Name, + DBaaSInstanceNamespaceLabel: inst.Namespace, + }), + } + err = r.Client.List(cx, atlasProjectList, opts) + if err != nil { + return + } + if len(atlasProjectList.Items) < 1 { + return + } + atlasProject = &atlasProjectList.Items[0] + return +} + +func (r *MongoDBAtlasInstanceReconciler) reconcileAtlasProject(cx context.Context, inst *dbaas.MongoDBAtlasInstance, instData *InstanceData, inventory *dbaas.MongoDBAtlasInventory) (atlasProject *v1.AtlasProject, err error) { + // First check if there is already an AtlasProject resource created for this instance using labels + atlasProject, err = r.getAtlasProject(cx, inst) + if err != nil { + return + } + if atlasProject == nil { + // No AtlasProject resource found, create one + project, err1 := r.getAtlasProjectForCreation(inst, instData, inventory) + if err1 != nil { + err = err1 + return + } + err = r.Client.Create(cx, project, &client.CreateOptions{}) + if err != nil { + return + } + atlasProject = project + } + return +} + +// Delete implements a handler for the Delete event. +func (r *MongoDBAtlasInstanceReconciler) Delete(e event.DeleteEvent) error { + inst, ok := e.Object.(*dbaas.MongoDBAtlasInstance) + log := r.Log.With("MongoDBAtlasInstance", kube.ObjectKeyFromObject(inst)) + if !ok { + log.Errorf("Ignoring malformed Delete() call (expected type %T, got %T)", &dbaas.MongoDBAtlasInstance{}, e.Object) + return nil + } + // Fetch the corresponding AtlasProject resource for this instance + cx := context.Background() + atlasProject, err := r.getAtlasProject(cx, inst) + if err == nil && atlasProject != nil { + // Delete the AtlasProject resource. Note that the project will be kept in Atlas. + err = r.Client.Delete(cx, atlasProject, &client.DeleteOptions{}) + } + return err +} + +// getAtlasProjectForCreation returns an AtlasProject object for provisioning +// No ownerref is set as the same project can be used to provision multiple clusters +func (r *MongoDBAtlasInstanceReconciler) getAtlasProjectForCreation(instance *dbaas.MongoDBAtlasInstance, data *InstanceData, inventory *dbaas.MongoDBAtlasInventory) (*v1.AtlasProject, error) { + secret := &corev1.Secret{} + if err := r.Client.Get(context.Background(), *inventory.ConnectionSecretObjectKey(), secret); err != nil { + return nil, err + } + return &v1.AtlasProject{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "atlas-project-", + Namespace: inventory.Namespace, // AtlasProject CR must be in the same namespace as the inventory + Labels: map[string]string{ + "created-by": "atlas-operator", + DBaaSInstanceNameLabel: instance.Name, + DBaaSInstanceNamespaceLabel: instance.Namespace, + }, + Annotations: map[string]string{ + // Keep the project in Atlas when local k8s AtlasProject resource is deleted + customresource.ResourcePolicyAnnotation: customresource.ResourcePolicyKeep, + }, + }, + Spec: v1.AtlasProjectSpec{ + Name: data.ProjectName, + ConnectionSecret: &common.ResourceRef{Name: inventory.Spec.CredentialsRef.Name}, + ProjectIPAccessList: []project.IPAccessList{}, + }, + }, nil +} + +// getAtlasDeploymentSpec returns the spec for the desired cluster +func getAtlasDeploymentSpec(atlasProject *v1.AtlasProject, data *InstanceData) *v1.AtlasDeploymentSpec { + var providerSettingsSpec *v1.ProviderSettingsSpec + if data.InstanceSizeName == "M0" || data.InstanceSizeName == "M2" || data.InstanceSizeName == "M5" { + // See Atlas documentation https://docs.atlas.mongodb.com/reference/api/clusters-create-one/ + providerSettingsSpec = &v1.ProviderSettingsSpec{ + InstanceSizeName: data.InstanceSizeName, + BackingProviderName: data.ProviderName, + ProviderName: provider.ProviderName("TENANT"), + RegionName: data.RegionName, + } + } else { + providerSettingsSpec = &v1.ProviderSettingsSpec{ + InstanceSizeName: data.InstanceSizeName, + ProviderName: provider.ProviderName(data.ProviderName), + RegionName: data.RegionName, + } + } + return &v1.AtlasDeploymentSpec{ + Project: common.ResourceRefNamespaced{Name: atlasProject.Name, Namespace: atlasProject.Namespace}, + DeploymentSpec: &v1.DeploymentSpec{ + Name: data.ClusterName, + ProviderSettings: providerSettingsSpec, + }, + } +} + +// getOwnedAtlasDeployment returns an AtlasDeployment object owned by the instance +func getOwnedAtlasDeployment(instance *dbaas.MongoDBAtlasInstance) *v1.AtlasDeployment { + return &v1.AtlasDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name, + Namespace: instance.Namespace, + Labels: map[string]string{ + "managed-by": "atlas-operator", + "owner": instance.Name, + "owner.kind": instance.Kind, + "owner.namespace": instance.Namespace, + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: instance.GetUID(), + APIVersion: dbaas.GroupVersion.Identifier(), + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "MongoDBAtlasInstance", + Name: instance.Name, + }, + }, + }, + } +} + +func getInstanceData(log *zap.SugaredLogger, inst *dbaas.MongoDBAtlasInstance) (*InstanceData, error) { + name := strings.TrimSpace(inst.Spec.Name) + if len(name) == 0 { + log.Errorf("Missing %v", dbaas.ClusterNameKey) + return nil, fmt.Errorf("missing %v", dbaas.ClusterNameKey) + } + projectName, ok := inst.Spec.OtherInstanceParams[dbaas.ProjectNameKey] + if !ok || len(strings.TrimSpace(projectName)) == 0 { + log.Errorf("Missing %v", dbaas.ProjectNameKey) + return nil, fmt.Errorf("missing %v", dbaas.ProjectNameKey) + } + provider := strings.ToUpper(strings.TrimSpace(inst.Spec.CloudProvider)) + if len(provider) == 0 { + provider = "AWS" + log.Infof("%v is missing, default value of AWS is used", dbaas.CloudProviderKey) + } + region := strings.TrimSpace(inst.Spec.CloudRegion) + if len(region) == 0 { + switch provider { + case "AWS": + region = "US_EAST_1" + case "GCE": + region = "CENTRAL_US" + case "AZURE": + region = "US_WEST" + } + log.Infof("%v is missing, default value of %s is used", dbaas.CloudProviderKey, region) + } + instanceSizeName, ok := inst.Spec.OtherInstanceParams[dbaas.InstanceSizeNameKey] + if !ok || len(strings.TrimSpace(instanceSizeName)) == 0 { + log.Infof("%v is missing, default value of M0 is used", dbaas.InstanceSizeNameKey) + instanceSizeName = "M0" + } + + return &InstanceData{ + ProjectName: strings.TrimSpace(projectName), + ClusterName: name, + ProviderName: provider, + RegionName: region, + InstanceSizeName: strings.TrimSpace(instanceSizeName), + }, nil +} + +func instanceMutateFn(atlasProject *v1.AtlasProject, atlasDeployment *v1.AtlasDeployment, data *InstanceData) controllerutil.MutateFn { + return func() error { + atlasDeployment.Spec = *getAtlasDeploymentSpec(atlasProject, data) + return nil + } +} + +func setInstanceStatusWithDeploymentInfo(atlasClient *mongodbatlas.Client, inst *dbaas.MongoDBAtlasInstance, atlasDeployment *v1.AtlasDeployment, project string) workflow.Result { + instInfo, result := atlasinventory.GetClusterInfo(atlasClient, project, inst.Spec.Name) + if result.IsOk() { + // Stores the phase info in inst.Status.Phase and remove from instInfo.InstanceInf map + inst.Status.Phase = dbaasv1alpha1.DBaasInstancePhase(instInfo.InstanceInfo[dbaas.ProvisionPhaseKey]) + delete(instInfo.InstanceInfo, dbaas.ProvisionPhaseKey) + inst.Status.InstanceID = instInfo.InstanceID + inst.Status.InstanceInfo = instInfo.InstanceInfo + } else { + inst.Status.Phase = dbaasv1alpha1.InstancePhasePending + inst.Status.InstanceID = "" + inst.Status.InstanceInfo = nil + } + statusFound := false + for _, cond := range atlasDeployment.Status.Conditions { + if cond.Type == status.DeploymentReadyType { + statusFound = true + if cond.Status == corev1.ConditionTrue { + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionStatus(cond.Status), "Ready", cond.Message) + } else { + if strings.Contains(cond.Message, FreeClusterFailed) { + inst.Status.Phase = dbaasv1alpha1.InstancePhaseFailed + } + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionStatus(cond.Status), cond.Reason, cond.Message) + } + } + } + if !statusFound { + dbaas.SetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType, metav1.ConditionFalse, string(dbaasv1alpha1.InstancePhasePending), "Waiting for cluster creation to start") + } + + return result +} diff --git a/pkg/controller/atlasinstance/atlasinstance_test.go b/pkg/controller/atlasinstance/atlasinstance_test.go new file mode 100644 index 0000000000..d009705bbe --- /dev/null +++ b/pkg/controller/atlasinstance/atlasinstance_test.go @@ -0,0 +1,464 @@ +// Copyright 2022 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package atlasinstance + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "reflect" + "testing" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "github.com/fgrosse/zaptest" + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" + "go.mongodb.org/atlas/mongodbatlas" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + dbaas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/common" + status "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1/status" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" +) + +func TestGetInstanceData(t *testing.T) { + log := zaptest.Logger(t).Sugar() + testCase := map[string]struct { + deploymentName string + projectName string + providerName string + regionName string + instanceSizeName string + expProviderName string + expRegionName string + expInstanceSizeName string + expErrMsg string + }{ + "Nominal": { + deploymentName: "myDeployment", + projectName: "myProject", + providerName: "GCP", + regionName: "GCP_REGION", + instanceSizeName: "M10", + expProviderName: "GCP", + expRegionName: "GCP_REGION", + expInstanceSizeName: "M10", + expErrMsg: "", + }, + "MissingDeploymentName": { + deploymentName: "", + projectName: "myProject", + providerName: "GCP", + regionName: "GCP_REGION", + instanceSizeName: "M10", + expProviderName: "GCP", + expRegionName: "GCP_REGION", + expInstanceSizeName: "M10", + expErrMsg: "missing clusterName", + }, + "MissingProjectName": { + deploymentName: "myDeployment", + projectName: "", + providerName: "GCP", + regionName: "GCP_REGION", + instanceSizeName: "M10", + expProviderName: "GCP", + expRegionName: "GCP_REGION", + expInstanceSizeName: "M10", + expErrMsg: "missing projectName", + }, + "UseDefaultProvider": { + deploymentName: "myDeployment", + projectName: "myProject", + providerName: "", + regionName: "AWS_REGION", + instanceSizeName: "M10", + expProviderName: "AWS", + expRegionName: "AWS_REGION", + expInstanceSizeName: "M10", + expErrMsg: "", + }, + "UseDefaultRegion": { + deploymentName: "myDeployment", + projectName: "myProject", + providerName: "AWS", + regionName: "", + instanceSizeName: "M10", + expProviderName: "AWS", + expRegionName: "US_EAST_1", + expInstanceSizeName: "M10", + expErrMsg: "", + }, + "UseDefaultInstanceSizeName": { + deploymentName: "myDeployment", + projectName: "myProject", + providerName: "AWS", + regionName: "US_EAST_1", + instanceSizeName: "", + expProviderName: "AWS", + expRegionName: "US_EAST_1", + expInstanceSizeName: "M0", + expErrMsg: "", + }, + } + + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + instance := &dbaas.MongoDBAtlasInstance{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInstance", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("instance-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInstanceSpec{ + InventoryRef: dbaasv1alpha1.NamespacedName{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + Name: tc.deploymentName, + CloudProvider: tc.providerName, + CloudRegion: tc.regionName, + OtherInstanceParams: map[string]string{ + "projectName": tc.projectName, + "instanceSizeName": tc.instanceSizeName, + }, + }, + } + + expected := &InstanceData{ + ProjectName: tc.projectName, + ClusterName: tc.deploymentName, + ProviderName: tc.expProviderName, + RegionName: tc.expRegionName, + InstanceSizeName: tc.expInstanceSizeName, + } + res, err := getInstanceData(log, instance) + if len(tc.expErrMsg) == 0 { + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(expected, res)) + } else { + assert.Equal(t, err.Error(), tc.expErrMsg) + } + }) + } +} + +const ( + // baseURLPath is a non-empty Client.BaseURL path to use during tests, + // to ensure relative URLs are used for all endpoints. + baseURLPath = "/api-v1" +) + +// setupMockAltasServer sets up a test HTTP server along with a mongodbatlas.Client that is +// configured to talk to that test server. Tests should register handlers on +// mux which provide mock responses for the API method being tested. +func setupMockAltasServer(t *testing.T) (client *mongodbatlas.Client, teardown func()) { + // mux is the HTTP request multiplexer used with the test server. + router := mux.NewRouter() + + // We want to ensure that tests catch mistakes where the endpoint URL is + // specified as absolute rather than relative. It only makes a difference + // when there's a non-empty base URL path. So, use that. + apiHandler := http.NewServeMux() + apiHandler.Handle(baseURLPath+"/", http.StripPrefix(baseURLPath, router)) + router.HandleFunc("/api/atlas/v1.0/groups/byName/{group-name}", func(w http.ResponseWriter, r *http.Request) { + if m := http.MethodGet; m != r.Method { + t.Errorf("Request method = %v, expected %v", r.Method, m) + } + vars := mux.Vars(r) + groupName, ok := vars["group-name"] + if !ok { + fmt.Fprint(w, "group-id is missing in parameters") + return + } + var data []byte + var err error + data, err = ioutil.ReadFile(fmt.Sprintf("../../../test/e2e/data/atlasprojectget_%s.json", groupName)) + if err == nil { + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(data)) + } else { + w.WriteHeader(http.StatusUnauthorized) + fmt.Fprint(w, "{\"detail\":\"The current user is not in the group, or the group does not exist.\",\"error\":401,\"errorCode\":\"NOT_IN_GROUP\",\"parameters\":[],\"reason\":\"Unauthorized\"}") + } + }).Methods(http.MethodGet) + + router.HandleFunc("/api/atlas/v1.0/groups/{group-id}/clusters/{deployment-name}", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + groupID, ok := vars["group-id"] + if !ok { + fmt.Fprint(w, "group-id is missing in parameters") + } + deploymentName, ok := vars["deployment-name"] + if !ok { + fmt.Fprint(w, "deployment-name is missing in parameters") + } + data, err := ioutil.ReadFile(fmt.Sprintf("../../../test/e2e/data/atlasdeploymentget_%s_%s.json", groupID, deploymentName)) + if err == nil { + assert.NoError(t, err) + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(data)) + } else { + w.WriteHeader(http.StatusNotFound) + f := "{\"detail\":\"No deployment named %s exists in group %s.\",\"error\":404,\"errorCode\":\"CLUSTER_NOT_FOUND\",\"parameters\":[\"%s\",\"groupid123\"],\"reason\":\"Not Found\"}" + fmt.Fprintf(w, f, deploymentName, groupID, deploymentName) + } + }).Methods(http.MethodGet) + + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + // client is the Atlas client being tested and is + // configured to use test server. + client = mongodbatlas.NewClient(nil) + u, _ := url.Parse(server.URL + baseURLPath + "/") + client.BaseURL = u + + return client, server.Close +} + +func TestSetInstanceStatusWithDeploymentInfo(t *testing.T) { + atlasClient, teardown := setupMockAltasServer(t) + defer teardown() + + namespace := "default" + testCase := map[string]struct { + deploymentName string + projectName string + expErrMsg string + expPhase dbaasv1alpha1.DBaasInstancePhase + expStatus string + }{ + "DeploymentCreating": { + deploymentName: "mydeploymentcreating", + projectName: "myproject", + expErrMsg: "", + expPhase: dbaasv1alpha1.InstancePhaseCreating, + expStatus: "True", + }, + "DeploymentReady": { + deploymentName: "mydeploymentready", + projectName: "myproject", + expErrMsg: "", + expPhase: dbaasv1alpha1.InstancePhaseReady, + expStatus: "True", + }, + "InvalidProject": { + deploymentName: "mydeploymentready", + projectName: "myproject-invalid", + expErrMsg: "NOT_IN_GROUP", + }, + } + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + atlasDeployment := &v1.AtlasDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment-free", + Namespace: namespace, + }, + Spec: v1.AtlasDeploymentSpec{ + Project: common.ResourceRefNamespaced{ + Name: "my-atlas-project-free", + Namespace: namespace, + }, + DeploymentSpec: &v1.DeploymentSpec{ + Name: tc.deploymentName, + ProviderSettings: &v1.ProviderSettingsSpec{ + BackingProviderName: "AWS", + InstanceSizeName: "M0", + ProviderName: "TENANT", + RegionName: "US_EAST_1", + }, + }, + }, + Status: status.AtlasDeploymentStatus{ + Common: status.Common{ + Conditions: []status.Condition{ + { + Type: status.ConditionType("Ready"), + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Now(), + }, + { + Type: status.ConditionType("DeploymentReady"), + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Now(), + }, + }, + }, + }, + } + inst := &dbaas.MongoDBAtlasInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-instance", + Namespace: namespace, + }, + Spec: dbaasv1alpha1.DBaaSInstanceSpec{ + InventoryRef: dbaasv1alpha1.NamespacedName{ + Name: "my-inventory", + Namespace: namespace, + }, + Name: tc.deploymentName, + OtherInstanceParams: map[string]string{ + "projectName": tc.projectName, + }, + }, + } + result := setInstanceStatusWithDeploymentInfo(atlasClient, inst, atlasDeployment, tc.projectName) + if len(tc.expErrMsg) == 0 { + cond := dbaas.GetInstanceCondition(inst, dbaasv1alpha1.DBaaSInstanceProviderSyncType) + assert.NotNil(t, cond) + assert.True(t, result.IsOk()) + assert.Equal(t, inst.Status.Phase, tc.expPhase) + assert.Equal(t, string(cond.Status), tc.expStatus) + } else { + assert.Contains(t, result.Message(), tc.expErrMsg) + } + }) + } +} + +func TestAtlasInstanceReconcile(t *testing.T) { + atlasClient, teardown := setupMockAltasServer(t) + defer teardown() + + s := scheme.Scheme + utilruntime.Must(scheme.AddToScheme(s)) + utilruntime.Must(v1.AddToScheme(s)) + utilruntime.Must(dbaas.AddToScheme(s)) + client := fake.NewClientBuilder().WithScheme(s).Build() + logger := zaptest.Logger(t) + + // Create a MongoDBAtlasInstanceReconciler object with the scheme and fake client. + r := &MongoDBAtlasInstanceReconciler{ + Client: client, + AtlasClient: atlasClient, + Scheme: s, + Log: logger.Sugar(), + ResourceWatcher: watch.NewResourceWatcher(), + } + + tcName := "mytest" + deploymentName := "mydeploymentnew" + projectName := "myproject" + expectedPhase := dbaasv1alpha1.InstancePhasePending + expectedErrString := "CLUSTER_NOT_FOUND" + expectedRequeue := true + inventory := &dbaas.MongoDBAtlasInventory{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInventory", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInventorySpec{ + CredentialsRef: &dbaasv1alpha1.LocalObjectReference{ + Name: fmt.Sprintf("secret-%s", tcName), + }, + }, + } + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("secret-%s", tcName), + Namespace: "dbaas-operator", + Labels: map[string]string{ + "atlas.mongodb.com/type": "credentials", + }, + }, + Data: map[string][]byte{ + "orgId": []byte("testorgid"), + "privateApiKey": []byte("testprivatekey"), + "publicApiKey": []byte("testpublickey"), + }, + } + + instance := &dbaas.MongoDBAtlasInstance{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInstance", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("instance-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInstanceSpec{ + Name: deploymentName, + InventoryRef: dbaasv1alpha1.NamespacedName{ + Name: inventory.Name, + Namespace: inventory.Namespace, + }, + OtherInstanceParams: map[string]string{ + "projectName": projectName, + }, + }, + } + err := client.Create(context.Background(), secret) + assert.NoError(t, err) + err = client.Create(context.Background(), inventory) + assert.NoError(t, err) + err = client.Create(context.Background(), instance) + assert.NoError(t, err) + + // Mock request to simulate Reconcile() being called on an event for a + // watched resource . + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: instance.Name, + Namespace: instance.Namespace, + }, + } + res, err := r.Reconcile(context.Background(), req) + if err != nil { + assert.Contains(t, err.Error(), expectedErrString) + } else { + assert.Equal(t, expectedRequeue, res.Requeue) + } + instanceUpdated := &dbaas.MongoDBAtlasInstance{} + err = client.Get(context.Background(), + types.NamespacedName{ + Name: instance.Name, + Namespace: instance.Namespace, + }, instanceUpdated) + assert.NoError(t, err) + assert.Equal(t, expectedPhase, instanceUpdated.Status.Phase) + + // After an instance is deleted, the corresponding atlas project should be deleted + delEvent := event.DeleteEvent{Object: instance} + err = r.Delete(delEvent) + assert.NoError(t, err) + atlasProject, err := r.getAtlasProject(context.Background(), instance) + assert.NoError(t, err) + assert.Nil(t, atlasProject) +} diff --git a/pkg/controller/atlasinventory/atlasinventory_controller.go b/pkg/controller/atlasinventory/atlasinventory_controller.go new file mode 100644 index 0000000000..69b42fc079 --- /dev/null +++ b/pkg/controller/atlasinventory/atlasinventory_controller.go @@ -0,0 +1,181 @@ +/* +Copyright 2021 MongoDB. + +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 atlasinventory + +import ( + "context" + + "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/source" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.mongodb.org/atlas/mongodbatlas" + + dbaas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/atlas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow" +) + +// MongoDBAtlasInventoryReconciler reconciles a MongoDBAtlasInventory object +type MongoDBAtlasInventoryReconciler struct { + Client client.Client + AtlasClient *mongodbatlas.Client + watch.ResourceWatcher + Log *zap.SugaredLogger + Scheme *runtime.Scheme + AtlasDomain string + GlobalAPISecret client.ObjectKey + EventRecorder record.EventRecorder +} + +// Dev note: duplicate the permissions in both sections below to generate both Role and ClusterRoles + +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasinventories,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=mongodbatlasinventories/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch + +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasinventories,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,namespace=default,resources=mongodbatlasinventories/status,verbs=get;update;patch +// +kubebuilder:rbac:groups="",namespace=default,resources=secrets,verbs=get;list;watch + +func (r *MongoDBAtlasInventoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = ctx + log := r.Log.With("MongoDBAtlasInventory", req.NamespacedName) + log.Info("Reconciling MongoDBAtlasInventory") + inventory := &dbaas.MongoDBAtlasInventory{} + if err := r.Client.Get(ctx, req.NamespacedName, inventory); err != nil { + if errors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("MongoDBAtlasInventory resource not found, has been deleted") + return ctrl.Result{}, nil + } + log.Error(err, "Error fetching MongoDBAtlasInventory for reconcile") + return ctrl.Result{}, err + } + + log.Infow("-> Starting MongoDBAtlasInventory reconciliation", "spec", inventory.Spec) + + // This update will make sure the status is always updated in case of any errors or successful result + defer func(inv *dbaas.MongoDBAtlasInventory) { + err := r.Client.Status().Update(ctx, inv) + if err != nil { + log.Infow("Could not update resource status:%v", err) + } + }(inventory) + + secretKey := inventory.ConnectionSecretObjectKey() + + if secretKey == nil { + result := workflow.Terminate(workflow.MongoDBAtlasInventoryInputError, "Secret name for atlas credentials is missing") + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } else { + // Note, that we are not watching the global connection secret - seems there is no point in reconciling all + // the services once that secret is changed + r.EnsureResourcesAreWatched(req.NamespacedName, "Secret", log, *secretKey) + } + + atlasConn, err := atlas.ReadConnection(log, r.Client, r.GlobalAPISecret, inventory.ConnectionSecretObjectKey()) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasInventoryInputError, err.Error()) + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + + atlasClient := r.AtlasClient + if atlasClient == nil { + cl, err := atlas.Client(r.AtlasDomain, atlasConn, log) + if err != nil { + result := workflow.Terminate(workflow.MongoDBAtlasConnectionBackendError, err.Error()) + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + atlasClient = &cl + } + + inventoryList, result := discoverInstances(atlasClient) + if !result.IsOk() { + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType, metav1.ConditionFalse, string(result.Reason()), result.Message()) + return result.ReconcileResult(), nil + } + + // Update the status + dbaas.SetInventoryCondition(inventory, dbaasv1alpha1.DBaaSInventoryProviderSyncType, metav1.ConditionTrue, string(workflow.MongoDBAtlasInventorySyncOK), "Spec sync OK") + inventory.Status.Instances = inventoryList + return ctrl.Result{}, nil +} + +// Delete is a no-op +func (r *MongoDBAtlasInventoryReconciler) Delete(e event.DeleteEvent) error { + return nil +} + +func (r *MongoDBAtlasInventoryReconciler) SetupWithManager(mgr ctrl.Manager) error { + c, err := controller.New("MongoDBAtlasInventory", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource MongoDBAtlasInventory & handle delete separately + err = c.Watch(&source.Kind{Type: &dbaas.MongoDBAtlasInventory{}}, + &watch.EventHandlerWithDelete{Controller: r}, + watch.CommonPredicates()) + if err != nil { + return err + } + + // Watch for changes to other resource MongoDBAtlasInstance + err = c.Watch(&source.Kind{Type: &dbaas.MongoDBAtlasInstance{}}, + handler.EnqueueRequestsFromMapFunc(instanceMapFunc)) + if err != nil { + return err + } + + // Watch for Connection Secrets + err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, watch.NewSecretHandler(r.WatchedResources)) + if err != nil { + return err + } + return nil +} + +// instanceMapFunc defines a function for EnqueueRequestsFromMapFunc so that when a MongoDBAtlasInstance +// CR status is updated or the CR is deleted, the corresponding inventory is enqueued in order to refresh +// the instance list +func instanceMapFunc(a client.Object) []ctrl.Request { + if instance, ok := a.(*dbaas.MongoDBAtlasInstance); ok { + return []ctrl.Request{ + {NamespacedName: types.NamespacedName{ + Name: instance.Spec.InventoryRef.Name, + Namespace: instance.Spec.InventoryRef.Namespace, + }, + }} + } + return nil +} diff --git a/pkg/controller/atlasinventory/inventory.go b/pkg/controller/atlasinventory/inventory.go new file mode 100644 index 0000000000..b6503b5e7a --- /dev/null +++ b/pkg/controller/atlasinventory/inventory.go @@ -0,0 +1,120 @@ +package atlasinventory + +import ( + "context" + "net/http" + "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/language" + + "go.mongodb.org/atlas/mongodbatlas" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/workflow" +) + +// discoverInstances query atlas and return list of instances found +func discoverInstances(atlasClient *mongodbatlas.Client) ([]dbaasv1alpha1.Instance, workflow.Result) { + // Try to find the service + projects, response, err := atlasClient.Projects.GetAllProjects(context.Background(), &mongodbatlas.ListOptions{}) + if err != nil { + return nil, workflow.Terminate(getReasonFromResponse(response), err.Error()) + } + processed := map[string]bool{} + instanceList := []dbaasv1alpha1.Instance{} + for _, p := range projects.Results { + if _, ok := processed[p.ID]; ok { + // This project ID has been processed. Move on to next. + continue + } + clusters, response, err := atlasClient.Clusters.List(context.Background(), p.ID, &mongodbatlas.ListOptions{}) + if err != nil { + return nil, workflow.Terminate(getReasonFromResponse(response), err.Error()) + } + for _, cluster := range clusters { + instanceList = append(instanceList, GetInstance(*p, cluster)) + } + processed[p.ID] = true + } + return instanceList, workflow.OK() +} + +func getReasonFromResponse(response *mongodbatlas.Response) workflow.ConditionReason { + reason := workflow.MongoDBAtlasInventoryBackendError + if response == nil { + return reason + } + if response.StatusCode == http.StatusUnauthorized { + reason = workflow.MongoDBAtlasInventoryAuthenticationError + } else if response.StatusCode == http.StatusBadGateway || response.StatusCode == http.StatusServiceUnavailable { + reason = workflow.MongoDBAtlasInventoryEndpointUnreachable + } + return reason +} + +// GetClusterInfo query atlas for the cluster and return the relevant data required by DBaaS Operator +func GetClusterInfo(atlasClient *mongodbatlas.Client, projectName, clusterName string) (*dbaasv1alpha1.Instance, workflow.Result) { + // Try to find the service + project, response, err := atlasClient.Projects.GetOneProjectByName(context.Background(), projectName) + if err != nil { + return nil, workflow.Terminate(getReasonFromResponse(response), err.Error()) + } + cluster, response, err := atlasClient.Clusters.Get(context.Background(), project.ID, clusterName) + if err != nil { + return nil, workflow.Terminate(getReasonFromResponse(response), err.Error()) + } + instance := GetInstance(*project, *cluster) + return &instance, workflow.OK() +} + +// GetInstance returns instance info as required by DBaaS Operator +func GetInstance(project mongodbatlas.Project, cluster mongodbatlas.Cluster) dbaasv1alpha1.Instance { + // Convert state names to "Creating", "Ready", "Deleting", "Deleted" etc. + // Pending - provisioning not yet started + // Creating - provisioning in progress + // Updating - cluster updating in progress + // Deleting - cluster deletion in progress + // Deleted - cluster has been deleted + // Ready - cluster provisioning complete + caser := cases.Title(language.AmericanEnglish) + phase := parsePhase(caser.String(strings.ToLower(cluster.StateName))) + provider := cluster.ProviderSettings.BackingProviderName + if len(provider) == 0 { + provider = cluster.ProviderSettings.ProviderName + } + return dbaasv1alpha1.Instance{ + InstanceID: cluster.ID, + Name: cluster.Name, + InstanceInfo: map[string]string{ + dbaas.InstanceSizeNameKey: cluster.ProviderSettings.InstanceSizeName, + dbaas.CloudProviderKey: provider, + dbaas.CloudRegionKey: cluster.ProviderSettings.RegionName, + dbaas.ProjectIDKey: project.ID, + dbaas.ProjectNameKey: project.Name, + dbaas.ConnectionStringsStandardSrvKey: cluster.ConnectionStrings.StandardSrv, + dbaas.ProvisionPhaseKey: string(phase), + }, + } +} + +func parsePhase(state string) dbaasv1alpha1.DBaasInstancePhase { + switch state { + case "Pending": + return dbaasv1alpha1.InstancePhasePending + case "Creating": + return dbaasv1alpha1.InstancePhaseCreating + case "Updating": + return dbaasv1alpha1.InstancePhaseUpdating + case "Deleting": + return dbaasv1alpha1.InstancePhaseDeleting + case "Deleted": + return dbaasv1alpha1.InstancePhaseDeleted + case "Ready", "Idle": + return dbaasv1alpha1.InstancePhaseReady + default: + return dbaasv1alpha1.InstancePhaseUnknown + } +} diff --git a/pkg/controller/atlasinventory/inventory_test.go b/pkg/controller/atlasinventory/inventory_test.go new file mode 100644 index 0000000000..25a1ed38d5 --- /dev/null +++ b/pkg/controller/atlasinventory/inventory_test.go @@ -0,0 +1,297 @@ +// Copyright 2021 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package atlasinventory + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "reflect" + "testing" + + "github.com/fgrosse/zaptest" + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + dbaasv1alpha1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.mongodb.org/atlas/mongodbatlas" + + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + "github.com/mongodb/mongodb-atlas-kubernetes/pkg/controller/watch" +) + +const ( + // baseURLPath is a non-empty Client.BaseURL path to use during tests, + // to ensure relative URLs are used for all endpoints. + baseURLPath = "/api-v1" +) + +var isSingleProjectWithoutCluster = false + +// setupMockAltasServer sets up a test HTTP server along with a mongodbatlas.Client that is +// configured to talk to that test server. Tests should register handlers on +// mux which provide mock responses for the API method being tested. +func setupMockAltasServer(t *testing.T) (client *mongodbatlas.Client, teardown func()) { + // mux is the HTTP request multiplexer used with the test server. + router := mux.NewRouter() + + // We want to ensure that tests catch mistakes where the endpoint URL is + // specified as absolute rather than relative. It only makes a difference + // when there's a non-empty base URL path. So, use that. + apiHandler := http.NewServeMux() + apiHandler.Handle(baseURLPath+"/", http.StripPrefix(baseURLPath, router)) + router.HandleFunc("/api/atlas/v1.0/groups", func(w http.ResponseWriter, r *http.Request) { + if m := http.MethodGet; m != r.Method { + t.Errorf("Request method = %v, expected %v", r.Method, m) + } + var data []byte + var err error + if isSingleProjectWithoutCluster { + data, err = ioutil.ReadFile("../../../test/e2e/data/atlasprojectlistresp_single.json") + } else { + data, err = ioutil.ReadFile("../../../test/e2e/data/atlasprojectlistresp.json") + } + assert.NoError(t, err) + if err == nil { + fmt.Fprint(w, string(data)) + } + }).Methods(http.MethodGet) + + router.HandleFunc("/api/atlas/v1.0/groups/{group-id}/clusters", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + groupID, ok := vars["group-id"] + if !ok { + fmt.Fprint(w, "group-id is missing in parameters") + } + data, err := ioutil.ReadFile(fmt.Sprintf("../../../test/e2e/data/atlasdeploymentlistresp_%s.json", groupID)) + assert.NoError(t, err) + if err == nil { + fmt.Fprint(w, string(data)) + } + }).Methods(http.MethodGet) + + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + // client is the Atlas client being tested and is + // configured to use test server. + client = mongodbatlas.NewClient(nil) + u, _ := url.Parse(server.URL + baseURLPath + "/") + client.BaseURL = u + + return client, server.Close +} + +// Test special case for instance discovery: nominal +func TestDiscoverInstancesNominal(t *testing.T) { + isSingleProjectWithoutCluster = false + client, teardown := setupMockAltasServer(t) + defer teardown() + + instances, res := discoverInstances(client) + assert.True(t, res.IsOk()) + instancesExpected := []dbaasv1alpha1.Instance{} + dataExpected, err := ioutil.ReadFile("../../../test/e2e/data/atlasinventoryexpected.json") + assert.NoError(t, err) + err = json.Unmarshal(dataExpected, &instancesExpected) + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(instancesExpected, instances)) +} + +// Test special case for instance discovery: no instances found +func TestDiscoverInstancesEmpty(t *testing.T) { + isSingleProjectWithoutCluster = true + client, teardown := setupMockAltasServer(t) + defer teardown() + + instances, res := discoverInstances(client) + assert.True(t, res.IsOk()) + assert.True(t, len(instances) == 0) +} + +func TestAtlasInventoryReconcile(t *testing.T) { + isSingleProjectWithoutCluster = false + atlasClient, teardown := setupMockAltasServer(t) + defer teardown() + + s := scheme.Scheme + utilruntime.Must(scheme.AddToScheme(s)) + utilruntime.Must(mdbv1.AddToScheme(s)) + utilruntime.Must(dbaas.AddToScheme(s)) + + client := fake.NewClientBuilder().WithScheme(s).Build() + + logger := zaptest.Logger(t) + + // Create a MongoDBAtlasInventoryReconciler object with the scheme and fake client. + r := &MongoDBAtlasInventoryReconciler{ + Client: client, + AtlasClient: atlasClient, + Scheme: s, + Log: logger.Sugar(), + ResourceWatcher: watch.NewResourceWatcher(), + } + + testCase := map[string]struct { + createInventory bool + createSecret bool + expectedRequeue bool + expectedErrString string + expectedReadyCondition string + expectedReasonString string + expectedInstancesPath string + }{ + "Nominal": { + createInventory: true, + createSecret: true, + expectedReadyCondition: "True", + expectedReasonString: "SyncOK", + expectedInstancesPath: "../../../test/e2e/data/atlasinventoryexpected.json", + expectedErrString: "", + expectedRequeue: false, + }, + "InventoryCRNotFound": { + createInventory: false, + createSecret: false, + expectedReadyCondition: "", + expectedReasonString: "", + expectedInstancesPath: "", + expectedErrString: "", + expectedRequeue: false, + }, + "SecretNotFound": { + createInventory: true, + createSecret: false, + expectedReadyCondition: "False", + expectedReasonString: "InputError", + expectedInstancesPath: "", + expectedErrString: "", + expectedRequeue: false, + }, + "NoCredentialRef": { + createInventory: true, + createSecret: false, + expectedReadyCondition: "False", + expectedReasonString: "InputError", + expectedInstancesPath: "", + expectedErrString: "", + expectedRequeue: false, + }, + } + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + inventory := &dbaas.MongoDBAtlasInventory{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "dbaas.redhat.com/v1alpha1", + Kind: "MongoDBAtlasInventory", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("inventory-%s", tcName), + Namespace: "dbaas-operator", + }, + Spec: dbaasv1alpha1.DBaaSInventorySpec{ + CredentialsRef: &dbaasv1alpha1.LocalObjectReference{ + Name: fmt.Sprintf("secret-%s", tcName), + }, + }, + } + if tcName == "NoCredentialRef" { + inventory.Spec.CredentialsRef = nil + } + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("secret-%s", tcName), + Namespace: "dbaas-operator", + Labels: map[string]string{ + "atlas.mongodb.com/type": "credentials", + }, + }, + Data: map[string][]byte{ + "orgId": []byte("testorgid"), + "privateApiKey": []byte("testprivatekey"), + "publicApiKey": []byte("testpublickey"), + }, + } + if tc.createInventory { + err := client.Create(context.Background(), inventory) + assert.NoError(t, err) + } + if tc.createSecret { + err := client.Create(context.Background(), secret) + assert.NoError(t, err) + } + // Mock request to simulate Reconcile() being called on an event for a + // watched resource . + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: inventory.Name, + Namespace: inventory.Namespace, + }, + } + + res, err := r.Reconcile(context.Background(), req) + if err != nil { + assert.Contains(t, err, tc.expectedErrString) + // Move on to next test case + return + } + assert.Equal(t, tc.expectedRequeue, res.Requeue) + if tcName == "InventoryCRNotFound" { + // Special case: the CR does not exist + // No further checking is needed + return + } + inventoryUpdated := &dbaas.MongoDBAtlasInventory{} + err = client.Get(context.Background(), + types.NamespacedName{ + Name: inventory.Name, + Namespace: inventory.Namespace, + }, inventoryUpdated) + assert.NoError(t, err) + + if len(tc.expectedReadyCondition) > 0 { + assert.Equal(t, tc.expectedReadyCondition, string(inventoryUpdated.Status.Conditions[0].Status)) + assert.Equal(t, tc.expectedReasonString, inventoryUpdated.Status.Conditions[0].Reason) + } + + if len(tc.expectedInstancesPath) == 0 { + // No need to check discovered instances + // Move on to next test case + return + } + instancesExpected := []dbaasv1alpha1.Instance{} + dataExpected, err := ioutil.ReadFile("../../../test/e2e/data/atlasinventoryexpected.json") + assert.NoError(t, err) + err = json.Unmarshal(dataExpected, &instancesExpected) + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(instancesExpected, inventoryUpdated.Status.Instances)) + }) + } +} diff --git a/pkg/controller/atlasproject/atlasproject_controller.go b/pkg/controller/atlasproject/atlasproject_controller.go index c79f8b0969..f3dd8d246c 100644 --- a/pkg/controller/atlasproject/atlasproject_controller.go +++ b/pkg/controller/atlasproject/atlasproject_controller.go @@ -107,9 +107,11 @@ func (r *AtlasProjectReconciler) Reconcile(context context.Context, req ctrl.Req connection, err := atlas.ReadConnection(log, r.Client, r.GlobalAPISecret, project.ConnectionSecretObjectKey()) if err != nil { - if errRm := r.removeDeletionFinalizer(context, project); errRm != nil { - result = workflow.Terminate(workflow.Internal, errRm.Error()) - setCondition(ctx, status.DeploymentReadyType, result) + if !project.GetDeletionTimestamp().IsZero() && isDeletionFinalizerPresent(project) { + if errRm := r.removeDeletionFinalizer(context, project); errRm != nil { + result = workflow.Terminate(workflow.Internal, errRm.Error()) + setCondition(ctx, status.DeploymentReadyType, result) + } } result = workflow.Terminate(workflow.AtlasCredentialsNotProvided, err.Error()) setCondition(ctx, status.ProjectReadyType, result) diff --git a/pkg/controller/customresource/customresource.go b/pkg/controller/customresource/customresource.go index 861e8671e0..f6270712db 100644 --- a/pkg/controller/customresource/customresource.go +++ b/pkg/controller/customresource/customresource.go @@ -5,6 +5,7 @@ import ( "go.uber.org/zap" apiErrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -24,17 +25,23 @@ const ( // PrepareResource queries the Custom Resource 'request.NamespacedName' and populates the 'resource' pointer. func PrepareResource(client client.Client, request reconcile.Request, resource mdbv1.AtlasCustomResource, log *zap.SugaredLogger) workflow.Result { - err := client.Get(context.Background(), request.NamespacedName, resource) + return GetResource(client, request.Namespace, request.Name, resource, log) +} + +// GetResource queries the Custom Resource key and populates the 'resource' pointer. +func GetResource(client client.Client, namespace, name string, resource client.Object, log *zap.SugaredLogger) workflow.Result { + key := types.NamespacedName{Namespace: namespace, Name: name} + err := client.Get(context.Background(), key, resource) if err != nil { if apiErrors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. // Return and don't requeue - log.Debugf("Object %s doesn't exist, was it deleted after reconcile request?", request.NamespacedName) + log.Debugf("Object %s doesn't exist, was it deleted after reconcile request?", key) return workflow.TerminateSilently().WithoutRetry() } // Error reading the object - requeue the request. Note, that we don't intend to update resource status // as most of all it will fail as well. - log.Errorf("Failed to query object %s: %s", request.NamespacedName, err) + log.Errorf("Failed to query object %s: %s", key, err) return workflow.TerminateSilently() } diff --git a/pkg/controller/dbaasprovider/dbaasprovider_reconciler.go b/pkg/controller/dbaasprovider/dbaasprovider_reconciler.go new file mode 100644 index 0000000000..d56fa94921 --- /dev/null +++ b/pkg/controller/dbaasprovider/dbaasprovider_reconciler.go @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2010 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dbaasprovider + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + "time" + + dbaasoperator "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + "go.uber.org/zap" + v1 "k8s.io/api/apps/v1" + rbac "k8s.io/api/rbac/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + label "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/workqueue" + "k8s.io/utils/pointer" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +const ( + resourceName = "mongodb-atlas-registration" + dbaasProviderKind = "DBaaSProvider" + defaultProviderFile = "./dbaas_provider.yaml" +) + +type DBaaSProviderReconciler struct { + client.Client + *runtime.Scheme + Log *zap.SugaredLogger + Clientset kubernetes.Interface + operatorNameVersion string + operatorInstallNamespace string + providerFile string + cdrChecker func(groupVersion, kind string) (bool, error) +} + +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=dbaasproviders,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=dbaas.redhat.com,resources=dbaasproviders/status,verbs=get;update;patch + +func (r *DBaaSProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := r.Log.With("DBaaSProvider Reconciler", req.NamespacedName) + + // due to predicate filtering, we'll only reconcile this operator's own deployment when it's seen the first time + // meaning we have a reconcile entry-point on operator start-up, so now we can create a cluster-scoped resource + // owned by the operator's ClusterRole to ensure cleanup on uninstall + + dep := &v1.Deployment{} + if err := r.Get(ctx, req.NamespacedName, dep); err != nil { + if apiErrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("deployment not found, deleted, no requeue") + return ctrl.Result{}, nil + } + // error fetching deployment, requeue and try again + log.Error(err, "error fetching Deployment CR") + return ctrl.Result{}, err + } + + if r.cdrChecker == nil { + r.cdrChecker = r.checkCrdInstalled + } + isCrdInstalled, err := r.cdrChecker(dbaasoperator.GroupVersion.String(), dbaasProviderKind) + if err != nil { + log.Error(err, "error discovering GVK") + return ctrl.Result{}, err + } + if !isCrdInstalled { + log.Info("CRD not found, requeueing with rate limiter") + // returning with 'Requeue: true' will invoke our custom rate limiter seen in SetupWithManager below + return ctrl.Result{Requeue: true}, nil + } + + instance := &dbaasoperator.DBaaSProvider{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + }, + } + if err := r.Get(ctx, client.ObjectKeyFromObject(instance), instance); err != nil { + if apiErrors.IsNotFound(err) { + log.Info("resource not found, creating now") + // Atlas registration custom resource isn't present,so create now with ClusterRole owner for GC + opts := &client.ListOptions{ + LabelSelector: label.SelectorFromSet(map[string]string{ + "olm.owner": r.operatorNameVersion, + "olm.owner.kind": "ClusterServiceVersion", + }), + } + clusterRoleList := &rbac.ClusterRoleList{} + if err := r.List(context.Background(), clusterRoleList, opts); err != nil { + log.Error(err, "unable to list ClusterRoles to seek potential operand owners") + return ctrl.Result{}, err + } + + if len(clusterRoleList.Items) < 1 { + err := apiErrors.NewNotFound( + schema.GroupResource{Group: "rbac.authorization.k8s.io", Resource: "ClusterRole"}, "potentialOwner") + log.Error(err, "could not find ClusterRole owned by CSV to inherit operand") + return ctrl.Result{}, err + } + + instance, err := r.getAtlasProviderCR(clusterRoleList) + if err != nil { + log.Error(err, "error while constructing new cluster-scoped Atlas DbaaS provider CR") + return ctrl.Result{}, err + } + if err = r.Create(ctx, instance); err != nil { + log.Error(err, "error while creating new cluster-scoped resource") + return ctrl.Result{}, err + } else { + log.Info("cluster-scoped resource created") + return ctrl.Result{}, nil + } + } + // error fetching the resource, requeue and try again + log.Error(err, "error fetching the resource") + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil +} + +// getAtlasProviderCR CR for MongoDB Atlas DBaaS registration +func (r *DBaaSProviderReconciler) getAtlasProviderCR(clusterRoleList *rbac.ClusterRoleList) (*dbaasoperator.DBaaSProvider, error) { + d, err := ioutil.ReadFile(r.providerFile) + if err != nil { + return nil, err + } + jsonData, err := yaml.ToJSON(d) + if err != nil { + return nil, err + } + instance := &dbaasoperator.DBaaSProvider{} + err = json.Unmarshal(jsonData, instance) + if err != nil { + return nil, err + } + instance.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRole", + UID: clusterRoleList.Items[0].GetUID(), // doesn't really matter which 'item' we use + Name: clusterRoleList.Items[0].Name, + Controller: pointer.BoolPtr(true), + BlockOwnerDeletion: pointer.BoolPtr(false), + }, + } + return instance, nil +} + +// CheckCrdInstalled checks whether dbaas provider CRD, has been created yet +func (r *DBaaSProviderReconciler) checkCrdInstalled(groupVersion, kind string) (bool, error) { + resources, err := r.Clientset.Discovery().ServerResourcesForGroupVersion(groupVersion) + if err != nil { + if apiErrors.IsNotFound(err) { + return false, nil + } + return false, fmt.Errorf("failed to check DBaaSProvider CRD:%w", err) + } + for _, r := range resources.APIResources { + if r.Kind == kind { + return true, nil + } + } + return false, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *DBaaSProviderReconciler) SetupWithManager(mgr ctrl.Manager) error { + // envVar set in controller-manager's Deployment YAML + if operatorInstallNamespace, found := os.LookupEnv("OPERATOR_NAMESPACE"); !found { + return errors.New("OPERATOR_NAMESPACE must be set") + } else { + r.operatorInstallNamespace = operatorInstallNamespace + } + + // envVar set for all operators + if operatorNameEnvVar, found := os.LookupEnv("OPERATOR_CONDITION_NAME"); !found { + return errors.New("OPERATOR_CONDITION_NAME must be set") + } else { + r.operatorNameVersion = operatorNameEnvVar + } + + // envVar set for directory for dbaas_provider.yaml + if providerFileEnvVar, found := os.LookupEnv("DBAAS_PROVIDER_FILE"); !found { + r.providerFile = defaultProviderFile + } else { + r.providerFile = providerFileEnvVar + } + + customRateLimiter := workqueue.NewItemExponentialFailureRateLimiter(30*time.Second, 30*time.Minute) + + return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{RateLimiter: customRateLimiter}). + For( + &v1.Deployment{}, + builder.WithPredicates(r.ignoreOtherDeployments()), + builder.OnlyMetadata, + ). + Complete(r) +} + +// ignoreOtherDeployments only on a 'create' event is issued for the deployment +func (r *DBaaSProviderReconciler) ignoreOtherDeployments() predicate.Predicate { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return r.evaluatePredicateObject(e.Object) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return false + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return false + }, + GenericFunc: func(e event.GenericEvent) bool { + return false + }, + } +} + +func (r *DBaaSProviderReconciler) evaluatePredicateObject(obj client.Object) bool { + lbls := obj.GetLabels() + if obj.GetNamespace() == r.operatorInstallNamespace { + if val, keyFound := lbls["olm.owner.kind"]; keyFound { + if val == "ClusterServiceVersion" { + if val, keyFound := lbls["olm.owner"]; keyFound { + return val == r.operatorNameVersion + } + } + } + } + return false +} diff --git a/pkg/controller/dbaasprovider/dbaasprovider_test.go b/pkg/controller/dbaasprovider/dbaasprovider_test.go new file mode 100644 index 0000000000..0ad0e48419 --- /dev/null +++ b/pkg/controller/dbaasprovider/dbaasprovider_test.go @@ -0,0 +1,156 @@ +// Copyright 2021 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbaasprovider + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "testing" + + "github.com/fgrosse/zaptest" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/apps/v1" + rbac "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + k8sfake "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + dbaasoperator "github.com/RHEcosystemAppEng/dbaas-operator/api/v1alpha1" + + dbaas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/dbaas" + mdbv1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" +) + +const mongDBAtlasOperatorLabel = "mongodb-atlas-kubernetes.v0.0.0" + +func TestDBaaSProviderCreate(t *testing.T) { + s := scheme.Scheme + utilruntime.Must(scheme.AddToScheme(s)) + utilruntime.Must(mdbv1.AddToScheme(s)) + utilruntime.Must(dbaas.AddToScheme(s)) + logger := zaptest.Logger(t) + + testCase := map[string]struct { + crdChecker func(groupVersion, kind string) (bool, error) + expectedRequeue bool + expectedErrString string + }{ + "Nominal": { + crdChecker: cdrCheckerOK, + expectedErrString: "", + expectedRequeue: false, + }, + "CRDCheckFail": { + crdChecker: cdrCheckerFail, + expectedErrString: "failed to check DBaaSProvider CRD", + expectedRequeue: false, + }, + "CRDCheckNotFound": { + crdChecker: cdrCheckerNotFound, + expectedErrString: "", + expectedRequeue: true, + }, + } + for tcName, tc := range testCase { + t.Run(tcName, func(t *testing.T) { + d := &v1.Deployment{} + data, err := ioutil.ReadFile("../../../test/e2e/data/dummy_deployment.json") + assert.NoError(t, err) + err = json.Unmarshal(data, d) + assert.NoError(t, err) + + gvk := schema.GroupVersionKind{ + Group: "dbaas.redhat.com", + Version: "v1alpha1", + Kind: "DBaaSProvider", + } + clusterrole := &rbac.ClusterRole{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRole", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("mongodb-atlas-kubernetes-%s", tcName), + Namespace: "dbaas-operator", + Labels: map[string]string{ + "olm.owner": mongDBAtlasOperatorLabel, + "olm.owner.kind": "ClusterServiceVersion", + }, + }, + } + + // Register DBaaSProvider CRD with the scheme + s.AddKnownTypeWithName(gvk, &dbaasoperator.DBaaSProvider{}) + // Create a fake client with the objects + client := fake.NewClientBuilder().WithRuntimeObjects(d, clusterrole).WithScheme(s).Build() + // Create a fake clientset + clientSet := k8sfake.NewSimpleClientset() + + // Mock request to simulate Reconcile() being called on an event for a + // watched resource. + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: d.Name, + Namespace: d.Namespace, + }, + } + // Create a MongoDBAtlasInventoryReconciler object with the scheme and fake client. + r := &DBaaSProviderReconciler{ + Client: client, + Clientset: clientSet, + Scheme: s, + Log: logger.Sugar(), + cdrChecker: tc.crdChecker, + operatorNameVersion: mongDBAtlasOperatorLabel, + providerFile: "../../../config/dbaasprovider/dbaas_provider.yaml", + } + + res, err := r.Reconcile(context.Background(), req) + if err != nil { + assert.Contains(t, err.Error(), tc.expectedErrString) + // Move on to next test case + return + } + assert.Equal(t, tc.expectedRequeue, res.Requeue) + if res.Requeue { + // Move on to next test case + return + } + // Check the dbaasprovider CR has been created + instance := &dbaasoperator.DBaaSProvider{} + err = r.Client.Get(context.Background(), types.NamespacedName{Name: resourceName}, instance) + assert.NoError(t, err) + }) + } +} + +// Mock functions to to check DBaaSProvider CRD +func cdrCheckerOK(groupVersion, kind string) (bool, error) { + return true, nil +} +func cdrCheckerNotFound(groupVersion, kind string) (bool, error) { + return false, nil +} +func cdrCheckerFail(groupVersion, kind string) (bool, error) { + return false, errors.New("failed to check DBaaSProvider CRD:") +} diff --git a/pkg/controller/workflow/reason.go b/pkg/controller/workflow/reason.go index 0762e3b127..b84dae9b68 100644 --- a/pkg/controller/workflow/reason.go +++ b/pkg/controller/workflow/reason.go @@ -38,6 +38,8 @@ const ( DeploymentNotUpdatedInAtlas ConditionReason = "DeploymentNotUpdatedInAtlas" DeploymentCreating ConditionReason = "DeploymentCreating" DeploymentUpdating ConditionReason = "DeploymentUpdating" + DeploymentDeleting ConditionReason = "DeploymentDeleting" + DeploymentDeleted ConditionReason = "DeploymentDeleted" DeploymentConnectionSecretsNotCreated ConditionReason = "DeploymentConnectionSecretsNotCreated" DeploymentAdvancedOptionsAreNotReady ConditionReason = "DeploymentAdvancedOptionsAreNotReady" ) @@ -52,3 +54,35 @@ const ( DatabaseUserInvalidSpec ConditionReason = "DatabaseUserInvalidSpec" DatabaseUserExpired ConditionReason = "DatabaseUserExpired" ) + +// MongoDBAtlasInventory reasons +const ( + MongoDBAtlasInventorySyncOK ConditionReason = "SyncOK" + MongoDBAtlasInventoryInputError ConditionReason = "InputError" + MongoDBAtlasInventoryBackendError ConditionReason = "BackendError" + MongoDBAtlasInventoryEndpointUnreachable ConditionReason = "EndpointUnreachable" + MongoDBAtlasInventoryAuthenticationError ConditionReason = "AuthenticationError" +) + +// MongoDBAtlasConnection reasons +const ( + MongoDBAtlasConnectionReady ConditionReason = "Ready" + MongoDBAtlasConnectionAtlasUnreachable ConditionReason = "Unreachable" + MongoDBAtlasConnectionInventoryNotReady ConditionReason = "InventoryNotReady" + MongoDBAtlasConnectionInventoryNotFound ConditionReason = "InventoryNotFound" + MongoDBAtlasConnectionInstanceIDNotFound ConditionReason = "InstanceIDNotFound" + MongoDBAtlasConnectionBackendError ConditionReason = "BackendError" + MongoDBAtlasConnectionAuthenticationError ConditionReason = "AuthenticationError" + MongoDBAtlasConnectionInprogress ConditionReason = "Inprogress" +) + +// MongoDBAtlasInstance reasons +const ( + MongoDBAtlasInstanceReady ConditionReason = "Ready" + MongoDBAtlasInstanceAtlasUnreachable ConditionReason = "Unreachable" + MongoDBAtlasInstanceInventoryNotFound ConditionReason = "InventoryNotFound" + MongoDBAtlasInstanceClusterNotFound ConditionReason = "AtlasClusterNotFound" + MongoDBAtlasInstanceBackendError ConditionReason = "BackendError" + MongoDBAtlasInstanceAuthenticationError ConditionReason = "AuthenticationError" + MongoDBAtlasInstanceInprogress ConditionReason = "Inprogress" +) diff --git a/pkg/controller/workflow/result.go b/pkg/controller/workflow/result.go index 12e1ee0c96..8b69adb490 100644 --- a/pkg/controller/workflow/result.go +++ b/pkg/controller/workflow/result.go @@ -97,3 +97,11 @@ func (r Result) ReconcileResult() reconcile.Result { } return reconcile.Result{RequeueAfter: r.requeueAfter} } + +func (r Result) Reason() ConditionReason { + return r.reason +} + +func (r Result) Message() string { + return r.message +} diff --git a/scripts/build_catalog.sh b/scripts/build_catalog.sh index bacf77a6d3..701d00cecb 100755 --- a/scripts/build_catalog.sh +++ b/scripts/build_catalog.sh @@ -28,6 +28,11 @@ if [ -z "${VERSION+x}" ]; then exit 1 fi +if [ -z "${CONTAINER_ENGINE+x}" ]; then + echo "CONTAINER_ENGINE is not set" + exit 1 +fi + rm -f "${CATALOG_DIR}"/operator.yaml rm -f "${CATALOG_DIR}"/channel.yaml rm -f "$(dirname "${CATALOG_DIR}")"/atlas-catalog.Dockerfile @@ -59,4 +64,4 @@ echo "Validating catalog..." opm validate "${CATALOG_DIR}" echo "Catalog is valid" echo "Building catalog image" -cd "$(dirname "${CATALOG_DIR}")" && docker build . -f atlas-catalog.Dockerfile -t "${CATALOG_IMAGE}" +cd "$(dirname "${CATALOG_DIR}")" && ${CONTAINER_ENGINE} build . -f atlas-catalog.Dockerfile -t "${CATALOG_IMAGE}" diff --git a/scripts/openshift/atlas-catalog.Dockerfile b/scripts/openshift/atlas-catalog.Dockerfile deleted file mode 100644 index e5f7912b1d..0000000000 --- a/scripts/openshift/atlas-catalog.Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -# The base image is expected to contain -# /bin/opm (with a serve subcommand) and /bin/grpc_health_probe -FROM quay.io/operator-framework/opm:latest - -# Configure the entrypoint and command -ENTRYPOINT ["/bin/opm"] -CMD ["serve", "/configs"] - -# Copy declarative config root into image at /configs -ADD atlas-catalog /configs - -# Set DC-specific label for the location of the DC root directory -# in the image -LABEL operators.operatorframework.io.index.configs.v1=/configs diff --git a/scripts/openshift/atlas-catalog/operator.yaml b/scripts/openshift/atlas-catalog/operator.yaml index 1eed7ffa67..e69de29bb2 100644 --- a/scripts/openshift/atlas-catalog/operator.yaml +++ b/scripts/openshift/atlas-catalog/operator.yaml @@ -1,52 +0,0 @@ ---- -defaultChannel: beta -name: mongodb-atlas-kubernetes -schema: olm.package ---- -image: docker.io/ikarpukhin/mongodb-atlas-controller-bundle:0.5.0 -name: mongodb-atlas-kubernetes.v0.5.0 -package: mongodb-atlas-kubernetes -properties: -- type: olm.gvk - value: - group: atlas.mongodb.com - kind: AtlasDeployment - version: v1 -- type: olm.gvk - value: - group: atlas.mongodb.com - kind: AtlasDatabaseUser - version: v1 -- type: olm.gvk - value: - group: atlas.mongodb.com - kind: AtlasProject - version: v1 -- type: olm.package - value: - packageName: mongodb-atlas-kubernetes - version: 0.5.0 -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiY29udHJvbGxlci1nZW4ua3ViZWJ1aWxkZXIuaW8vdmVyc2lvbiI6InYwLjQuMSJ9LCJjcmVhdGlvblRpbWVzdGFtcCI6bnVsbCwibGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ImNvbnRyb2xsZXIiLCJhcHAua3ViZXJuZXRlcy5pby9pbnN0YW5jZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciIsImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiJtb25nb2RiLWF0bGFzLWt1YmVybmV0ZXMtb3BlcmF0b3IifSwibmFtZSI6ImF0bGFzY2x1c3RlcnMuYXRsYXMubW9uZ29kYi5jb20ifSwic3BlYyI6eyJncm91cCI6ImF0bGFzLm1vbmdvZGIuY29tIiwibmFtZXMiOnsia2luZCI6IkF0bGFzQ2x1c3RlciIsImxpc3RLaW5kIjoiQXRsYXNDbHVzdGVyTGlzdCIsInBsdXJhbCI6ImF0bGFzY2x1c3RlcnMiLCJzaW5ndWxhciI6ImF0bGFzY2x1c3RlciJ9LCJzY29wZSI6Ik5hbWVzcGFjZWQiLCJ2ZXJzaW9ucyI6W3sibmFtZSI6InYxIiwic2NoZW1hIjp7Im9wZW5BUElWM1NjaGVtYSI6eyJkZXNjcmlwdGlvbiI6IkF0bGFzQ2x1c3RlciBpcyB0aGUgU2NoZW1hIGZvciB0aGUgYXRsYXNjbHVzdGVycyBBUEkiLCJwcm9wZXJ0aWVzIjp7ImFwaVZlcnNpb24iOnsiZGVzY3JpcHRpb24iOiJBUElWZXJzaW9uIGRlZmluZXMgdGhlIHZlcnNpb25lZCBzY2hlbWEgb2YgdGhpcyByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QuIFNlcnZlcnMgc2hvdWxkIGNvbnZlcnQgcmVjb2duaXplZCBzY2hlbWFzIHRvIHRoZSBsYXRlc3QgaW50ZXJuYWwgdmFsdWUsIGFuZCBtYXkgcmVqZWN0IHVucmVjb2duaXplZCB2YWx1ZXMuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjcmVzb3VyY2VzIiwidHlwZSI6InN0cmluZyJ9LCJraW5kIjp7ImRlc2NyaXB0aW9uIjoiS2luZCBpcyBhIHN0cmluZyB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIFJFU1QgcmVzb3VyY2UgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4gU2VydmVycyBtYXkgaW5mZXIgdGhpcyBmcm9tIHRoZSBlbmRwb2ludCB0aGUgY2xpZW50IHN1Ym1pdHMgcmVxdWVzdHMgdG8uIENhbm5vdCBiZSB1cGRhdGVkLiBJbiBDYW1lbENhc2UuIE1vcmUgaW5mbzogaHR0cHM6Ly9naXQuazhzLmlvL2NvbW11bml0eS9jb250cmlidXRvcnMvZGV2ZWwvc2lnLWFyY2hpdGVjdHVyZS9hcGktY29udmVudGlvbnMubWQjdHlwZXMta2luZHMiLCJ0eXBlIjoic3RyaW5nIn0sIm1ldGFkYXRhIjp7InR5cGUiOiJvYmplY3QifSwic3BlYyI6eyJkZXNjcmlwdGlvbiI6IkF0bGFzQ2x1c3RlclNwZWMgZGVmaW5lcyB0aGUgZGVzaXJlZCBzdGF0ZSBvZiBBdGxhc0NsdXN0ZXIiLCJwcm9wZXJ0aWVzIjp7ImF1dG9TY2FsaW5nIjp7ImRlc2NyaXB0aW9uIjoiQ29sbGVjdGlvbiBvZiBzZXR0aW5ncyB0aGF0IGNvbmZpZ3VyZXMgYXV0by1zY2FsaW5nIGluZm9ybWF0aW9uIGZvciB0aGUgY2x1c3Rlci4gSWYgeW91IHNwZWNpZnkgdGhlIGF1dG9TY2FsaW5nIG9iamVjdCwgeW91IG11c3QgYWxzbyBzcGVjaWZ5IHRoZSBwcm92aWRlclNldHRpbmdzLmF1dG9TY2FsaW5nIG9iamVjdC4iLCJwcm9wZXJ0aWVzIjp7ImF1dG9JbmRleGluZ0VuYWJsZWQiOnsiZGVzY3JpcHRpb24iOiJGbGFnIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgYXV0b3BpbG90IG1vZGUgZm9yIFBlcmZvcm1hbmNlIEFkdmlzb3IgaXMgZW5hYmxlZC4gVGhlIGRlZmF1bHQgaXMgZmFsc2UuIiwidHlwZSI6ImJvb2xlYW4ifSwiY29tcHV0ZSI6eyJkZXNjcmlwdGlvbiI6IkNvbGxlY3Rpb24gb2Ygc2V0dGluZ3MgdGhhdCBjb25maWd1cmUgaG93IGEgY2x1c3RlciBtaWdodCBzY2FsZSBpdHMgY2x1c3RlciB0aWVyIGFuZCB3aGV0aGVyIHRoZSBjbHVzdGVyIGNhbiBzY2FsZSBkb3duLiIsInByb3BlcnRpZXMiOnsiZW5hYmxlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciBjbHVzdGVyIHRpZXIgYXV0by1zY2FsaW5nIGlzIGVuYWJsZWQuIFRoZSBkZWZhdWx0IGlzIGZhbHNlLiIsInR5cGUiOiJib29sZWFuIn0sIm1heEluc3RhbmNlU2l6ZSI6eyJkZXNjcmlwdGlvbiI6Ik1heGltdW0gaW5zdGFuY2Ugc2l6ZSB0byB3aGljaCB5b3VyIGNsdXN0ZXIgY2FuIGF1dG9tYXRpY2FsbHkgc2NhbGUgKHN1Y2ggYXMgTTQwKS4gQXRsYXMgcmVxdWlyZXMgdGhpcyBwYXJhbWV0ZXIgaWYgXCJhdXRvU2NhbGluZy5jb21wdXRlLmVuYWJsZWRcIiA6IHRydWUuIiwidHlwZSI6InN0cmluZyJ9LCJtaW5JbnN0YW5jZVNpemUiOnsiZGVzY3JpcHRpb24iOiJNaW5pbXVtIGluc3RhbmNlIHNpemUgdG8gd2hpY2ggeW91ciBjbHVzdGVyIGNhbiBhdXRvbWF0aWNhbGx5IHNjYWxlIChzdWNoIGFzIE0xMCkuIEF0bGFzIHJlcXVpcmVzIHRoaXMgcGFyYW1ldGVyIGlmIFwiYXV0b1NjYWxpbmcuY29tcHV0ZS5zY2FsZURvd25FbmFibGVkXCIgOiB0cnVlLiIsInR5cGUiOiJzdHJpbmcifSwic2NhbGVEb3duRW5hYmxlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY2x1c3RlciB0aWVyIG1heSBzY2FsZSBkb3duLiBBdGxhcyByZXF1aXJlcyB0aGlzIHBhcmFtZXRlciBpZiBcImF1dG9TY2FsaW5nLmNvbXB1dGUuZW5hYmxlZFwiIDogdHJ1ZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwidHlwZSI6Im9iamVjdCJ9LCJkaXNrR0JFbmFibGVkIjp7ImRlc2NyaXB0aW9uIjoiRmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIGRpc2sgYXV0by1zY2FsaW5nIGlzIGVuYWJsZWQuIFRoZSBkZWZhdWx0IGlzIHRydWUuIiwidHlwZSI6ImJvb2xlYW4ifX0sInR5cGUiOiJvYmplY3QifSwiYmlDb25uZWN0b3IiOnsiZGVzY3JpcHRpb24iOiJDb25maWd1cmF0aW9uIG9mIEJJIENvbm5lY3RvciBmb3IgQXRsYXMgb24gdGhpcyBjbHVzdGVyLiBUaGUgTW9uZ29EQiBDb25uZWN0b3IgZm9yIEJ1c2luZXNzIEludGVsbGlnZW5jZSBmb3IgQXRsYXMgKEJJIENvbm5lY3RvcikgaXMgb25seSBhdmFpbGFibGUgZm9yIE0xMCBhbmQgbGFyZ2VyIGNsdXN0ZXJzLiIsInByb3BlcnRpZXMiOnsiZW5hYmxlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciBvciBub3QgQkkgQ29ubmVjdG9yIGZvciBBdGxhcyBpcyBlbmFibGVkIG9uIHRoZSBjbHVzdGVyLiIsInR5cGUiOiJib29sZWFuIn0sInJlYWRQcmVmZXJlbmNlIjp7ImRlc2NyaXB0aW9uIjoiU291cmNlIGZyb20gd2hpY2ggdGhlIEJJIENvbm5lY3RvciBmb3IgQXRsYXMgcmVhZHMgZGF0YS4gRWFjaCBCSSBDb25uZWN0b3IgZm9yIEF0bGFzIHJlYWQgcHJlZmVyZW5jZSBjb250YWlucyBhIGRpc3RpbmN0IGNvbWJpbmF0aW9uIG9mIHJlYWRQcmVmZXJlbmNlIGFuZCByZWFkUHJlZmVyZW5jZVRhZ3Mgb3B0aW9ucy4iLCJ0eXBlIjoic3RyaW5nIn19LCJ0eXBlIjoib2JqZWN0In0sImNsdXN0ZXJUeXBlIjp7ImRlc2NyaXB0aW9uIjoiVHlwZSBvZiB0aGUgY2x1c3RlciB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZS4gVGhlIHBhcmFtZXRlciBpcyByZXF1aXJlZCBpZiByZXBsaWNhdGlvblNwZWNzIGFyZSBzZXQgb3IgaWYgR2xvYmFsIENsdXN0ZXJzIGFyZSBkZXBsb3llZC4iLCJlbnVtIjpbIlJFUExJQ0FTRVQiLCJTSEFSREVEIiwiR0VPU0hBUkRFRCJdLCJ0eXBlIjoic3RyaW5nIn0sImRpc2tTaXplR0IiOnsiZGVzY3JpcHRpb24iOiJDYXBhY2l0eSwgaW4gZ2lnYWJ5dGVzLCBvZiB0aGUgaG9zdCdzIHJvb3Qgdm9sdW1lLiBJbmNyZWFzZSB0aGlzIG51bWJlciB0byBhZGQgY2FwYWNpdHksIHVwIHRvIGEgbWF4aW11bSBwb3NzaWJsZSB2YWx1ZSBvZiA0MDk2IChpLmUuLCA0IFRCKS4gVGhpcyB2YWx1ZSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlci4gVGhlIHBhcmFtZXRlciBpcyByZXF1aXJlZCBpZiByZXBsaWNhdGlvblNwZWNzIGFyZSBjb25maWd1cmVkLiIsIm1heGltdW0iOjQwOTYsIm1pbmltdW0iOjAsInR5cGUiOiJpbnRlZ2VyIn0sImVuY3J5cHRpb25BdFJlc3RQcm92aWRlciI6eyJkZXNjcmlwdGlvbiI6IkNsb3VkIHNlcnZpY2UgcHJvdmlkZXIgdGhhdCBvZmZlcnMgRW5jcnlwdGlvbiBhdCBSZXN0LiIsImVudW0iOlsiQVdTIiwiR0NQIiwiQVpVUkUiLCJOT05FIl0sInR5cGUiOiJzdHJpbmcifSwibGFiZWxzIjp7ImRlc2NyaXB0aW9uIjoiQ29sbGVjdGlvbiBvZiBrZXktdmFsdWUgcGFpcnMgdGhhdCB0YWcgYW5kIGNhdGVnb3JpemUgdGhlIGNsdXN0ZXIuIEVhY2gga2V5IGFuZCB2YWx1ZSBoYXMgYSBtYXhpbXVtIGxlbmd0aCBvZiAyNTUgY2hhcmFjdGVycy4iLCJpdGVtcyI6eyJkZXNjcmlwdGlvbiI6IkxhYmVsU3BlYyBjb250YWlucyBrZXktdmFsdWUgcGFpcnMgdGhhdCB0YWcgYW5kIGNhdGVnb3JpemUgdGhlIENsdXN0ZXIvREJVc2VyIiwicHJvcGVydGllcyI6eyJrZXkiOnsibWF4TGVuZ3RoIjoyNTUsInR5cGUiOiJzdHJpbmcifSwidmFsdWUiOnsidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsia2V5IiwidmFsdWUiXSwidHlwZSI6Im9iamVjdCJ9LCJ0eXBlIjoiYXJyYXkifSwibW9uZ29EQk1ham9yVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IlZlcnNpb24gb2YgdGhlIGNsdXN0ZXIgdG8gZGVwbG95LiIsInR5cGUiOiJzdHJpbmcifSwibmFtZSI6eyJkZXNjcmlwdGlvbiI6Ik5hbWUgb2YgdGhlIGNsdXN0ZXIgYXMgaXQgYXBwZWFycyBpbiBBdGxhcy4gQWZ0ZXIgQXRsYXMgY3JlYXRlcyB0aGUgY2x1c3RlciwgeW91IGNhbid0IGNoYW5nZSBpdHMgbmFtZS4iLCJ0eXBlIjoic3RyaW5nIn0sIm51bVNoYXJkcyI6eyJkZXNjcmlwdGlvbiI6IlBvc2l0aXZlIGludGVnZXIgdGhhdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBzaGFyZHMgdG8gZGVwbG95IGZvciBhIHNoYXJkZWQgY2x1c3Rlci4gVGhlIHBhcmFtZXRlciBpcyByZXF1aXJlZCBpZiByZXBsaWNhdGlvblNwZWNzIGFyZSBjb25maWd1cmVkIiwibWF4aW11bSI6NTAsIm1pbmltdW0iOjEsInR5cGUiOiJpbnRlZ2VyIn0sInBhdXNlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY2x1c3RlciBzaG91bGQgYmUgcGF1c2VkLiIsInR5cGUiOiJib29sZWFuIn0sInBpdEVuYWJsZWQiOnsiZGVzY3JpcHRpb24iOiJGbGFnIHRoYXQgaW5kaWNhdGVzIHRoZSBjbHVzdGVyIHVzZXMgY29udGludW91cyBjbG91ZCBiYWNrdXBzLiIsInR5cGUiOiJib29sZWFuIn0sInByb2plY3RSZWYiOnsiZGVzY3JpcHRpb24iOiJQcm9qZWN0IGlzIGEgcmVmZXJlbmNlIHRvIEF0bGFzUHJvamVjdCByZXNvdXJjZSB0aGUgY2x1c3RlciBiZWxvbmdzIHRvIiwicHJvcGVydGllcyI6eyJuYW1lIjp7ImRlc2NyaXB0aW9uIjoiTmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgS3ViZXJuZXRlcyBSZXNvdXJjZSIsInR5cGUiOiJzdHJpbmcifSwibmFtZXNwYWNlIjp7ImRlc2NyaXB0aW9uIjoiTmFtZXNwYWNlIGlzIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIEt1YmVybmV0ZXMgUmVzb3VyY2UiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInR5cGUiOiJvYmplY3QifSwicHJvdmlkZXJCYWNrdXBFbmFibGVkIjp7ImRlc2NyaXB0aW9uIjoiQXBwbGljYWJsZSBvbmx5IGZvciBNMTArIGNsdXN0ZXJzLiBGbGFnIHRoYXQgaW5kaWNhdGVzIGlmIHRoZSBjbHVzdGVyIHVzZXMgQ2xvdWQgQmFja3VwcyBmb3IgYmFja3Vwcy4iLCJ0eXBlIjoiYm9vbGVhbiJ9LCJwcm92aWRlclNldHRpbmdzIjp7ImRlc2NyaXB0aW9uIjoiQ29uZmlndXJhdGlvbiBmb3IgdGhlIHByb3Zpc2lvbmVkIGhvc3RzIG9uIHdoaWNoIE1vbmdvREIgcnVucy4gVGhlIGF2YWlsYWJsZSBvcHRpb25zIGFyZSBzcGVjaWZpYyB0byB0aGUgY2xvdWQgc2VydmljZSBwcm92aWRlci4iLCJwcm9wZXJ0aWVzIjp7ImF1dG9TY2FsaW5nIjp7ImRlc2NyaXB0aW9uIjoiUmFuZ2Ugb2YgaW5zdGFuY2Ugc2l6ZXMgdG8gd2hpY2ggeW91ciBjbHVzdGVyIGNhbiBzY2FsZS4iLCJwcm9wZXJ0aWVzIjp7ImF1dG9JbmRleGluZ0VuYWJsZWQiOnsiZGVzY3JpcHRpb24iOiJGbGFnIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgYXV0b3BpbG90IG1vZGUgZm9yIFBlcmZvcm1hbmNlIEFkdmlzb3IgaXMgZW5hYmxlZC4gVGhlIGRlZmF1bHQgaXMgZmFsc2UuIiwidHlwZSI6ImJvb2xlYW4ifSwiY29tcHV0ZSI6eyJkZXNjcmlwdGlvbiI6IkNvbGxlY3Rpb24gb2Ygc2V0dGluZ3MgdGhhdCBjb25maWd1cmUgaG93IGEgY2x1c3RlciBtaWdodCBzY2FsZSBpdHMgY2x1c3RlciB0aWVyIGFuZCB3aGV0aGVyIHRoZSBjbHVzdGVyIGNhbiBzY2FsZSBkb3duLiIsInByb3BlcnRpZXMiOnsiZW5hYmxlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciBjbHVzdGVyIHRpZXIgYXV0by1zY2FsaW5nIGlzIGVuYWJsZWQuIFRoZSBkZWZhdWx0IGlzIGZhbHNlLiIsInR5cGUiOiJib29sZWFuIn0sIm1heEluc3RhbmNlU2l6ZSI6eyJkZXNjcmlwdGlvbiI6Ik1heGltdW0gaW5zdGFuY2Ugc2l6ZSB0byB3aGljaCB5b3VyIGNsdXN0ZXIgY2FuIGF1dG9tYXRpY2FsbHkgc2NhbGUgKHN1Y2ggYXMgTTQwKS4gQXRsYXMgcmVxdWlyZXMgdGhpcyBwYXJhbWV0ZXIgaWYgXCJhdXRvU2NhbGluZy5jb21wdXRlLmVuYWJsZWRcIiA6IHRydWUuIiwidHlwZSI6InN0cmluZyJ9LCJtaW5JbnN0YW5jZVNpemUiOnsiZGVzY3JpcHRpb24iOiJNaW5pbXVtIGluc3RhbmNlIHNpemUgdG8gd2hpY2ggeW91ciBjbHVzdGVyIGNhbiBhdXRvbWF0aWNhbGx5IHNjYWxlIChzdWNoIGFzIE0xMCkuIEF0bGFzIHJlcXVpcmVzIHRoaXMgcGFyYW1ldGVyIGlmIFwiYXV0b1NjYWxpbmcuY29tcHV0ZS5zY2FsZURvd25FbmFibGVkXCIgOiB0cnVlLiIsInR5cGUiOiJzdHJpbmcifSwic2NhbGVEb3duRW5hYmxlZCI6eyJkZXNjcmlwdGlvbiI6IkZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY2x1c3RlciB0aWVyIG1heSBzY2FsZSBkb3duLiBBdGxhcyByZXF1aXJlcyB0aGlzIHBhcmFtZXRlciBpZiBcImF1dG9TY2FsaW5nLmNvbXB1dGUuZW5hYmxlZFwiIDogdHJ1ZS4iLCJ0eXBlIjoiYm9vbGVhbiJ9fSwidHlwZSI6Im9iamVjdCJ9LCJkaXNrR0JFbmFibGVkIjp7ImRlc2NyaXB0aW9uIjoiRmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIGRpc2sgYXV0by1zY2FsaW5nIGlzIGVuYWJsZWQuIFRoZSBkZWZhdWx0IGlzIHRydWUuIiwidHlwZSI6ImJvb2xlYW4ifX0sInR5cGUiOiJvYmplY3QifSwiYmFja2luZ1Byb3ZpZGVyTmFtZSI6eyJkZXNjcmlwdGlvbiI6IkNsb3VkIHNlcnZpY2UgcHJvdmlkZXIgb24gd2hpY2ggdGhlIGhvc3QgZm9yIGEgbXVsdGktdGVuYW50IGNsdXN0ZXIgaXMgcHJvdmlzaW9uZWQuIFRoaXMgc2V0dGluZyBvbmx5IHdvcmtzIHdoZW4gXCJwcm92aWRlclNldHRpbmcucHJvdmlkZXJOYW1lXCIgOiBcIlRFTkFOVFwiIGFuZCBcInByb3ZpZGVyU2V0dGluZy5pbnN0YW5jZVNpemVOYW1lXCIgOiBNMiBvciBNNS4iLCJlbnVtIjpbIkFXUyIsIkdDUCIsIkFaVVJFIl0sInR5cGUiOiJzdHJpbmcifSwiZGlza0lPUFMiOnsiZGVzY3JpcHRpb24iOiJEaXNrIElPUFMgc2V0dGluZyBmb3IgQVdTIHN0b3JhZ2UuIFNldCBvbmx5IGlmIHlvdSBzZWxlY3RlZCBBV1MgYXMgeW91ciBjbG91ZCBzZXJ2aWNlIHByb3ZpZGVyLiIsImZvcm1hdCI6ImludDY0IiwidHlwZSI6ImludGVnZXIifSwiZGlza1R5cGVOYW1lIjp7ImRlc2NyaXB0aW9uIjoiVHlwZSBvZiBkaXNrIGlmIHlvdSBzZWxlY3RlZCBBenVyZSBhcyB5b3VyIGNsb3VkIHNlcnZpY2UgcHJvdmlkZXIuIiwidHlwZSI6InN0cmluZyJ9LCJlbmNyeXB0RUJTVm9sdW1lIjp7ImRlc2NyaXB0aW9uIjoiRmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRoZSBBbWF6b24gRUJTIGVuY3J5cHRpb24gZmVhdHVyZSBlbmNyeXB0cyB0aGUgaG9zdCdzIHJvb3Qgdm9sdW1lIGZvciBib3RoIGRhdGEgYXQgcmVzdCB3aXRoaW4gdGhlIHZvbHVtZSBhbmQgZm9yIGRhdGEgbW92aW5nIGJldHdlZW4gdGhlIHZvbHVtZSBhbmQgdGhlIGNsdXN0ZXIuIiwidHlwZSI6ImJvb2xlYW4ifSwiaW5zdGFuY2VTaXplTmFtZSI6eyJkZXNjcmlwdGlvbiI6IkF0bGFzIHByb3ZpZGVzIGRpZmZlcmVudCBjbHVzdGVyIHRpZXJzLCBlYWNoIHdpdGggYSBkZWZhdWx0IHN0b3JhZ2UgY2FwYWNpdHkgYW5kIFJBTSBzaXplLiBUaGUgY2x1c3RlciB5b3Ugc2VsZWN0IGlzIHVzZWQgZm9yIGFsbCB0aGUgZGF0YS1iZWFyaW5nIGhvc3RzIGluIHlvdXIgY2x1c3RlciB0aWVyLiIsInR5cGUiOiJzdHJpbmcifSwicHJvdmlkZXJOYW1lIjp7ImRlc2NyaXB0aW9uIjoiQ2xvdWQgc2VydmljZSBwcm92aWRlciBvbiB3aGljaCBBdGxhcyBwcm92aXNpb25zIHRoZSBob3N0cy4iLCJlbnVtIjpbIkFXUyIsIkdDUCIsIkFaVVJFIiwiVEVOQU5UIl0sInR5cGUiOiJzdHJpbmcifSwicmVnaW9uTmFtZSI6eyJkZXNjcmlwdGlvbiI6IlBoeXNpY2FsIGxvY2F0aW9uIG9mIHlvdXIgTW9uZ29EQiBjbHVzdGVyLiBUaGUgcmVnaW9uIHlvdSBjaG9vc2UgY2FuIGFmZmVjdCBuZXR3b3JrIGxhdGVuY3kgZm9yIGNsaWVudHMgYWNjZXNzaW5nIHlvdXIgZGF0YWJhc2VzLiIsInR5cGUiOiJzdHJpbmcifSwidm9sdW1lVHlwZSI6eyJkZXNjcmlwdGlvbiI6IkRpc2sgSU9QUyBzZXR0aW5nIGZvciBBV1Mgc3RvcmFnZS4gU2V0IG9ubHkgaWYgeW91IHNlbGVjdGVkIEFXUyBhcyB5b3VyIGNsb3VkIHNlcnZpY2UgcHJvdmlkZXIuIiwiZW51bSI6WyJTVEFOREFSRCIsIlBST1ZJU0lPTkVEIl0sInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImluc3RhbmNlU2l6ZU5hbWUiLCJwcm92aWRlck5hbWUiXSwidHlwZSI6Im9iamVjdCJ9LCJyZXBsaWNhdGlvblNwZWNzIjp7ImRlc2NyaXB0aW9uIjoiQ29uZmlndXJhdGlvbiBmb3IgY2x1c3RlciByZWdpb25zLiIsIml0ZW1zIjp7ImRlc2NyaXB0aW9uIjoiUmVwbGljYXRpb25TcGVjIHJlcHJlc2VudHMgYSBjb25maWd1cmF0aW9uIGZvciBjbHVzdGVyIHJlZ2lvbnMiLCJwcm9wZXJ0aWVzIjp7Im51bVNoYXJkcyI6eyJkZXNjcmlwdGlvbiI6Ik51bWJlciBvZiBzaGFyZHMgdG8gZGVwbG95IGluIGVhY2ggc3BlY2lmaWVkIHpvbmUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDEuIiwiZm9ybWF0IjoiaW50NjQiLCJ0eXBlIjoiaW50ZWdlciJ9LCJyZWdpb25zQ29uZmlnIjp7ImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjp7ImRlc2NyaXB0aW9uIjoiUmVnaW9uc0NvbmZpZyBkZXNjcmliZXMgdGhlIHJlZ2lvbuKAmXMgcHJpb3JpdHkgaW4gZWxlY3Rpb25zIGFuZCB0aGUgbnVtYmVyIGFuZCB0eXBlIG9mIE1vbmdvREIgbm9kZXMgQXRsYXMgZGVwbG95cyB0byB0aGUgcmVnaW9uLiIsInByb3BlcnRpZXMiOnsiYW5hbHl0aWNzTm9kZXMiOnsiZGVzY3JpcHRpb24iOiJUaGUgbnVtYmVyIG9mIGFuYWx5dGljcyBub2RlcyBmb3IgQXRsYXMgdG8gZGVwbG95IHRvIHRoZSByZWdpb24uIEFuYWx5dGljcyBub2RlcyBhcmUgdXNlZnVsIGZvciBoYW5kbGluZyBhbmFseXRpYyBkYXRhIHN1Y2ggYXMgcmVwb3J0aW5nIHF1ZXJpZXMgZnJvbSBCSSBDb25uZWN0b3IgZm9yIEF0bGFzLiBBbmFseXRpY3Mgbm9kZXMgYXJlIHJlYWQtb25seSwgYW5kIGNhbiBuZXZlciBiZWNvbWUgdGhlIHByaW1hcnkuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSB0aGlzIG9wdGlvbiwgbm8gYW5hbHl0aWNzIG5vZGVzIGFyZSBkZXBsb3llZCB0byB0aGUgcmVnaW9uLiIsImZvcm1hdCI6ImludDY0IiwidHlwZSI6ImludGVnZXIifSwiZWxlY3RhYmxlTm9kZXMiOnsiZGVzY3JpcHRpb24iOiJOdW1iZXIgb2YgZWxlY3RhYmxlIG5vZGVzIGZvciBBdGxhcyB0byBkZXBsb3kgdG8gdGhlIHJlZ2lvbi4gRWxlY3RhYmxlIG5vZGVzIGNhbiBiZWNvbWUgdGhlIHByaW1hcnkgYW5kIGNhbiBmYWNpbGl0YXRlIGxvY2FsIHJlYWRzLiIsImZvcm1hdCI6ImludDY0IiwidHlwZSI6ImludGVnZXIifSwicHJpb3JpdHkiOnsiZGVzY3JpcHRpb24iOiJFbGVjdGlvbiBwcmlvcml0eSBvZiB0aGUgcmVnaW9uLiBGb3IgcmVnaW9ucyB3aXRoIG9ubHkgcmVwbGljYXRpb25TcGVjc1tuXS5yZWdpb25zQ29uZmlnLlx1MDAzY3JlZ2lvblx1MDAzZS5yZWFkT25seU5vZGVzLCBzZXQgdGhpcyB2YWx1ZSB0byAwLiIsImZvcm1hdCI6ImludDY0IiwidHlwZSI6ImludGVnZXIifSwicmVhZE9ubHlOb2RlcyI6eyJkZXNjcmlwdGlvbiI6Ik51bWJlciBvZiByZWFkLW9ubHkgbm9kZXMgZm9yIEF0bGFzIHRvIGRlcGxveSB0byB0aGUgcmVnaW9uLiBSZWFkLW9ubHkgbm9kZXMgY2FuIG5ldmVyIGJlY29tZSB0aGUgcHJpbWFyeSwgYnV0IGNhbiBmYWNpbGl0YXRlIGxvY2FsLXJlYWRzLiIsImZvcm1hdCI6ImludDY0IiwidHlwZSI6ImludGVnZXIifX0sInR5cGUiOiJvYmplY3QifSwiZGVzY3JpcHRpb24iOiJDb25maWd1cmF0aW9uIGZvciBhIHJlZ2lvbi4gRWFjaCByZWdpb25zQ29uZmlnIG9iamVjdCBkZXNjcmliZXMgdGhlIHJlZ2lvbidzIHByaW9yaXR5IGluIGVsZWN0aW9ucyBhbmQgdGhlIG51bWJlciBhbmQgdHlwZSBvZiBNb25nb0RCIG5vZGVzIHRoYXQgQXRsYXMgZGVwbG95cyB0byB0aGUgcmVnaW9uLiIsInR5cGUiOiJvYmplY3QifSwiem9uZU5hbWUiOnsiZGVzY3JpcHRpb24iOiJOYW1lIGZvciB0aGUgem9uZSBpbiBhIEdsb2JhbCBDbHVzdGVyLiBEb24ndCBwcm92aWRlIHRoaXMgdmFsdWUgaWYgY2x1c3RlclR5cGUgaXMgbm90IEdFT1NIQVJERUQuIiwidHlwZSI6InN0cmluZyJ9fSwidHlwZSI6Im9iamVjdCJ9LCJ0eXBlIjoiYXJyYXkifX0sInJlcXVpcmVkIjpbIm5hbWUiLCJwcm9qZWN0UmVmIiwicHJvdmlkZXJTZXR0aW5ncyJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IkF0bGFzQ2x1c3RlclN0YXR1cyBkZWZpbmVzIHRoZSBvYnNlcnZlZCBzdGF0ZSBvZiBBdGxhc0NsdXN0ZXIuIiwicHJvcGVydGllcyI6eyJjb25kaXRpb25zIjp7ImRlc2NyaXB0aW9uIjoiQ29uZGl0aW9ucyBpcyB0aGUgbGlzdCBvZiBzdGF0dXNlcyBzaG93aW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBBdGxhcyBDdXN0b20gUmVzb3VyY2UiLCJpdGVtcyI6eyJkZXNjcmlwdGlvbiI6IkNvbmRpdGlvbiBkZXNjcmliZXMgdGhlIHN0YXRlIG9mIGFuIEF0bGFzIEN1c3RvbSBSZXNvdXJjZSBhdCBhIGNlcnRhaW4gcG9pbnQuIiwicHJvcGVydGllcyI6eyJsYXN0VHJhbnNpdGlvblRpbWUiOnsiZGVzY3JpcHRpb24iOiJMYXN0IHRpbWUgdGhlIGNvbmRpdGlvbiB0cmFuc2l0aW9uZWQgZnJvbSBvbmUgc3RhdHVzIHRvIGFub3RoZXIuIiwiZm9ybWF0IjoiZGF0ZS10aW1lIiwidHlwZSI6InN0cmluZyJ9LCJtZXNzYWdlIjp7ImRlc2NyaXB0aW9uIjoiQSBodW1hbiByZWFkYWJsZSBtZXNzYWdlIGluZGljYXRpbmcgZGV0YWlscyBhYm91dCB0aGUgdHJhbnNpdGlvbi4iLCJ0eXBlIjoic3RyaW5nIn0sInJlYXNvbiI6eyJkZXNjcmlwdGlvbiI6IlRoZSByZWFzb24gZm9yIHRoZSBjb25kaXRpb24ncyBsYXN0IHRyYW5zaXRpb24uIiwidHlwZSI6InN0cmluZyJ9LCJzdGF0dXMiOnsiZGVzY3JpcHRpb24iOiJTdGF0dXMgb2YgdGhlIGNvbmRpdGlvbiwgb25lIG9mIFRydWUsIEZhbHNlLCBVbmtub3duLiIsInR5cGUiOiJzdHJpbmcifSwidHlwZSI6eyJkZXNjcmlwdGlvbiI6IlR5cGUgb2YgQXRsYXMgQ3VzdG9tIFJlc291cmNlIGNvbmRpdGlvbi4iLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJzdGF0dXMiLCJ0eXBlIl0sInR5cGUiOiJvYmplY3QifSwidHlwZSI6ImFycmF5In0sImNvbm5lY3Rpb25TdHJpbmdzIjp7ImRlc2NyaXB0aW9uIjoiQ29ubmVjdGlvblN0cmluZ3MgaXMgYSBzZXQgb2YgY29ubmVjdGlvbiBzdHJpbmdzIHRoYXQgeW91ciBhcHBsaWNhdGlvbnMgdXNlIHRvIGNvbm5lY3QgdG8gdGhpcyBjbHVzdGVyLiIsInByb3BlcnRpZXMiOnsicHJpdmF0ZSI6eyJkZXNjcmlwdGlvbiI6Ik5ldHdvcmstcGVlcmluZy1lbmRwb2ludC1hd2FyZSBtb25nb2RiOi8vIGNvbm5lY3Rpb24gc3RyaW5ncyBmb3IgZWFjaCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50IHlvdSBjb25maWd1cmVkIHRvIGNvbm5lY3QgdG8gdGhpcyBjbHVzdGVyLiBBdGxhcyByZXR1cm5zIHRoaXMgcGFyYW1ldGVyIG9ubHkgaWYgeW91IGNyZWF0ZWQgYSBuZXR3b3JrIHBlZXJpbmcgY29ubmVjdGlvbiB0byB0aGlzIGNsdXN0ZXIuIiwidHlwZSI6InN0cmluZyJ9LCJwcml2YXRlRW5kcG9pbnQiOnsiZGVzY3JpcHRpb24iOiJQcml2YXRlIGVuZHBvaW50IGNvbm5lY3Rpb24gc3RyaW5ncy4gRWFjaCBvYmplY3QgZGVzY3JpYmVzIHRoZSBjb25uZWN0aW9uIHN0cmluZ3MgeW91IGNhbiB1c2UgdG8gY29ubmVjdCB0byB0aGlzIGNsdXN0ZXIgdGhyb3VnaCBhIHByaXZhdGUgZW5kcG9pbnQuIEF0bGFzIHJldHVybnMgdGhpcyBwYXJhbWV0ZXIgb25seSBpZiB5b3UgZGVwbG95ZWQgYSBwcml2YXRlIGVuZHBvaW50IHRvIGFsbCByZWdpb25zIHRvIHdoaWNoIHlvdSBkZXBsb3llZCB0aGlzIGNsdXN0ZXIncyBub2Rlcy4iLCJpdGVtcyI6eyJkZXNjcmlwdGlvbiI6IlByaXZhdGVFbmRwb2ludCBjb25uZWN0aW9uIHN0cmluZ3MuIEVhY2ggb2JqZWN0IGRlc2NyaWJlcyB0aGUgY29ubmVjdGlvbiBzdHJpbmdzIHlvdSBjYW4gdXNlIHRvIGNvbm5lY3QgdG8gdGhpcyBjbHVzdGVyIHRocm91Z2ggYSBwcml2YXRlIGVuZHBvaW50LiBBdGxhcyByZXR1cm5zIHRoaXMgcGFyYW1ldGVyIG9ubHkgaWYgeW91IGRlcGxveWVkIGEgcHJpdmF0ZSBlbmRwb2ludCB0byBhbGwgcmVnaW9ucyB0byB3aGljaCB5b3UgZGVwbG95ZWQgdGhpcyBjbHVzdGVyJ3Mgbm9kZXMuIiwicHJvcGVydGllcyI6eyJjb25uZWN0aW9uU3RyaW5nIjp7ImRlc2NyaXB0aW9uIjoiUHJpdmF0ZS1lbmRwb2ludC1hd2FyZSBtb25nb2RiOi8vIGNvbm5lY3Rpb24gc3RyaW5nIGZvciB0aGlzIHByaXZhdGUgZW5kcG9pbnQuIiwidHlwZSI6InN0cmluZyJ9LCJlbmRwb2ludHMiOnsiZGVzY3JpcHRpb24iOiJQcml2YXRlIGVuZHBvaW50IHRocm91Z2ggd2hpY2ggeW91IGNvbm5lY3QgdG8gQXRsYXMgd2hlbiB5b3UgdXNlIGNvbm5lY3Rpb25TdHJpbmdzLnByaXZhdGVFbmRwb2ludFtuXS5jb25uZWN0aW9uU3RyaW5nIG9yIGNvbm5lY3Rpb25TdHJpbmdzLnByaXZhdGVFbmRwb2ludFtuXS5zcnZDb25uZWN0aW9uU3RyaW5nLiIsIml0ZW1zIjp7ImRlc2NyaXB0aW9uIjoiRW5kcG9pbnQgdGhyb3VnaCB3aGljaCB5b3UgY29ubmVjdCB0byBBdGxhcyIsInByb3BlcnRpZXMiOnsiZW5kcG9pbnRJZCI6eyJkZXNjcmlwdGlvbiI6IlVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBwcml2YXRlIGVuZHBvaW50LiIsInR5cGUiOiJzdHJpbmcifSwiaXAiOnsiZGVzY3JpcHRpb24iOiJQcml2YXRlIElQIGFkZHJlc3Mgb2YgdGhlIHByaXZhdGUgZW5kcG9pbnQgbmV0d29yayBpbnRlcmZhY2UgeW91IGNyZWF0ZWQgaW4geW91ciBBenVyZSBWTmV0LiIsInR5cGUiOiJzdHJpbmcifSwicHJvdmlkZXJOYW1lIjp7ImRlc2NyaXB0aW9uIjoiQ2xvdWQgcHJvdmlkZXIgdG8gd2hpY2ggeW91IGRlcGxveWVkIHRoZSBwcml2YXRlIGVuZHBvaW50LiBBdGxhcyByZXR1cm5zIEFXUyBvciBBWlVSRS4iLCJ0eXBlIjoic3RyaW5nIn0sInJlZ2lvbiI6eyJkZXNjcmlwdGlvbiI6IlJlZ2lvbiB0byB3aGljaCB5b3UgZGVwbG95ZWQgdGhlIHByaXZhdGUgZW5kcG9pbnQuIiwidHlwZSI6InN0cmluZyJ9fSwidHlwZSI6Im9iamVjdCJ9LCJ0eXBlIjoiYXJyYXkifSwic3J2Q29ubmVjdGlvblN0cmluZyI6eyJkZXNjcmlwdGlvbiI6IlByaXZhdGUtZW5kcG9pbnQtYXdhcmUgbW9uZ29kYitzcnY6Ly8gY29ubmVjdGlvbiBzdHJpbmcgZm9yIHRoaXMgcHJpdmF0ZSBlbmRwb2ludC4iLCJ0eXBlIjoic3RyaW5nIn0sInR5cGUiOnsiZGVzY3JpcHRpb24iOiJUeXBlIG9mIE1vbmdvREIgcHJvY2VzcyB0aGF0IHlvdSBjb25uZWN0IHRvIHdpdGggdGhlIGNvbm5lY3Rpb24gc3RyaW5ncyBcbiBBdGxhcyByZXR1cm5zOiBcbiDigKIgTU9OR09EIGZvciByZXBsaWNhIHNldHMsIG9yIFxuIOKAoiBNT05HT1MgZm9yIHNoYXJkZWQgY2x1c3RlcnMiLCJ0eXBlIjoic3RyaW5nIn19LCJ0eXBlIjoib2JqZWN0In0sInR5cGUiOiJhcnJheSJ9LCJwcml2YXRlU3J2Ijp7ImRlc2NyaXB0aW9uIjoiTmV0d29yay1wZWVyaW5nLWVuZHBvaW50LWF3YXJlIG1vbmdvZGIrc3J2Oi8vIGNvbm5lY3Rpb24gc3RyaW5ncyBmb3IgZWFjaCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50IHlvdSBjb25maWd1cmVkIHRvIGNvbm5lY3QgdG8gdGhpcyBjbHVzdGVyLiBBdGxhcyByZXR1cm5zIHRoaXMgcGFyYW1ldGVyIG9ubHkgaWYgeW91IGNyZWF0ZWQgYSBuZXR3b3JrIHBlZXJpbmcgY29ubmVjdGlvbiB0byB0aGlzIGNsdXN0ZXIuIFVzZSB0aGlzIFVSSSBmb3JtYXQgaWYgeW91ciBkcml2ZXIgc3VwcG9ydHMgaXQuIElmIGl0IGRvZXNuJ3QsIHVzZSBjb25uZWN0aW9uU3RyaW5ncy5wcml2YXRlLiIsInR5cGUiOiJzdHJpbmcifSwic3RhbmRhcmQiOnsiZGVzY3JpcHRpb24iOiJQdWJsaWMgbW9uZ29kYjovLyBjb25uZWN0aW9uIHN0cmluZyBmb3IgdGhpcyBjbHVzdGVyLiIsInR5cGUiOiJzdHJpbmcifSwic3RhbmRhcmRTcnYiOnsiZGVzY3JpcHRpb24iOiJQdWJsaWMgbW9uZ29kYitzcnY6Ly8gY29ubmVjdGlvbiBzdHJpbmcgZm9yIHRoaXMgY2x1c3Rlci4iLCJ0eXBlIjoic3RyaW5nIn19LCJ0eXBlIjoib2JqZWN0In0sIm1vbmdvREJWZXJzaW9uIjp7ImRlc2NyaXB0aW9uIjoiTW9uZ29EQlZlcnNpb24gaXMgdGhlIHZlcnNpb24gb2YgTW9uZ29EQiB0aGUgY2x1c3RlciBydW5zLCBpbiBcdTAwM2NtYWpvciB2ZXJzaW9uXHUwMDNlLlx1MDAzY21pbm9yIHZlcnNpb25cdTAwM2UgZm9ybWF0LiIsInR5cGUiOiJzdHJpbmcifSwibW9uZ29VUklVcGRhdGVkIjp7ImRlc2NyaXB0aW9uIjoiTW9uZ29VUklVcGRhdGVkIGlzIGEgdGltZXN0YW1wIGluIElTTyA4NjAxIGRhdGUgYW5kIHRpbWUgZm9ybWF0IGluIFVUQyB3aGVuIHRoZSBjb25uZWN0aW9uIHN0cmluZyB3YXMgbGFzdCB1cGRhdGVkLiBUaGUgY29ubmVjdGlvbiBzdHJpbmcgY2hhbmdlcyBpZiB5b3UgdXBkYXRlIGFueSBvZiB0aGUgb3RoZXIgdmFsdWVzLiIsInR5cGUiOiJzdHJpbmcifSwib2JzZXJ2ZWRHZW5lcmF0aW9uIjp7ImRlc2NyaXB0aW9uIjoiT2JzZXJ2ZWRHZW5lcmF0aW9uIGluZGljYXRlcyB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbiB0aGF0IHRoZSBBdGxhcyBPcGVyYXRvciBpcyBhd2FyZSBvZi4gVGhlIEF0bGFzIE9wZXJhdG9yIHVwZGF0ZXMgdGhpcyBmaWVsZCB0byB0aGUgJ21ldGFkYXRhLmdlbmVyYXRpb24nIGFzIHNvb24gYXMgaXQgc3RhcnRzIHJlY29uY2lsaWF0aW9uIG9mIHRoZSByZXNvdXJjZS4iLCJmb3JtYXQiOiJpbnQ2NCIsInR5cGUiOiJpbnRlZ2VyIn0sInN0YXRlTmFtZSI6eyJkZXNjcmlwdGlvbiI6IlN0YXRlTmFtZSBpcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgY2x1c3Rlci4gVGhlIHBvc3NpYmxlIHN0YXRlcyBhcmU6IElETEUsIENSRUFUSU5HLCBVUERBVElORywgREVMRVRJTkcsIERFTEVURUQsIFJFUEFJUklORyIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvbmRpdGlvbnMiXSwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlLCJzdWJyZXNvdXJjZXMiOnsic3RhdHVzIjp7fX19XX0sInN0YXR1cyI6eyJhY2NlcHRlZE5hbWVzIjp7ImtpbmQiOiIiLCJwbHVyYWwiOiIifSwiY29uZGl0aW9ucyI6W10sInN0b3JlZFZlcnNpb25zIjpbXX19 -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiY29udHJvbGxlci1nZW4ua3ViZWJ1aWxkZXIuaW8vdmVyc2lvbiI6InYwLjQuMSJ9LCJjcmVhdGlvblRpbWVzdGFtcCI6bnVsbCwibGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ImNvbnRyb2xsZXIiLCJhcHAua3ViZXJuZXRlcy5pby9pbnN0YW5jZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciIsImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiJtb25nb2RiLWF0bGFzLWt1YmVybmV0ZXMtb3BlcmF0b3IifSwibmFtZSI6ImF0bGFzZGF0YWJhc2V1c2Vycy5hdGxhcy5tb25nb2RiLmNvbSJ9LCJzcGVjIjp7Imdyb3VwIjoiYXRsYXMubW9uZ29kYi5jb20iLCJuYW1lcyI6eyJraW5kIjoiQXRsYXNEYXRhYmFzZVVzZXIiLCJsaXN0S2luZCI6IkF0bGFzRGF0YWJhc2VVc2VyTGlzdCIsInBsdXJhbCI6ImF0bGFzZGF0YWJhc2V1c2VycyIsInNpbmd1bGFyIjoiYXRsYXNkYXRhYmFzZXVzZXIifSwic2NvcGUiOiJOYW1lc3BhY2VkIiwidmVyc2lvbnMiOlt7ImFkZGl0aW9uYWxQcmludGVyQ29sdW1ucyI6W3sianNvblBhdGgiOiIuc3BlYy5uYW1lIiwibmFtZSI6Ik5hbWUiLCJ0eXBlIjoic3RyaW5nIn1dLCJuYW1lIjoidjEiLCJzY2hlbWEiOnsib3BlbkFQSVYzU2NoZW1hIjp7ImRlc2NyaXB0aW9uIjoiQXRsYXNEYXRhYmFzZVVzZXIgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIEF0bGFzIERhdGFiYXNlIFVzZXIgQVBJIiwicHJvcGVydGllcyI6eyJhcGlWZXJzaW9uIjp7ImRlc2NyaXB0aW9uIjoiQVBJVmVyc2lvbiBkZWZpbmVzIHRoZSB2ZXJzaW9uZWQgc2NoZW1hIG9mIHRoaXMgcmVwcmVzZW50YXRpb24gb2YgYW4gb2JqZWN0LiBTZXJ2ZXJzIHNob3VsZCBjb252ZXJ0IHJlY29nbml6ZWQgc2NoZW1hcyB0byB0aGUgbGF0ZXN0IGludGVybmFsIHZhbHVlLCBhbmQgbWF5IHJlamVjdCB1bnJlY29nbml6ZWQgdmFsdWVzLiBNb3JlIGluZm86IGh0dHBzOi8vZ2l0Lms4cy5pby9jb21tdW5pdHkvY29udHJpYnV0b3JzL2RldmVsL3NpZy1hcmNoaXRlY3R1cmUvYXBpLWNvbnZlbnRpb25zLm1kI3Jlc291cmNlcyIsInR5cGUiOiJzdHJpbmcifSwia2luZCI6eyJkZXNjcmlwdGlvbiI6IktpbmQgaXMgYSBzdHJpbmcgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBSRVNUIHJlc291cmNlIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMuIFNlcnZlcnMgbWF5IGluZmVyIHRoaXMgZnJvbSB0aGUgZW5kcG9pbnQgdGhlIGNsaWVudCBzdWJtaXRzIHJlcXVlc3RzIHRvLiBDYW5ub3QgYmUgdXBkYXRlZC4gSW4gQ2FtZWxDYXNlLiBNb3JlIGluZm86IGh0dHBzOi8vZ2l0Lms4cy5pby9jb21tdW5pdHkvY29udHJpYnV0b3JzL2RldmVsL3NpZy1hcmNoaXRlY3R1cmUvYXBpLWNvbnZlbnRpb25zLm1kI3R5cGVzLWtpbmRzIiwidHlwZSI6InN0cmluZyJ9LCJtZXRhZGF0YSI6eyJ0eXBlIjoib2JqZWN0In0sInNwZWMiOnsiZGVzY3JpcHRpb24iOiJBdGxhc0RhdGFiYXNlVXNlclNwZWMgZGVmaW5lcyB0aGUgZGVzaXJlZCBzdGF0ZSBvZiBEYXRhYmFzZSBVc2VyIGluIEF0bGFzIiwicHJvcGVydGllcyI6eyJkYXRhYmFzZU5hbWUiOnsiZGVmYXVsdCI6ImFkbWluIiwiZGVzY3JpcHRpb24iOiJEYXRhYmFzZU5hbWUgaXMgYSBEYXRhYmFzZSBhZ2FpbnN0IHdoaWNoIEF0bGFzIGF1dGhlbnRpY2F0ZXMgdGhlIHVzZXIuIERlZmF1bHQgdmFsdWUgaXMgJ2FkbWluJy4iLCJ0eXBlIjoic3RyaW5nIn0sImRlbGV0ZUFmdGVyRGF0ZSI6eyJkZXNjcmlwdGlvbiI6IkRlbGV0ZUFmdGVyRGF0ZSBpcyBhIHRpbWVzdGFtcCBpbiBJU08gODYwMSBkYXRlIGFuZCB0aW1lIGZvcm1hdCBpbiBVVEMgYWZ0ZXIgd2hpY2ggQXRsYXMgZGVsZXRlcyB0aGUgdXNlci4gVGhlIHNwZWNpZmllZCBkYXRlIG11c3QgYmUgaW4gdGhlIGZ1dHVyZSBhbmQgd2l0aGluIG9uZSB3ZWVrLiIsInR5cGUiOiJzdHJpbmcifSwibGFiZWxzIjp7ImRlc2NyaXB0aW9uIjoiTGFiZWxzIGlzIGFuIGFycmF5IGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXJzIHRoYXQgdGFnIGFuZCBjYXRlZ29yaXplIHRoZSBkYXRhYmFzZSB1c2VyLiBFYWNoIGtleSBhbmQgdmFsdWUgaGFzIGEgbWF4aW11bSBsZW5ndGggb2YgMjU1IGNoYXJhY3RlcnMuIiwiaXRlbXMiOnsiZGVzY3JpcHRpb24iOiJMYWJlbFNwZWMgY29udGFpbnMga2V5LXZhbHVlIHBhaXJzIHRoYXQgdGFnIGFuZCBjYXRlZ29yaXplIHRoZSBDbHVzdGVyL0RCVXNlciIsInByb3BlcnRpZXMiOnsia2V5Ijp7Im1heExlbmd0aCI6MjU1LCJ0eXBlIjoic3RyaW5nIn0sInZhbHVlIjp7InR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImtleSIsInZhbHVlIl0sInR5cGUiOiJvYmplY3QifSwidHlwZSI6ImFycmF5In0sInBhc3N3b3JkU2VjcmV0UmVmIjp7ImRlc2NyaXB0aW9uIjoiUGFzc3dvcmRTZWNyZXQgaXMgYSByZWZlcmVuY2UgdG8gdGhlIFNlY3JldCBrZWVwaW5nIHRoZSB1c2VyIHBhc3N3b3JkLiIsInByb3BlcnRpZXMiOnsibmFtZSI6eyJkZXNjcmlwdGlvbiI6Ik5hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIEt1YmVybmV0ZXMgUmVzb3VyY2UiLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInR5cGUiOiJvYmplY3QifSwicHJvamVjdFJlZiI6eyJkZXNjcmlwdGlvbiI6IlByb2plY3QgaXMgYSByZWZlcmVuY2UgdG8gQXRsYXNQcm9qZWN0IHJlc291cmNlIHRoZSB1c2VyIGJlbG9uZ3MgdG8iLCJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsiZGVzY3JpcHRpb24iOiJOYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBLdWJlcm5ldGVzIFJlc291cmNlIiwidHlwZSI6InN0cmluZyJ9LCJuYW1lc3BhY2UiOnsiZGVzY3JpcHRpb24iOiJOYW1lc3BhY2UgaXMgdGhlIG5hbWVzcGFjZSBvZiB0aGUgS3ViZXJuZXRlcyBSZXNvdXJjZSIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbIm5hbWUiXSwidHlwZSI6Im9iamVjdCJ9LCJyb2xlcyI6eyJkZXNjcmlwdGlvbiI6IlJvbGVzIGlzIGFuIGFycmF5IG9mIHRoaXMgdXNlcidzIHJvbGVzIGFuZCB0aGUgZGF0YWJhc2VzIC8gY29sbGVjdGlvbnMgb24gd2hpY2ggdGhlIHJvbGVzIGFwcGx5LiBBIHJvbGUgYWxsb3dzIHRoZSB1c2VyIHRvIHBlcmZvcm0gcGFydGljdWxhciBhY3Rpb25zIG9uIHRoZSBzcGVjaWZpZWQgZGF0YWJhc2UuIiwiaXRlbXMiOnsiZGVzY3JpcHRpb24iOiJSb2xlU3BlYyBhbGxvd3MgdGhlIHVzZXIgdG8gcGVyZm9ybSBwYXJ0aWN1bGFyIGFjdGlvbnMgb24gdGhlIHNwZWNpZmllZCBkYXRhYmFzZS4gQSByb2xlIG9uIHRoZSBhZG1pbiBkYXRhYmFzZSBjYW4gaW5jbHVkZSBwcml2aWxlZ2VzIHRoYXQgYXBwbHkgdG8gdGhlIG90aGVyIGRhdGFiYXNlcyBhcyB3ZWxsLiIsInByb3BlcnRpZXMiOnsiY29sbGVjdGlvbk5hbWUiOnsiZGVzY3JpcHRpb24iOiJDb2xsZWN0aW9uTmFtZSBpcyBhIGNvbGxlY3Rpb24gZm9yIHdoaWNoIHRoZSByb2xlIGFwcGxpZXMuIiwidHlwZSI6InN0cmluZyJ9LCJkYXRhYmFzZU5hbWUiOnsiZGVzY3JpcHRpb24iOiJEYXRhYmFzZU5hbWUgaXMgYSBkYXRhYmFzZSBvbiB3aGljaCB0aGUgdXNlciBoYXMgdGhlIHNwZWNpZmllZCByb2xlLiBBIHJvbGUgb24gdGhlIGFkbWluIGRhdGFiYXNlIGNhbiBpbmNsdWRlIHByaXZpbGVnZXMgdGhhdCBhcHBseSB0byB0aGUgb3RoZXIgZGF0YWJhc2VzLiIsInR5cGUiOiJzdHJpbmcifSwicm9sZU5hbWUiOnsiZGVzY3JpcHRpb24iOiJSb2xlTmFtZSBpcyBhIG5hbWUgb2YgdGhlIHJvbGUuIFRoaXMgdmFsdWUgY2FuIGVpdGhlciBiZSBhIGJ1aWx0LWluIHJvbGUgb3IgYSBjdXN0b20gcm9sZS4iLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJkYXRhYmFzZU5hbWUiLCJyb2xlTmFtZSJdLCJ0eXBlIjoib2JqZWN0In0sIm1pbkl0ZW1zIjoxLCJ0eXBlIjoiYXJyYXkifSwic2NvcGVzIjp7ImRlc2NyaXB0aW9uIjoiU2NvcGVzIGlzIGFuIGFycmF5IG9mIGNsdXN0ZXJzIGFuZCBBdGxhcyBEYXRhIExha2VzIHRoYXQgdGhpcyB1c2VyIGhhcyBhY2Nlc3MgdG8uIiwiaXRlbXMiOnsiZGVzY3JpcHRpb24iOiJTY29wZVNwZWMgaWYgcHJlc2VudCBhIGRhdGFiYXNlIHVzZXIgb25seSBoYXZlIGFjY2VzcyB0byB0aGUgaW5kaWNhdGVkIHJlc291cmNlIChDbHVzdGVyIG9yIEF0bGFzIERhdGEgTGFrZSkgaWYgbm9uZSBpcyBnaXZlbiB0aGVuIGl0IGhhcyBhY2Nlc3MgdG8gYWxsLiBJdCdzIGhpZ2hseSByZWNvbW1lbmRlZCB0byByZXN0cmljdCB0aGUgYWNjZXNzIG9mIHRoZSBkYXRhYmFzZSB1c2VycyBvbmx5IHRvIGEgbGltaXRlZCBzZXQgb2YgcmVzb3VyY2VzLiIsInByb3BlcnRpZXMiOnsibmFtZSI6eyJkZXNjcmlwdGlvbiI6Ik5hbWUgaXMgYSBuYW1lIG9mIHRoZSBjbHVzdGVyIG9yIEF0bGFzIERhdGEgTGFrZSB0aGF0IHRoZSB1c2VyIGhhcyBhY2Nlc3MgdG8uIiwidHlwZSI6InN0cmluZyJ9LCJ0eXBlIjp7ImRlc2NyaXB0aW9uIjoiVHlwZSBpcyBhIHR5cGUgb2YgcmVzb3VyY2UgdGhhdCB0aGUgdXNlciBoYXMgYWNjZXNzIHRvLiIsImVudW0iOlsiQ0xVU1RFUiIsIkRBVEFfTEFLRSJdLCJ0eXBlIjoic3RyaW5nIn19LCJyZXF1aXJlZCI6WyJuYW1lIiwidHlwZSJdLCJ0eXBlIjoib2JqZWN0In0sInR5cGUiOiJhcnJheSJ9LCJ1c2VybmFtZSI6eyJkZXNjcmlwdGlvbiI6IlVzZXJuYW1lIGlzIGEgdXNlcm5hbWUgZm9yIGF1dGhlbnRpY2F0aW5nIHRvIE1vbmdvREIuIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsicGFzc3dvcmRTZWNyZXRSZWYiLCJwcm9qZWN0UmVmIiwicm9sZXMiLCJ1c2VybmFtZSJdLCJ0eXBlIjoib2JqZWN0In0sInN0YXR1cyI6eyJkZXNjcmlwdGlvbiI6IkF0bGFzRGF0YWJhc2VVc2VyU3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIEF0bGFzUHJvamVjdCIsInByb3BlcnRpZXMiOnsiY29uZGl0aW9ucyI6eyJkZXNjcmlwdGlvbiI6IkNvbmRpdGlvbnMgaXMgdGhlIGxpc3Qgb2Ygc3RhdHVzZXMgc2hvd2luZyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgQXRsYXMgQ3VzdG9tIFJlc291cmNlIiwiaXRlbXMiOnsiZGVzY3JpcHRpb24iOiJDb25kaXRpb24gZGVzY3JpYmVzIHRoZSBzdGF0ZSBvZiBhbiBBdGxhcyBDdXN0b20gUmVzb3VyY2UgYXQgYSBjZXJ0YWluIHBvaW50LiIsInByb3BlcnRpZXMiOnsibGFzdFRyYW5zaXRpb25UaW1lIjp7ImRlc2NyaXB0aW9uIjoiTGFzdCB0aW1lIHRoZSBjb25kaXRpb24gdHJhbnNpdGlvbmVkIGZyb20gb25lIHN0YXR1cyB0byBhbm90aGVyLiIsImZvcm1hdCI6ImRhdGUtdGltZSIsInR5cGUiOiJzdHJpbmcifSwibWVzc2FnZSI6eyJkZXNjcmlwdGlvbiI6IkEgaHVtYW4gcmVhZGFibGUgbWVzc2FnZSBpbmRpY2F0aW5nIGRldGFpbHMgYWJvdXQgdGhlIHRyYW5zaXRpb24uIiwidHlwZSI6InN0cmluZyJ9LCJyZWFzb24iOnsiZGVzY3JpcHRpb24iOiJUaGUgcmVhc29uIGZvciB0aGUgY29uZGl0aW9uJ3MgbGFzdCB0cmFuc2l0aW9uLiIsInR5cGUiOiJzdHJpbmcifSwic3RhdHVzIjp7ImRlc2NyaXB0aW9uIjoiU3RhdHVzIG9mIHRoZSBjb25kaXRpb24sIG9uZSBvZiBUcnVlLCBGYWxzZSwgVW5rbm93bi4iLCJ0eXBlIjoic3RyaW5nIn0sInR5cGUiOnsiZGVzY3JpcHRpb24iOiJUeXBlIG9mIEF0bGFzIEN1c3RvbSBSZXNvdXJjZSBjb25kaXRpb24uIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsic3RhdHVzIiwidHlwZSJdLCJ0eXBlIjoib2JqZWN0In0sInR5cGUiOiJhcnJheSJ9LCJuYW1lIjp7ImRlc2NyaXB0aW9uIjoiVXNlck5hbWUgaXMgdGhlIGN1cnJlbnQgbmFtZSBvZiBkYXRhYmFzZSB1c2VyLiIsInR5cGUiOiJzdHJpbmcifSwib2JzZXJ2ZWRHZW5lcmF0aW9uIjp7ImRlc2NyaXB0aW9uIjoiT2JzZXJ2ZWRHZW5lcmF0aW9uIGluZGljYXRlcyB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbiB0aGF0IHRoZSBBdGxhcyBPcGVyYXRvciBpcyBhd2FyZSBvZi4gVGhlIEF0bGFzIE9wZXJhdG9yIHVwZGF0ZXMgdGhpcyBmaWVsZCB0byB0aGUgJ21ldGFkYXRhLmdlbmVyYXRpb24nIGFzIHNvb24gYXMgaXQgc3RhcnRzIHJlY29uY2lsaWF0aW9uIG9mIHRoZSByZXNvdXJjZS4iLCJmb3JtYXQiOiJpbnQ2NCIsInR5cGUiOiJpbnRlZ2VyIn0sInBhc3N3b3JkVmVyc2lvbiI6eyJkZXNjcmlwdGlvbiI6IlBhc3N3b3JkVmVyc2lvbiBpcyB0aGUgJ1Jlc291cmNlVmVyc2lvbicgb2YgdGhlIHBhc3N3b3JkIFNlY3JldCB0aGF0IHRoZSBBdGxhcyBPcGVyYXRvciBpcyBhd2FyZSBvZiIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbImNvbmRpdGlvbnMiXSwidHlwZSI6Im9iamVjdCJ9fSwidHlwZSI6Im9iamVjdCJ9fSwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlLCJzdWJyZXNvdXJjZXMiOnsic3RhdHVzIjp7fX19XX0sInN0YXR1cyI6eyJhY2NlcHRlZE5hbWVzIjp7ImtpbmQiOiIiLCJwbHVyYWwiOiIifSwiY29uZGl0aW9ucyI6W10sInN0b3JlZFZlcnNpb25zIjpbXX19 -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiY29udHJvbGxlci1nZW4ua3ViZWJ1aWxkZXIuaW8vdmVyc2lvbiI6InYwLjQuMSJ9LCJjcmVhdGlvblRpbWVzdGFtcCI6bnVsbCwibGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ImNvbnRyb2xsZXIiLCJhcHAua3ViZXJuZXRlcy5pby9pbnN0YW5jZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciIsImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiJtb25nb2RiLWF0bGFzLWt1YmVybmV0ZXMtb3BlcmF0b3IifSwibmFtZSI6ImF0bGFzcHJvamVjdHMuYXRsYXMubW9uZ29kYi5jb20ifSwic3BlYyI6eyJncm91cCI6ImF0bGFzLm1vbmdvZGIuY29tIiwibmFtZXMiOnsia2luZCI6IkF0bGFzUHJvamVjdCIsImxpc3RLaW5kIjoiQXRsYXNQcm9qZWN0TGlzdCIsInBsdXJhbCI6ImF0bGFzcHJvamVjdHMiLCJzaW5ndWxhciI6ImF0bGFzcHJvamVjdCJ9LCJzY29wZSI6Ik5hbWVzcGFjZWQiLCJ2ZXJzaW9ucyI6W3siYWRkaXRpb25hbFByaW50ZXJDb2x1bW5zIjpbeyJqc29uUGF0aCI6Ii5zcGVjLm5hbWUiLCJuYW1lIjoiTmFtZSIsInR5cGUiOiJzdHJpbmcifV0sIm5hbWUiOiJ2MSIsInNjaGVtYSI6eyJvcGVuQVBJVjNTY2hlbWEiOnsiZGVzY3JpcHRpb24iOiJBdGxhc1Byb2plY3QgaXMgdGhlIFNjaGVtYSBmb3IgdGhlIGF0bGFzcHJvamVjdHMgQVBJIiwicHJvcGVydGllcyI6eyJhcGlWZXJzaW9uIjp7ImRlc2NyaXB0aW9uIjoiQVBJVmVyc2lvbiBkZWZpbmVzIHRoZSB2ZXJzaW9uZWQgc2NoZW1hIG9mIHRoaXMgcmVwcmVzZW50YXRpb24gb2YgYW4gb2JqZWN0LiBTZXJ2ZXJzIHNob3VsZCBjb252ZXJ0IHJlY29nbml6ZWQgc2NoZW1hcyB0byB0aGUgbGF0ZXN0IGludGVybmFsIHZhbHVlLCBhbmQgbWF5IHJlamVjdCB1bnJlY29nbml6ZWQgdmFsdWVzLiBNb3JlIGluZm86IGh0dHBzOi8vZ2l0Lms4cy5pby9jb21tdW5pdHkvY29udHJpYnV0b3JzL2RldmVsL3NpZy1hcmNoaXRlY3R1cmUvYXBpLWNvbnZlbnRpb25zLm1kI3Jlc291cmNlcyIsInR5cGUiOiJzdHJpbmcifSwia2luZCI6eyJkZXNjcmlwdGlvbiI6IktpbmQgaXMgYSBzdHJpbmcgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBSRVNUIHJlc291cmNlIHRoaXMgb2JqZWN0IHJlcHJlc2VudHMuIFNlcnZlcnMgbWF5IGluZmVyIHRoaXMgZnJvbSB0aGUgZW5kcG9pbnQgdGhlIGNsaWVudCBzdWJtaXRzIHJlcXVlc3RzIHRvLiBDYW5ub3QgYmUgdXBkYXRlZC4gSW4gQ2FtZWxDYXNlLiBNb3JlIGluZm86IGh0dHBzOi8vZ2l0Lms4cy5pby9jb21tdW5pdHkvY29udHJpYnV0b3JzL2RldmVsL3NpZy1hcmNoaXRlY3R1cmUvYXBpLWNvbnZlbnRpb25zLm1kI3R5cGVzLWtpbmRzIiwidHlwZSI6InN0cmluZyJ9LCJtZXRhZGF0YSI6eyJ0eXBlIjoib2JqZWN0In0sInNwZWMiOnsiZGVzY3JpcHRpb24iOiJBdGxhc1Byb2plY3RTcGVjIGRlZmluZXMgdGhlIGRlc2lyZWQgc3RhdGUgb2YgUHJvamVjdCBpbiBBdGxhcyIsInByb3BlcnRpZXMiOnsiY29ubmVjdGlvblNlY3JldFJlZiI6eyJkZXNjcmlwdGlvbiI6IkNvbm5lY3Rpb25TZWNyZXQgaXMgdGhlIG5hbWUgb2YgdGhlIEt1YmVybmV0ZXMgU2VjcmV0IHdoaWNoIGNvbnRhaW5zIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgd2F5IHRvIGNvbm5lY3QgdG8gQXRsYXMgKG9yZ2FuaXphdGlvbiBJRCwgQVBJIGtleXMpLiBUaGUgZGVmYXVsdCBPcGVyYXRvciBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24gd2lsbCBiZSB1c2VkIGlmIG5vdCBwcm92aWRlZC4iLCJwcm9wZXJ0aWVzIjp7Im5hbWUiOnsiZGVzY3JpcHRpb24iOiJOYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBLdWJlcm5ldGVzIFJlc291cmNlIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsibmFtZSJdLCJ0eXBlIjoib2JqZWN0In0sIm5hbWUiOnsiZGVzY3JpcHRpb24iOiJOYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBQcm9qZWN0IHRoYXQgaXMgY3JlYXRlZCBpbiBBdGxhcyBieSB0aGUgT3BlcmF0b3IgaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQuIiwidHlwZSI6InN0cmluZyJ9LCJwcml2YXRlRW5kcG9pbnRzIjp7ImRlc2NyaXB0aW9uIjoiUHJpdmF0ZUVuZHBvaW50cyBpcyBhIGxpc3Qgb2YgUHJpdmF0ZSBFbmRwb2ludHMgY29uZmlndXJlZCBmb3IgdGhlIGN1cnJlbnQgUHJvamVjdC4iLCJpdGVtcyI6eyJwcm9wZXJ0aWVzIjp7ImlkIjp7ImRlc2NyaXB0aW9uIjoiVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHByaXZhdGUgZW5kcG9pbnQgeW91IGNyZWF0ZWQgaW4geW91ciBBV1MgVlBDIG9yIEF6dXJlIFZuZXQuIiwidHlwZSI6InN0cmluZyJ9LCJpcCI6eyJkZXNjcmlwdGlvbiI6IlByaXZhdGUgSVAgYWRkcmVzcyBvZiB0aGUgcHJpdmF0ZSBlbmRwb2ludCBuZXR3b3JrIGludGVyZmFjZSB5b3UgY3JlYXRlZCBpbiB5b3VyIEF6dXJlIFZOZXQuIiwidHlwZSI6InN0cmluZyJ9LCJwcm92aWRlciI6eyJkZXNjcmlwdGlvbiI6IkNsb3VkIHByb3ZpZGVyIGZvciB3aGljaCB5b3Ugd2FudCB0byByZXRyaWV2ZSBhIHByaXZhdGUgZW5kcG9pbnQgc2VydmljZS4gQXRsYXMgYWNjZXB0cyBBV1Mgb3IgQVpVUkUuIiwiZW51bSI6WyJBV1MiLCJHQ1AiLCJBWlVSRSIsIlRFTkFOVCJdLCJ0eXBlIjoic3RyaW5nIn0sInJlZ2lvbiI6eyJkZXNjcmlwdGlvbiI6IkNsb3VkIHByb3ZpZGVyIHJlZ2lvbiBmb3Igd2hpY2ggeW91IHdhbnQgdG8gY3JlYXRlIHRoZSBwcml2YXRlIGVuZHBvaW50IHNlcnZpY2UuIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsicHJvdmlkZXIiLCJyZWdpb24iXSwidHlwZSI6Im9iamVjdCJ9LCJ0eXBlIjoiYXJyYXkifSwicHJvamVjdElwQWNjZXNzTGlzdCI6eyJkZXNjcmlwdGlvbiI6IlByb2plY3RJUEFjY2Vzc0xpc3QgYWxsb3dzIHRvIGVuYWJsZSB0aGUgSVAgQWNjZXNzIExpc3QgZm9yIHRoZSBQcm9qZWN0LiBTZWUgbW9yZSBpbmZvcm1hdGlvbiBhdCBodHRwczovL2RvY3MuYXRsYXMubW9uZ29kYi5jb20vcmVmZXJlbmNlL2FwaS9pcC1hY2Nlc3MtbGlzdC9hZGQtZW50cmllcy10by1hY2Nlc3MtbGlzdC8iLCJpdGVtcyI6eyJwcm9wZXJ0aWVzIjp7ImF3c1NlY3VyaXR5R3JvdXAiOnsiZGVzY3JpcHRpb24iOiJVbmlxdWUgaWRlbnRpZmllciBvZiBBV1Mgc2VjdXJpdHkgZ3JvdXAgaW4gdGhpcyBhY2Nlc3MgbGlzdCBlbnRyeS4iLCJ0eXBlIjoic3RyaW5nIn0sImNpZHJCbG9jayI6eyJkZXNjcmlwdGlvbiI6IlJhbmdlIG9mIElQIGFkZHJlc3NlcyBpbiBDSURSIG5vdGF0aW9uIGluIHRoaXMgYWNjZXNzIGxpc3QgZW50cnkuIiwidHlwZSI6InN0cmluZyJ9LCJjb21tZW50Ijp7ImRlc2NyaXB0aW9uIjoiQ29tbWVudCBhc3NvY2lhdGVkIHdpdGggdGhpcyBhY2Nlc3MgbGlzdCBlbnRyeS4iLCJ0eXBlIjoic3RyaW5nIn0sImRlbGV0ZUFmdGVyRGF0ZSI6eyJkZXNjcmlwdGlvbiI6IlRpbWVzdGFtcCBpbiBJU08gODYwMSBkYXRlIGFuZCB0aW1lIGZvcm1hdCBpbiBVVEMgYWZ0ZXIgd2hpY2ggQXRsYXMgZGVsZXRlcyB0aGUgdGVtcG9yYXJ5IGFjY2VzcyBsaXN0IGVudHJ5LiIsInR5cGUiOiJzdHJpbmcifSwiaXBBZGRyZXNzIjp7ImRlc2NyaXB0aW9uIjoiRW50cnkgdXNpbmcgYW4gSVAgYWRkcmVzcyBpbiB0aGlzIGFjY2VzcyBsaXN0IGVudHJ5LiIsInR5cGUiOiJzdHJpbmcifX0sInR5cGUiOiJvYmplY3QifSwidHlwZSI6ImFycmF5In19LCJyZXF1aXJlZCI6WyJuYW1lIl0sInR5cGUiOiJvYmplY3QifSwic3RhdHVzIjp7ImRlc2NyaXB0aW9uIjoiQXRsYXNQcm9qZWN0U3RhdHVzIGRlZmluZXMgdGhlIG9ic2VydmVkIHN0YXRlIG9mIEF0bGFzUHJvamVjdCIsInByb3BlcnRpZXMiOnsiY29uZGl0aW9ucyI6eyJkZXNjcmlwdGlvbiI6IkNvbmRpdGlvbnMgaXMgdGhlIGxpc3Qgb2Ygc3RhdHVzZXMgc2hvd2luZyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgQXRsYXMgQ3VzdG9tIFJlc291cmNlIiwiaXRlbXMiOnsiZGVzY3JpcHRpb24iOiJDb25kaXRpb24gZGVzY3JpYmVzIHRoZSBzdGF0ZSBvZiBhbiBBdGxhcyBDdXN0b20gUmVzb3VyY2UgYXQgYSBjZXJ0YWluIHBvaW50LiIsInByb3BlcnRpZXMiOnsibGFzdFRyYW5zaXRpb25UaW1lIjp7ImRlc2NyaXB0aW9uIjoiTGFzdCB0aW1lIHRoZSBjb25kaXRpb24gdHJhbnNpdGlvbmVkIGZyb20gb25lIHN0YXR1cyB0byBhbm90aGVyLiIsImZvcm1hdCI6ImRhdGUtdGltZSIsInR5cGUiOiJzdHJpbmcifSwibWVzc2FnZSI6eyJkZXNjcmlwdGlvbiI6IkEgaHVtYW4gcmVhZGFibGUgbWVzc2FnZSBpbmRpY2F0aW5nIGRldGFpbHMgYWJvdXQgdGhlIHRyYW5zaXRpb24uIiwidHlwZSI6InN0cmluZyJ9LCJyZWFzb24iOnsiZGVzY3JpcHRpb24iOiJUaGUgcmVhc29uIGZvciB0aGUgY29uZGl0aW9uJ3MgbGFzdCB0cmFuc2l0aW9uLiIsInR5cGUiOiJzdHJpbmcifSwic3RhdHVzIjp7ImRlc2NyaXB0aW9uIjoiU3RhdHVzIG9mIHRoZSBjb25kaXRpb24sIG9uZSBvZiBUcnVlLCBGYWxzZSwgVW5rbm93bi4iLCJ0eXBlIjoic3RyaW5nIn0sInR5cGUiOnsiZGVzY3JpcHRpb24iOiJUeXBlIG9mIEF0bGFzIEN1c3RvbSBSZXNvdXJjZSBjb25kaXRpb24uIiwidHlwZSI6InN0cmluZyJ9fSwicmVxdWlyZWQiOlsic3RhdHVzIiwidHlwZSJdLCJ0eXBlIjoib2JqZWN0In0sInR5cGUiOiJhcnJheSJ9LCJleHBpcmVkSXBBY2Nlc3NMaXN0Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGxpc3Qgb2YgSVAgQWNjZXNzIExpc3QgZW50cmllcyB0aGF0IGFyZSBleHBpcmVkIGR1ZSB0byAnZGVsZXRlQWZ0ZXJEYXRlJyBiZWluZyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgZGF0ZS4gTm90ZSwgdGhhdCB0aGlzIGZpZWxkIGlzIHVwZGF0ZWQgYnkgdGhlIEF0bGFzIE9wZXJhdG9yIG9ubHkgYWZ0ZXIgc3BlY2lmaWNhdGlvbiBjaGFuZ2VzIiwiaXRlbXMiOnsicHJvcGVydGllcyI6eyJhd3NTZWN1cml0eUdyb3VwIjp7ImRlc2NyaXB0aW9uIjoiVW5pcXVlIGlkZW50aWZpZXIgb2YgQVdTIHNlY3VyaXR5IGdyb3VwIGluIHRoaXMgYWNjZXNzIGxpc3QgZW50cnkuIiwidHlwZSI6InN0cmluZyJ9LCJjaWRyQmxvY2siOnsiZGVzY3JpcHRpb24iOiJSYW5nZSBvZiBJUCBhZGRyZXNzZXMgaW4gQ0lEUiBub3RhdGlvbiBpbiB0aGlzIGFjY2VzcyBsaXN0IGVudHJ5LiIsInR5cGUiOiJzdHJpbmcifSwiY29tbWVudCI6eyJkZXNjcmlwdGlvbiI6IkNvbW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYWNjZXNzIGxpc3QgZW50cnkuIiwidHlwZSI6InN0cmluZyJ9LCJkZWxldGVBZnRlckRhdGUiOnsiZGVzY3JpcHRpb24iOiJUaW1lc3RhbXAgaW4gSVNPIDg2MDEgZGF0ZSBhbmQgdGltZSBmb3JtYXQgaW4gVVRDIGFmdGVyIHdoaWNoIEF0bGFzIGRlbGV0ZXMgdGhlIHRlbXBvcmFyeSBhY2Nlc3MgbGlzdCBlbnRyeS4iLCJ0eXBlIjoic3RyaW5nIn0sImlwQWRkcmVzcyI6eyJkZXNjcmlwdGlvbiI6IkVudHJ5IHVzaW5nIGFuIElQIGFkZHJlc3MgaW4gdGhpcyBhY2Nlc3MgbGlzdCBlbnRyeS4iLCJ0eXBlIjoic3RyaW5nIn19LCJ0eXBlIjoib2JqZWN0In0sInR5cGUiOiJhcnJheSJ9LCJpZCI6eyJkZXNjcmlwdGlvbiI6IlRoZSBJRCBvZiB0aGUgQXRsYXMgUHJvamVjdCIsInR5cGUiOiJzdHJpbmcifSwib2JzZXJ2ZWRHZW5lcmF0aW9uIjp7ImRlc2NyaXB0aW9uIjoiT2JzZXJ2ZWRHZW5lcmF0aW9uIGluZGljYXRlcyB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbiB0aGF0IHRoZSBBdGxhcyBPcGVyYXRvciBpcyBhd2FyZSBvZi4gVGhlIEF0bGFzIE9wZXJhdG9yIHVwZGF0ZXMgdGhpcyBmaWVsZCB0byB0aGUgJ21ldGFkYXRhLmdlbmVyYXRpb24nIGFzIHNvb24gYXMgaXQgc3RhcnRzIHJlY29uY2lsaWF0aW9uIG9mIHRoZSByZXNvdXJjZS4iLCJmb3JtYXQiOiJpbnQ2NCIsInR5cGUiOiJpbnRlZ2VyIn0sInByaXZhdGVFbmRwb2ludHMiOnsiZGVzY3JpcHRpb24iOiJUaGUgbGlzdCBvZiBwcml2YXRlIGVuZHBvaW50cyBjb25maWd1cmVkIGZvciBjdXJyZW50IHByb2plY3QiLCJpdGVtcyI6eyJwcm9wZXJ0aWVzIjp7ImlkIjp7ImRlc2NyaXB0aW9uIjoiVW5pcXVlIGlkZW50aWZpZXIgZm9yIEFXUyBvciBBWlVSRSBQcml2YXRlIExpbmsgQ29ubmVjdGlvbi4iLCJ0eXBlIjoic3RyaW5nIn0sImludGVyZmFjZUVuZHBvaW50SWQiOnsiZGVzY3JpcHRpb24iOiJVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgQVdTIG9yIEF6dXJlIFByaXZhdGUgTGluayBJbnRlcmZhY2UgRW5kcG9pbnQuIiwidHlwZSI6InN0cmluZyJ9LCJwcm92aWRlciI6eyJkZXNjcmlwdGlvbiI6IkNsb3VkIHByb3ZpZGVyIGZvciB3aGljaCB5b3Ugd2FudCB0byByZXRyaWV2ZSBhIHByaXZhdGUgZW5kcG9pbnQgc2VydmljZS4gQXRsYXMgYWNjZXB0cyBBV1Mgb3IgQVpVUkUuIiwidHlwZSI6InN0cmluZyJ9LCJyZWdpb24iOnsiZGVzY3JpcHRpb24iOiJDbG91ZCBwcm92aWRlciByZWdpb24gZm9yIHdoaWNoIHlvdSB3YW50IHRvIGNyZWF0ZSB0aGUgcHJpdmF0ZSBlbmRwb2ludCBzZXJ2aWNlLiIsInR5cGUiOiJzdHJpbmcifSwic2VydmljZU5hbWUiOnsiZGVzY3JpcHRpb24iOiJOYW1lIG9mIHRoZSBBV1Mgb3IgQXp1cmUgUHJpdmF0ZSBMaW5rIFNlcnZpY2UgdGhhdCBBdGxhcyBtYW5hZ2VzLiIsInR5cGUiOiJzdHJpbmcifSwic2VydmljZVJlc291cmNlSWQiOnsiZGVzY3JpcHRpb24iOiJVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgQXp1cmUgUHJpdmF0ZSBMaW5rIFNlcnZpY2UgKGZvciBBV1MgdGhlIHNhbWUgYXMgSUQpLiIsInR5cGUiOiJzdHJpbmcifX0sInJlcXVpcmVkIjpbInByb3ZpZGVyIiwicmVnaW9uIl0sInR5cGUiOiJvYmplY3QifSwidHlwZSI6ImFycmF5In19LCJyZXF1aXJlZCI6WyJjb25kaXRpb25zIl0sInR5cGUiOiJvYmplY3QifX0sInR5cGUiOiJvYmplY3QifX0sInNlcnZlZCI6dHJ1ZSwic3RvcmFnZSI6dHJ1ZSwic3VicmVzb3VyY2VzIjp7InN0YXR1cyI6e319fV19LCJzdGF0dXMiOnsiYWNjZXB0ZWROYW1lcyI6eyJraW5kIjoiIiwicGx1cmFsIjoiIn0sImNvbmRpdGlvbnMiOltdLCJzdG9yZWRWZXJzaW9ucyI6W119fQ== -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoidjEiLCJraW5kIjoiU2VydmljZSIsIm1ldGFkYXRhIjp7ImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJsYWJlbHMiOnsiYXBwLmt1YmVybmV0ZXMuaW8vY29tcG9uZW50IjoiY29udHJvbGxlciIsImFwcC5rdWJlcm5ldGVzLmlvL2luc3RhbmNlIjoibW9uZ29kYi1hdGxhcy1rdWJlcm5ldGVzLW9wZXJhdG9yIiwiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciJ9LCJuYW1lIjoibW9uZ29kYi1hdGxhcy1jb250cm9sbGVyLW1hbmFnZXItbWV0cmljcy1zZXJ2aWNlIn0sInNwZWMiOnsicG9ydHMiOlt7Im5hbWUiOiJodHRwcyIsInBvcnQiOjg0NDMsInRhcmdldFBvcnQiOiJodHRwcyJ9XSwic2VsZWN0b3IiOnsiYXBwLmt1YmVybmV0ZXMuaW8vY29tcG9uZW50IjoiY29udHJvbGxlciIsImFwcC5rdWJlcm5ldGVzLmlvL2luc3RhbmNlIjoibW9uZ29kYi1hdGxhcy1rdWJlcm5ldGVzLW9wZXJhdG9yIiwiYXBwLmt1YmVybmV0ZXMuaW8vbmFtZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciJ9fSwic3RhdHVzIjp7ImxvYWRCYWxhbmNlciI6e319fQ== -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW1xuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwiYXRsYXMubW9uZ29kYi5jb20vdjFcIixcbiAgICBcImtpbmRcIjogXCJBdGxhc0NsdXN0ZXJcIixcbiAgICBcIm1ldGFkYXRhXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcIm15LWF0bGFzLWNsdXN0ZXJcIlxuICAgIH0sXG4gICAgXCJzcGVjXCI6IHtcbiAgICAgIFwibmFtZVwiOiBcInRlc3QtY2x1c3RlclwiLFxuICAgICAgXCJwcm9qZWN0UmVmXCI6IHtcbiAgICAgICAgXCJuYW1lXCI6IFwibXktcHJvamVjdFwiXG4gICAgICB9LFxuICAgICAgXCJwcm92aWRlclNldHRpbmdzXCI6IHtcbiAgICAgICAgXCJpbnN0YW5jZVNpemVOYW1lXCI6IFwiTTEwXCIsXG4gICAgICAgIFwicHJvdmlkZXJOYW1lXCI6IFwiQVdTXCIsXG4gICAgICAgIFwicmVnaW9uTmFtZVwiOiBcIlVTX0VBU1RfMVwiXG4gICAgICB9XG4gICAgfVxuICB9LFxuICB7XG4gICAgXCJhcGlWZXJzaW9uXCI6IFwiYXRsYXMubW9uZ29kYi5jb20vdjFcIixcbiAgICBcImtpbmRcIjogXCJBdGxhc0RhdGFiYXNlVXNlclwiLFxuICAgIFwibWV0YWRhdGFcIjoge1xuICAgICAgXCJuYW1lXCI6IFwibXktZGF0YWJhc2UtdXNlclwiXG4gICAgfSxcbiAgICBcInNwZWNcIjoge1xuICAgICAgXCJkYXRhYmFzZU5hbWVcIjogXCJhZG1pblwiLFxuICAgICAgXCJwYXNzd29yZFNlY3JldFJlZlwiOiB7XG4gICAgICAgIFwibmFtZVwiOiBcIm15LWRhdGFiYXNlLXVzZXItcGFzc3dvcmRcIlxuICAgICAgfSxcbiAgICAgIFwicHJvamVjdFJlZlwiOiB7XG4gICAgICAgIFwibmFtZVwiOiBcIm15LXByb2plY3RcIlxuICAgICAgfSxcbiAgICAgIFwicm9sZXNcIjogW1xuICAgICAgICB7XG4gICAgICAgICAgXCJkYXRhYmFzZU5hbWVcIjogXCJhZG1pblwiLFxuICAgICAgICAgIFwicm9sZU5hbWVcIjogXCJyZWFkV3JpdGVBbnlEYXRhYmFzZVwiXG4gICAgICAgIH1cbiAgICAgIF0sXG4gICAgICBcInVzZXJuYW1lXCI6IFwiZGF2aWRcIlxuICAgIH1cbiAgfSxcbiAge1xuICAgIFwiYXBpVmVyc2lvblwiOiBcImF0bGFzLm1vbmdvZGIuY29tL3YxXCIsXG4gICAgXCJraW5kXCI6IFwiQXRsYXNQcm9qZWN0XCIsXG4gICAgXCJtZXRhZGF0YVwiOiB7XG4gICAgICBcIm5hbWVcIjogXCJteS1wcm9qZWN0XCJcbiAgICB9LFxuICAgIFwic3BlY1wiOiB7XG4gICAgICBcIm5hbWVcIjogXCJUZXN0IEF0bGFzIE9wZXJhdG9yIFByb2plY3RcIixcbiAgICAgIFwicHJvamVjdElwQWNjZXNzTGlzdFwiOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBcImNvbW1lbnRcIjogXCJJUCBhZGRyZXNzIGZvciBBcHBsaWNhdGlvbiBTZXJ2ZXIgQVwiLFxuICAgICAgICAgIFwiaXBBZGRyZXNzXCI6IFwiMTkyLjAuMi4xNVwiXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9XG4gIH1cbl0iLCJjYXBhYmlsaXRpZXMiOiJCYXNpYyBJbnN0YWxsIiwiY2F0ZWdvcmllcyI6IkRhdGFiYXNlIiwiZGVzY3JpcHRpb24iOiJUaGUgTW9uZ29EQiBBdGxhcyBLdWJlcm5ldGVzIE9wZXJhdG9yIGVuYWJsZXMgZWFzeSBtYW5hZ2VtZW50IG9mIENsdXN0ZXJzIGluIE1vbmdvREIgQXRsYXMiLCJvcGVyYXRvcnMub3BlcmF0b3JmcmFtZXdvcmsuaW8vYnVpbGRlciI6Im9wZXJhdG9yLXNkay12MS4xNi4wIiwib3BlcmF0b3JzLm9wZXJhdG9yZnJhbWV3b3JrLmlvL3Byb2plY3RfbGF5b3V0IjoiZ28ua3ViZWJ1aWxkZXIuaW8vdjIifSwibmFtZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy52MC41LjAiLCJuYW1lc3BhY2UiOiJwbGFjZWhvbGRlciJ9LCJzcGVjIjp7ImFwaXNlcnZpY2VkZWZpbml0aW9ucyI6e30sImN1c3RvbXJlc291cmNlZGVmaW5pdGlvbnMiOnsib3duZWQiOlt7ImRlc2NyaXB0aW9uIjoiQXRsYXNDbHVzdGVyIGlzIHRoZSBTY2hlbWEgZm9yIHRoZSBhdGxhc2NsdXN0ZXJzIEFQSSIsImRpc3BsYXlOYW1lIjoiQXRsYXMgQ2x1c3RlciIsImtpbmQiOiJBdGxhc0NsdXN0ZXIiLCJuYW1lIjoiYXRsYXNjbHVzdGVycy5hdGxhcy5tb25nb2RiLmNvbSIsInZlcnNpb24iOiJ2MSJ9LHsiZGVzY3JpcHRpb24iOiJBdGxhc0RhdGFiYXNlVXNlciBpcyB0aGUgU2NoZW1hIGZvciB0aGUgQXRsYXMgRGF0YWJhc2UgVXNlciBBUEkiLCJkaXNwbGF5TmFtZSI6IkF0bGFzIERhdGFiYXNlIFVzZXIiLCJraW5kIjoiQXRsYXNEYXRhYmFzZVVzZXIiLCJuYW1lIjoiYXRsYXNkYXRhYmFzZXVzZXJzLmF0bGFzLm1vbmdvZGIuY29tIiwidmVyc2lvbiI6InYxIn0seyJkZXNjcmlwdGlvbiI6IkF0bGFzUHJvamVjdCBpcyB0aGUgU2NoZW1hIGZvciB0aGUgYXRsYXNwcm9qZWN0cyBBUEkiLCJkaXNwbGF5TmFtZSI6IkF0bGFzIFByb2plY3QiLCJraW5kIjoiQXRsYXNQcm9qZWN0IiwibmFtZSI6ImF0bGFzcHJvamVjdHMuYXRsYXMubW9uZ29kYi5jb20iLCJ2ZXJzaW9uIjoidjEifV19LCJkZXNjcmlwdGlvbiI6IlRoZSBNb25nb0RCIEF0bGFzIE9wZXJhdG9yIHByb3ZpZGVzIGEgbmF0aXZlIGludGVncmF0aW9uIGJldHdlZW4gdGhlIEt1YmVybmV0ZXMgb3JjaGVzdHJhdGlvbiBwbGF0Zm9ybSBhbmQgTW9uZ29EQiBBdGxhcyDigJRcbnRoZSBvbmx5IG11bHRpLWNsb3VkIGRvY3VtZW50IGRhdGFiYXNlIHNlcnZpY2UgdGhhdCBnaXZlcyB5b3UgdGhlIHZlcnNhdGlsaXR5IHlvdSBuZWVkIHRvIGJ1aWxkIHNvcGhpc3RpY2F0ZWQgYW5kIHJlc2lsaWVudCBhcHBsaWNhdGlvbnMgdGhhdCBjYW4gYWRhcHQgdG8gY2hhbmdpbmcgY3VzdG9tZXIgZGVtYW5kcyBhbmQgbWFya2V0IHRyZW5kcy5cblxuXHUwMDNlIEN1cnJlbnQgU3RhdHVzOiAqdHJpYWwgdmVyc2lvbiouIFRoZSBPcGVyYXRvciBnaXZlcyB1c2VycyB0aGUgYWJpbGl0eSB0byBwcm92aXNpb25cblx1MDAzZSBBdGxhcyBwcm9qZWN0cywgY2x1c3RlcnMgYW5kIGRhdGFiYXNlIHVzZXJzIHVzaW5nIEt1YmVybmV0ZXMgU3BlY2lmaWNhdGlvbnMgYW5kIGJpbmQgY29ubmVjdGlvbiBpbmZvcm1hdGlvblxuXHUwMDNlIGludG8gYXBwbGljYXRpb25zIGRlcGxveWVkIHRvIEt1YmVybmV0ZXMuIE1vcmUgZmVhdHVyZXMgbGlrZSBwcml2YXRlIGVuZHBvaW50cywgYmFja3VwIG1hbmFnZW1lbnQsIExEQVAvWC41MDkgYXV0aGVudGljYXRpb24sIGV0Yy5cblx1MDAzZSBhcmUgeWV0IHRvIGNvbWUuXG5cblxuIyMgUXVpY2sgU3RhcnQgZ3VpZGVcbiMjIyBTdGVwIDEuIERlcGxveSBLdWJlcm5ldGVzIG9wZXJhdG9yIGJ5IGNsaWNraW5nIEluc3RhbGwgYnV0dG9uLlxuXG4jIyMgU3RlcCAyLiBDcmVhdGUgQXRsYXMgQ2x1c3RlclxuXG4qKjEuKiogQ3JlYXRlIGFuIEF0bGFzIEFQSSBLZXkgU2VjcmV0XG5JbiBvcmRlciB0byB3b3JrIHdpdGggdGhlIEF0bGFzIE9wZXJhdG9yIHlvdSBuZWVkIHRvIHByb3ZpZGUgW2F1dGhlbnRpY2F0aW9uIGluZm9ybWF0aW9uXShodHRwczovL2RvY3MuYXRsYXMubW9uZ29kYi5jb20vY29uZmlndXJlLWFwaS1hY2Nlc3MpXG4gdG8gYWxsb3cgdGhlIEF0bGFzIE9wZXJhdG9yIHRvIGNvbW11bmljYXRlIHdpdGggQXRsYXMgQVBJLiBPbmNlIHlvdSBoYXZlIGdlbmVyYXRlZCBhIFB1YmxpYyBhbmQgUHJpdmF0ZSBrZXkgaW4gQXRsYXMsIHlvdSBjYW4gY3JlYXRlIGEgS3ViZXJlbnRlcyBTZWNyZXQgd2l0aDpcbmBgYFxua3ViZWN0bCBjcmVhdGUgc2VjcmV0IGdlbmVyaWMgbW9uZ29kYi1hdGxhcy1vcGVyYXRvci1hcGkta2V5IFxcXG4gICAgICAgICAtLWZyb20tbGl0ZXJhbD1cIm9yZ0lkPVx1MDAzY3RoZV9hdGxhc19vcmdhbml6YXRpb25faWRcdTAwM2VcIiBcXFxuICAgICAgICAgLS1mcm9tLWxpdGVyYWw9XCJwdWJsaWNBcGlLZXk9XHUwMDNjdGhlX2F0bGFzX2FwaV9wdWJsaWNfa2V5XHUwMDNlXCIgXFxcbiAgICAgICAgIC0tZnJvbS1saXRlcmFsPVwicHJpdmF0ZUFwaUtleT1cdTAwM2N0aGVfYXRsYXNfYXBpX3ByaXZhdGVfa2V5XHUwMDNlXCIgXFxcbiAgICAgICAgIC1uIG9wZW5zaGlmdC1vcGVyYXRvcnNcbmBgYFxuKE5vdGUsIHRoYXQgeW91IHNob3VsZCB1c2UgdGhlIG5hbWVzcGFjZSB3aGVyZSB0aGUgT3BlcmF0b3Igd2FzIGluc3RhbGxlZCAtIGl0J3MgYG9wZW5zaGlmdC1vcGVyYXRvcnNgIGJ5IGRlZmF1bHQpXG5cbioqMi4qKiBDcmVhdGUgYW4gYEF0bGFzUHJvamVjdGAgQ3VzdG9tIFJlc291cmNlXG5cblRoZSBgQXRsYXNQcm9qZWN0YCBDdXN0b21SZXNvdXJjZSByZXByZXNlbnRzIEF0bGFzIFByb2plY3RzIGluIG91ciBLdWJlcm5ldGVzIGNsdXN0ZXIuIFlvdSBuZWVkIHRvIHNwZWNpZnlcbmBwcm9qZWN0SXBBY2Nlc3NMaXN0YCB3aXRoIHRoZSBJUCBhZGRyZXNzZXMgb3IgQ0lEUiBibG9ja3Mgb2YgYW55IGhvc3RzIHRoYXQgd2lsbCBjb25uZWN0IHRvIHRoZSBBdGxhcyBDbHVzdGVyLlxuYGBgXG5hcGlWZXJzaW9uOiBhdGxhcy5tb25nb2RiLmNvbS92MVxua2luZDogQXRsYXNQcm9qZWN0XG5tZXRhZGF0YTpcbiAgbmFtZTogbXktcHJvamVjdFxuc3BlYzpcbiAgbmFtZTogVGVzdCBBdGxhcyBPcGVyYXRvciBQcm9qZWN0XG4gIHByb2plY3RJcEFjY2Vzc0xpc3Q6XG4gICAgLSBpcEFkZHJlc3M6IFwiMTkyLjAuMi4xNVwiXG4gICAgICBjb21tZW50OiBcIklQIGFkZHJlc3MgZm9yIEFwcGxpY2F0aW9uIFNlcnZlciBBXCJcbiAgICAtIGlwQWRkcmVzczogXCIyMDMuMC4xMTMuMC8yNFwiXG4gICAgICBjb21tZW50OiBcIkNJRFIgYmxvY2sgZm9yIEFwcGxpY2F0aW9uIFNlcnZlciBCIC0gRFwiXG5gYGBcbioqMy4qKiBDcmVhdGUgYW4gYEF0bGFzQ2x1c3RlcmAgQ3VzdG9tIFJlc291cmNlLlxuVGhlIGV4YW1wbGUgYmVsb3cgaXMgYSBtaW5pbWFsIGNvbmZpZ3VyYXRpb24gdG8gY3JlYXRlIGFuIE0xMCBBdGxhcyBjbHVzdGVyIGluIHRoZSBBV1MgVVMgRWFzdCByZWdpb24uIEZvciBhIGZ1bGwgbGlzdCBvZiBwcm9wZXJ0aWVzLCBjaGVja1xuYGF0bGFzY2x1c3RlcnMuYXRsYXMubW9uZ29kYi5jb21gIFtDUkQgc3BlY2lmaWNhdGlvbl0oY29uZmlnL2NyZC9iYXNlcy9hdGxhcy5tb25nb2RiLmNvbV9hdGxhc2NsdXN0ZXJzLnlhbWwpKTpcbmBgYFxuYXBpVmVyc2lvbjogYXRsYXMubW9uZ29kYi5jb20vdjFcbmtpbmQ6IEF0bGFzQ2x1c3RlclxubWV0YWRhdGE6XG4gIG5hbWU6IG15LWF0bGFzLWNsdXN0ZXJcbnNwZWM6XG4gIG5hbWU6IFwiVGVzdC1jbHVzdGVyXCJcbiAgcHJvamVjdFJlZjpcbiAgICBuYW1lOiBteS1wcm9qZWN0XG4gIHByb3ZpZGVyU2V0dGluZ3M6XG4gICAgaW5zdGFuY2VTaXplTmFtZTogTTEwXG4gICAgcHJvdmlkZXJOYW1lOiBBV1NcbiAgICByZWdpb25OYW1lOiBVU19FQVNUXzFcbmBgYFxuXG4qKjQuKiogQ3JlYXRlIGEgZGF0YWJhc2UgdXNlciBwYXNzd29yZCBLdWJlcm5ldGVzIFNlY3JldFxuVGhlIFNlY3JldCBtdXN0IGJlIGNyZWF0ZWQgaW4gdGhlIHNhbWUgbmFtZXNwYWNlIGFzIHRoZSBgQXRsYXNDbHVzdGVyYCBhbmQgYEF0bGFzUHJvamVjdGAgd2VyZSBjcmVhdGVkLlxuYGBgXG5rdWJlY3RsIGNyZWF0ZSBzZWNyZXQgZ2VuZXJpYyB0aGUtdXNlci1wYXNzd29yZCAtLWZyb20tbGl0ZXJhbD1cInBhc3N3b3JkPVBAQHN3b3JkJVwiXG5gYGBcblxuKio1LioqIENyZWF0ZSBhbiBgQXRsYXNEYXRhYmFzZVVzZXJgIEN1c3RvbSBSZXNvdXJjZVxuXG5JbiBvcmRlciB0byBjb25uZWN0IHRvIGFuIEF0bGFzIENsdXN0ZXIgdGhlIGRhdGFiYXNlIHVzZXIgbmVlZHMgdG8gYmUgY3JlYXRlZC4gYEF0bGFzRGF0YWJhc2VVc2VyYCByZXNvdXJjZSBzaG91bGQgcmVmZXJlbmNlXG50aGUgcGFzc3dvcmQgS3ViZXJuZXRlcyBTZWNyZXQgY3JlYXRlZCBpbiB0aGUgcHJldmlvdXMgc3RlcC5cbmBgYFxuYXBpVmVyc2lvbjogYXRsYXMubW9uZ29kYi5jb20vdjFcbmtpbmQ6IEF0bGFzRGF0YWJhc2VVc2VyXG5tZXRhZGF0YTpcbiAgbmFtZTogbXktZGF0YWJhc2UtdXNlclxuc3BlYzpcbiAgcm9sZXM6XG4gICAgLSByb2xlTmFtZTogXCJyZWFkV3JpdGVBbnlEYXRhYmFzZVwiXG4gICAgICBkYXRhYmFzZU5hbWU6IFwiYWRtaW5cIlxuICBwcm9qZWN0UmVmOlxuICAgIG5hbWU6IG15LXByb2plY3RcbiAgdXNlcm5hbWU6IHRoZXVzZXJcbiAgcGFzc3dvcmRTZWNyZXRSZWY6XG4gICAgbmFtZTogdGhlLXVzZXItcGFzc3dvcmRcbmBgYFxuKio2LioqIFdhaXQgZm9yIHRoZSBgQXRsYXNEYXRhYmFzZVVzZXJgIEN1c3RvbSBSZXNvdXJjZSB0byBiZSByZWFkeVxuXG5XYWl0IHVudGlsIHRoZSBBdGxhc0RhdGFiYXNlVXNlciByZXNvdXJjZSBnZXRzIHRvIFwicmVhZHlcIiBzdGF0dXMgKGl0IHdpbGwgd2FpdCB1bnRpbCB0aGUgY2x1c3RlciBpcyBjcmVhdGVkIHRoYXQgbWF5IHRha2UgYXJvdW5kIDEwIG1pbnV0ZXMpOlxuYGBgXG5rdWJlY3RsIGdldCBhdGxhc2RhdGFiYXNldXNlcnMgbXktZGF0YWJhc2UtdXNlciAtbz1qc29ucGF0aD0ney5zdGF0dXMuY29uZGl0aW9uc1s/KEAudHlwZT09XCJSZWFkeVwiKV0uc3RhdHVzfSdcblRydWVcbmBgYFxuIyMjIFN0ZXAgMy4gQ29ubmVjdCB5b3VyIGFwcGxpY2F0aW9uIHRvIHRoZSBBdGxhcyBDbHVzdGVyXG5cblRoZSBBdGxhcyBPcGVyYXRvciB3aWxsIGNyZWF0ZSBhIEt1YmVybmV0ZXMgU2VjcmV0IHdpdGggdGhlIGluZm9ybWF0aW9uIG5lY2Vzc2FyeSB0byBjb25uZWN0IHRvIHRoZSBBdGxhcyBDbHVzdGVyIGNyZWF0ZWRcbmluIHRoZSBwcmV2aW91cyBzdGVwLiBBbiBhcHBsaWNhdGlvbiBpbiB0aGUgc2FtZSBLdWJlcm5ldGVzIENsdXN0ZXIgY2FuIG1vdW50IGFuZCB1c2UgdGhlIFNlY3JldDpcblxuYGBgXG4uLi5cbmNvbnRhaW5lcnM6XG4gICAgICAtIG5hbWU6IHRlc3QtYXBwXG4gICAgICAgIGVudjpcbiAgICAgICAgIC0gbmFtZTogXCJDT05ORUNUSU9OX1NUUklOR1wiXG4gICAgICAgICAgIHZhbHVlRnJvbTpcbiAgICAgICAgICAgICBzZWNyZXRLZXlSZWY6XG4gICAgICAgICAgICAgICBuYW1lOiB0ZXN0LWF0bGFzLW9wZXJhdG9yLXByb2plY3QtdGVzdC1jbHVzdGVyLXRoZXVzZXJcbiAgICAgICAgICAgICAgIGtleTogY29ubmVjdGlvblN0cmluZ1N0YW5kYXJkU3J2XG5cbmBgYFxuIiwiZGlzcGxheU5hbWUiOiJNb25nb0RCIEF0bGFzIE9wZXJhdG9yIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6ImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFIOEFBQUIvQ0FZQUFBREd2UjBUQUFBQUJtSkxSMFFBL3dEL0FQK2d2YWVUQUFBQUNYQklXWE1BQUFzVEFBQUxFd0VBbXB3WUFBQUFCM1JKVFVVSDRnZ1lFaGtwOUpWaThnQUFGRU5KUkVGVWVOcnRuWG1jVmVWNXg3L1BlODZkR1VaUVVkd0FvNEthYW0xY1VBZG0zREFZbDFaam1taE1Za1Vsa01ZdE1WVnJWRXhxWTdxNG9hYk5wNkV1TWRwRXE4WkdwZjFvSkNiS0pneHFsV2lJZ0lyQUNDZ2ltd0p6bnY1eGx2dWU1ZDY1ZHhqc3ZYUFA0K2Q0dDNPQisvN2UzN08vN3dzTktoZE52OWlaOHVxTlFnT0xhZGhmTG5MQTdDVi9PT3JULzNKTURuN0QvWERoMDJzM2JSci9oNHVmejhGdk5PbnUxczl2MnJMNS9FWlcrMDZqL2VDSlQwOWkxUGlqZGhiNDZacE5Hd2E0Snc0eDcwOTcrOW1HdEh5TitLTW4vZm9iL3l5WUs5OThieVdMVjcyN0ZYUVBnZmNYWGpJalYvdjlVYzcvbndrQVRIaHE0dCtxNnBXS1VqQU9ncm9DZjczd2toa2MrS09PblBuOWR3SmNlSWt4NWs2RHdSakR5Zy9Yc21ENTIrRWc3TEh3a2hrcmMrYjNJemwzMm5rQW5EZnRna2NWN2tSQlVWUVZ4eGhBdzF1Zk9mQkhIYWFSMk4rdndmL0tFK2ZTN1cwWjhMVnA1ejJ0NkJjSVFQZmhWaVN1OXc0QkxsdDR5UXhHM05tUmcxL3Y4dk8vdUIvRW1ZM3FPRkRVQzNpdWlpcTR4c0hYQk9BQjNjcHRJKy9zK0t2Rmw4N2dnQWFZQVAzUzVuL3BWMThXak5uQlVabGx4QndpQW80NENJSVlneEhCaU1QNmp6Y3hkOGtpeEZJQkFwN0FWLzU0Nll5SGN1YlhvWHkwM2dWUGY2bm9JYUdTOTN4TFQ2RHhBY1UxRGhJTVFuZ0pHRlVlM1ArT2poTUI5citqSTJkK1BjaVpqMzBKY1VXa1c2WWI1QVF4QmdlRGlHQ01ZRENJQk13M2hvODJiMlhPb29VeDVsdmlBU2U5Y2RtTTZUbno2MEFlTy9OaGRLdmVCSHFDUmdoNkVkc2pleCs4ZG96MFJJeG45citqNDFCZkE3VG56SzlWR2ZmMFdiU3U5NjRWNFFkR0RJSmdRcFlIanlJbVlML2dpS0ZibGVjWHZvNlJjc09nSHJESEc1Zk5YTjNmd0hmN3l3OXBXYmUxRFpFYlFOQm9WdnZQTkh4SEZTUjhEMVExZHAvbEVDUzE0Ly91ZjBmNy90M0NSdVBCb20vTnpNR3ZGVG5sNFRQMlZIUzJJcUFCM0FLcWdpZUtvNElIR0FraWZGVlVGTmN4S0lvZ0tkQTEvcmdYTUd2SnBUTVB6VzEramNqSkQ1L3UyeTdod1pESlNSQjlXSXZ2ZTlGelA5WVBYM2tVbjJ2eEZxUjRmV2JrN2UzM0FveTh2WC9ZLzdvdDZZNTc2RFNlUHV0SlRuNzQ5TytEakFkODJ5MFNaZTVFQWswUXZDY1VIMEZBNEszM1Z2dnZWL2JYSHJiTHFYdS9zdWhiTTEvTEhiNy9Sem54b2RNd3lKK0ltRmNjRWRkMzZBU0RIOGI1RGw4UTNnVmhYdWo4U2ZDKzR6ZzgrOXJ2ZTNENDBoNGdNQXA0c2Q1dGY5MnEvZWxuVDBQUi8wUTkxNHNwZGdKMXJvRTYxK2kxRjVtQXdNVVQ2UzFoN3U4UFRsL2Rnai8yd1ZOdlZUaEVBeng4ZTIvYmRCSmVmMmpNTGQ5QXRiZC8vY0VqYjI5L0xBZi9FNVpqZnpHSzQzOXh5aTZxK28yd1FxZnFVWFQ0QW04KzhOdzh5N0ZMYWdYZHRuL0s1MGRNYVQ4T1lNU1U5aHo4VDBLZU82Y1REKzluQ3EyaENiWUpyQm5Qb3Z2cy9INHZtYTlhdklDSEFSWi9lMllPL2ljaEhmOXgwcWtvcHlWcjgyR0RCcEUyS0RadHFIV3ZocG9nZUwrbFVDZ0pidGFWa04xR1RHbWZtcXY5N1N5akgvaHN5TmZ2cFpNd0NkV2VVdXFoZG9nUy9DWEI3b1djTzJKSyszQmYvWS9Kd2Q4ZU12dHJ6ekQ2Z2M4ZUM5cm1xYVhDMWMvUnFmb0ZIRTgxMDc1SHZnQ1dCdGhXcSsvL3FTMmdqK2JNMzg2aThJaVN0dStSOGxlTldYamI2N2REdk1neHJCcDh6YmdBT0dyRWxERmZXUHp0V1RuNGZTMmo3aC9Ma1ErY2VLYWl1MFZBYXFqT2syekdzdnZGMTlaRFpQZlJMUGkxekZWV3JnVVllZHVZSFB5K2tzUHZIMHZudWI5QjRXKzhCR3NqU0dMMlBBR1Z4cGxQNHZ0K1NiOWlnS01zanhETCt5UEtxSkczalRsNTBlV3pjdkQ3U2w0ODl6Y2Nkdi9ZZzFUMW1CZzNMZVJEaG51WlhyK3QvaE5hUXFIZ09qMUNuZ1E3T1UrczR0Q2pBUHZWQ2Z2clF1MnI2cjFnVmQ4MGJzOURleStBZW1yWDdZcVJnR3JDNjlmSWZKUmdjblJGMFlEMWI3QXZheTYwN25mYm1EUFpzaVVIZjF2bFQrODdua04rZHNMZXhUUnUzSlZUalNkdXZJUjZUd2Q4ZGhSZ3BYOUxNemxlNnEzRU1LaGVzZVNxZWV4MzYrZ2MvRzJSQmVmOUZsUlBVV2oxVTdhYUFFSURteTRaNnQxaU94cEwrR0E1Z2w0R204dUMzSE1XcUdPL1cwY2Z0dVE3czNQd2V5djczbmRjeU9iSklhdmpTUnZiVS9maWZycEdqVnN4YjU5RWdGZWNQR1daM0pzczBML1dnOXF2NlhyK2dmY2QxK2JBYkNlb3pUdmlQd3JnaHZWNmtVU3packdHNzRoQndIOFVnd2lFeloyT0dGekg0ZFczbDdGdTAwZDlOaERCbjdNUk9CaDRhM0VOYTRDYVZ2dWlYQnhUODJxSGVwYlhML0hRTDViMEVVbVZlZG1HREovMGNBWFNDcHl5dU1aVmYwMDJjSTc4NmJFSXRDaTAyMWs1RlgvNFF4c3Rxc1dtWEpHaUxSY0o3dmNmUlNSS0Jkak5uYXBVRk9iMUxrSmhNdkJ2dWMydlVoYU5mdzZGUVFvand5WFZXTTRZcWpHdkg1VkVzVmFMcWQ2TWVOKzIvNjR4bFRBNU93OW91UUplNGxJWXR1OHRvenR5OEhzaG51cVh2WGoxbmF4Y25QL2NTeVY4MGw0L1ZuSkhveVNQWTZSSCtrZWhudzJ1VmhUK2ZTY0h2M2R5ZVh6d05lcS9LQzdGU29JZER3TkQwS1AyYmRVTVNPTk05ckpZM1B0eTc1SDczaks2TlFlL0N0bnZudmJCcW93b3BteEpsV0hUR2tGVCtYczBJMGxqTjNkYUtyc1MrOThMK1JTd1J3NStoVEw4N25hNlZjYlo5aHJOQUZBVG1UNk5SL0h4OUs0bWNvUHhoVnpiSzRZT1VzYVg1dUJYS085Y09CUGZ5eTluNzIzMkI4MGNWaTlmbUEzRVN2aGtOWGRxMzRDYmVWbno3S0ljL09ya3p6d2JTRXRkMjZvY3F5K1BoSk9YOHZwSk4zZDYyMURHcmVLcnpmdmMzSFpZRG42bE1USjZVQkh3RUtTTWpweWtWbEF0N2ZWbk5IZEd3RXA1RnZjTWRyRis0R1Zjd01uNzNOeVdnOStUREx0cnRLTXdGRXBVNUVKSHp2clFpeGllNVF5bUowTHNEbnVWWmtVVE13dnNIaFZCeDF0WHpNa3pmRDFKTnpMV3NSbXVnb29Qc0VUWlBjVy9SMklGSE4rRFY4TFFYVlJSTVVFS01QeE1ZZ21hMGt4T21nb3l6RWRGbVQ2QXczTzFYNW1NMVdURVpvVnU4VVpNVW1WZW05QlJDWmRrRzFleUV1QkZYVUFWTXJrczJCbEZ3T0g3M3RTMll3NSt6MnAxWEZhUnhxdkk2MDl6MXM3eXhVMkhXaHBmS21aMFQrWDgwREUwaVFzNEt3ZS9aL0FQVGE2dmlLMjdzN0oxdHRkZmJYT25KbDM1S3NFdEJYSjJUVUFCUFNHMytXVmt0N3ZhQmdFRmphSjM4SkRBdnFlWkx5V2VoeUFoUWYrZWlOWE5FMzRtVWN5dkhpV3JPSktlSHhXN2hRazVKZ2UvN0pqSkVCWGZzZk1pRm9XVWxjQnBJM0xvMUM3aGtpejlVdHh0SjZqcnE2ZW9rWlJMSjcxU2dWckZYWUw2cWQ1YzdaZVJuWU53Tzhid0xBY3MrVm5LUzFkS05uZmFXVDlUMFpZc1BTL2dLSDRpZU1IVkhUMzNQOXY3cHJZaE9mZ2x4SU1oc1o0NmpkdHR1eFFiWDJ4WmZYTm4yTHBkY0EzbFYrbGtBVjBFdHpzR3NwU0xGQVRJd1MvRHNCMkNoRnRtTmk5a3NPMzlxL2F1dVRNeGZjcHlQUTEwaFVvL21VaFFIWlRiL0F3WlBMVU5ZR2NQTUJRM1NrUkJSWU51SFg5bStFa2V1eVluTVROZ1l1ejNrMFJoeTVmL09uUW5RMjFoK21LbkRvZzJkU3c1QVhiSm1aOGhheWJPUVdGZ2VqUEVlTXEyVkpuWHM1bzdQWHZjSmF2TTYyZjd3bnU5U2t1N3FraTVxL3kzQlJpUWcxOTZiQWZHblRWU1M2L0NuTDVucTJkTkxzZTJsMmRaU1I2TkwrVXVrbElxQTN2YmYySWhCNzhNTzdJOCtoQWt6NC9ZWXVDRnl6UEMxVFpaelozSnZGOXNKVS92bWR3YkdaaURYMXIyME1UT0tXRUN4NHVGY0hGVnJjbGV2Tmh6RHhMNzgyQk5LbE5Gek43TGpLVTlpV3Rxa1V4TkpYa1VYUytSSTFiY0R0bERNWUhqcGdrbDdRWHVuZ2FiSzRmN0tucW92OExXMm1oUmsxNi9LSzVyK2dUZ1dHaGFKMUpqNExOT2lEZGxTakhIbDFubWRhTFBMYy9mWHFoaGZVK2lGUjY5YTloVWErWnBsUXBEdHErQ3FYL3dTWEZlTEliN1FIc0tqaEF1MHdsQ1FheFZQRmI2TjRyckpiZzFTUHdFNi8zSzlmRnBLU1pyRHdDWHZGY0JOdWZnbDViVjl2cTdNTVpQVHdlTkdqbnNvbzc5V1RTVnhBVDJYdnhDajgxK3dESEdkeVFyWlc4NW5kK3pmSlE3ZkdYQy9heHhUZmJjOTlUYzZWbXNWczA2UkVHanRLK1VPR2NuYytsV3VuK2NLdG8rRkZpZk03K0VlTXFIUmdKZUJ1cGNva1JOMGZlM3RZT0hYNXpSbU1rQXpRS2FnUDFCbGc4dGJ1Y2kyV3E2cjJWZHp2d3lhaDhvRWNSbExiREtES2VLbW9INEhqNmFUQTZGTVdUeWVJM3Q1NW10emNFdkxlOTZtcmFpbXVxNXRkVjlWbXQzWXYrOWpPUk9CTFpzSDdBek5tOVNEOTdQd1MrbEV5ZTlzQ0w4TjZsMVNFS3NCYXVhNXM0VWx6WGUzRmx0dkZZWnlMR3lydFg3THg2c3pNRXZQNXd2SjdOMHNSaS9USE5udkF3YlAxZ2h5MlJVdy9rZVFTWjc0WWNsSDZ5NGV1N1dIUHp5OGxSeTFMMmt6ZGY0a3Uyd3VUT2FKSmE2OTdkbEliN2xPdW1ObXRLVEozNUZVVUNQSzNwS05vWFUzTEdzdFFqK1ExcGlHMVV5R0orZUZPazBia3lEMkR0M0VxekJ6NENxc3JWNVZlM1ArMVFPZm85MmYrNDhZSXRtZVAzcEhuNTdWODNrMlhpYXNYbVR2Y3dxRFBPMHQweXU5cWY5TWdlL1VydXYyUkYzY2hkTno4cndrZkFQc3Zid0tmNGh5WnArS1RiM1RZajN6bmZuclJyK0QwZm00RmNnTDBTSm54SmVQd243SDIvdUpISEFBdG5ObmZLSnhmZXZBcnp6M1hrNStPVmswRStPQXZoMXFiTnR5WWo5eXpkM1N2eGJHdCtmWS9OV2IvdnByK0pLbjg1YVpGZ3QybnlBeDFLQWE3SDMzbzZoWTE1L0xPR1RiQUNMTzRpaHJ5Q1M3QkRvRTdDVDVtUjZEbjdsRTBDQkIyTW5ZMlR3Mzl1bTVzN3E5K0NzOHVRdFc1N013YTlPYnNoS3hLUU9UYks0N1NYVWYxWnpaeXdyQ0d3dG9mYXJCTGVjL1BleWErWnR6Y0d2enU0dkFWMnFhdHZyREovY2J1NGtxN2t6V2VhTnIrQ05GbXYyRGRCWjh2MWFaVmV0cW4zV1RacTd5YmFWcWRDYm5wczdTNjN2S3pxRjJ0ZEFKMlVWc0dEWUQ0K3NTZkJkYWx1dUJoMGZkdWJZblRxVk5IZmFaK2w0UVN0WDZDczR3ZktmclZzOVpQdjExTTVmZHMyOERUbnplNkg2MTAyYTJ3VThtcW51UzJ5aG5pN3p4aHM4VTNGL0gxTy9tQlpXZ0IvV01yTnFGdngxaythR3R2OEdvRHQ1bmw2bTF4OUw0Sk1xODNxcHJLSFMzZTMxR2RoaU9RMEtieXk3WnQ3dmh0ODRLZ2UvOTdMbFpkQ2xXWGJmOXZxOU1zbWZlRXRYTWN6ekFNK3JEdHdreUY1NGtTcjFYZ0h3enJXZE5UdXlRaDNJb0o4Y2RRekljMGI4M251RGY3aUMvZHJndnpZSWpwSGdlQldKM25jUVJBUlhndnRGY0kxaDJkdHI2ZTdXOUlCb09yTlFoWUZZQTR3QVBsaGV3K0NiT2dDZWRaUG1QZzg4a1FKQkV4azdTTFIzcGIzOFpDYS9lNHNYaS9HU1RLNjZQOWUvYmxsK2JXZE5BMTlIekQ4YTRFZ1I1b3JGY3FGNDRGTEk1a2dEQkljdE9ZR1djQUlONFFRSE5Vbnd1SFR4QjczMzlyTm54T3JsMTNYdVZnL2pXaGNuYXE2YjlBTHJKcjB3VDVWZkpjYzlleWwzYWZhcmxmRHhWQ3RsY2pYbC9PdXBFNm1ySTlTQnM0SDNTalYzVXFLNVV4TmVmL2kxeU5iM1NhOEdBQjhDVTRmK1lGUmRES1pUVDhodmZueFpkOHNad3pZRHAvZ0xNSHdUUUdBQ3d2MzFKRWpvaVArL3hEM0JjeEc4Ym1YajJzMjlObjRacTNxT1gzNWQ1OUoxMDFma3pOOGVzbmJpQzFPQVdTRmprMnBkMUdyN0RtaWVMdk1HMytraHhxL3dETDN3NzM5aTJYV2RjNGJWQ2V2ckV2eWRwaDROOE9jS0c4czFkeWJidldKbDNsRHRKMVpvVm5Lc1d0YnFvT0NNbm9zQmxsM1htWU8vbmRtL1J0R3JpZkZaTXhJNkpabzdnNDZlSm5WaW9HZUJYT3FrcmNUNi9qTldUTzU4ZTYrL0gxVlg0eWoxQ1A1T1U0OW03Y1FYR0R5MTdRR0JyeG9KYkh4V3drZkVQMWMzQ2dXTENaOGROeFpZdlBLOWFDTUg2ZDNPR3RNRnhpbm9pc21kT2ZpZmhBVDc5ZzBFM2piQ1lCTUFLaEc0eGNmb0VHWUVSOExKSVF6ZDBNcExxN3A4aDdCM29mMW1vS1ZyY3FmVzR4aWFlZ1YvemNRNXJKazRaejF3aE1MbXJOWnR0ZVozdUE5bnNibFRHWkt4TFY3bG9iMENqTzJhM0tsNzFwbTZyM3Z3US9hdm1Uam5UWUd6MDB1eHJKYnUxTjU5L24rNzBscXk4YU9jcXhjVWlXL3NtdHc1RTZDcnp0Ujl2d0IvemNRNTdESzFqZmUrUHVlL1FDZmFuM2xKbmlhYU96MWdUN05Eb3BPbkNLNEVtN0lhRFMraVM1UWZkMDJlZjkyUUc0K281K0dycnlSUGxteDZmQm03L25zYjczMTl6dndkemhnK0ZHRlVtUEFKZllBdzRTUGkrL1hoaGswZFc0YXk2T1AzMmFBZlIvVUIwUjVQMEo0RGZISFEyTDMwM2NuejYzcnNoSDRtUSs0YS9ZaEIvakwwK3AwZ0NuQ0N2WGZjd1BGVFVhN2FlRFJQYnZnanN6WXNyZFRwV3dBY3Z2ejYrVnY2dzFpWmZnYThySjR3KzR2QTQybzVlR0d5eDQ3M1c5WEZ4ZkNaQVh2U1hhTEFrempRNFJXRlkvc0w4UDBPL05VVFp1dnVkNDFoNVlSWlp3Qy9TMmIyYkg5Z0wyOGdIc3JRd280TU1HN1pqUmVBSlFwdG10Z3RyTjdGcFIvSzduZU5vUVhHZmd5UEtaeGVyQUtHWGI3SzhPNUJZUHh1bnQwTGczaG5jOG05a3VZRFk3dXVuNytwdjQyVDZXOC9hT1dFV2F5Y01JdVB3ZXZ5TmNEUDdlU01CcnQ0N09QdGhBcTRqc01SQTRleFZiMHNwZjh5ZEkrbXhyWlF5OEh2UWJvbXpHTG9YV05ZUG1IbVZ4V3VESUVIS09Bd21CYkVDQ0tHazRjY3hHQjNRQlR4QjNIOGo0RlJYZGUvdktYcit2bWFnMTluc256Q0xJYmQzYzZ5QzJmZURIeFRvUnRnUjY4SkZ4OTRZd3dleWxValBrZXJGRUIxTThxVlhkZS9lQkhCL2YxVmhBYVNmZTdwMkZlUUJRZm96cTNuZUFmaE9BV2FDazAwTlRYVDNOeUNOTFh3VDY4L2Z2QnpsMDk3YmErL081d1YzM3V4WDQrSGFSVGdQM1YzQjI5ZE1PUE5OMlg1MEdPNmgvbXQzOFpFbDJOY1dwM0N4YzlkUHUyMVMrLzVacjhIdnVHWUg4clVxVmZjNnpydStFS2hpYVpDRTgxTkxUUzNERmpsdWswSEduRStPUEdrQ3h0aUhOeEdCTjh4NWhFUk05Nkl3VEVPeG5Fd3h2Mzl1TTlOL0tDUnhzRTBJdmpHT0F1Tk1WdDhsZS9nT0M2T2NaOXR1SEdnSVVXWEd1TnNkWXlEQlBiZWNaeVhjdkFiUU02LzRCODNPa1pXaTNGd0hSZkhkVEdPdXpRSHYyRlV2enNqOHZTZEFxNWJXSkdEM3pEZ20wN0hNUmluZ09PNjdEQmdodzl5OEJ2SDQzL2RpSVBydXJpT2kxdG9raHo4QnZMNEhjY05WVDVPb1VBT2ZxUDhjTWRkNVlQdjRMcE5GTnptSFB4R2tUUE92SHlONHpnKzh3dE5OTGUwNU9BM0dQc3B1QVVLaFNZVTJUa0h2NEdrNEJROHQ5QkVVNkdaNXFibVFUbjRqZVR4dTRXWDNFS0JRbk16aGVhVzNYUHdHMFNlKyswRHRCOTd6cWpXbG9HN05oVmE3bTVwR2pDWVhCcEhYbHNRM3daL3cvcGxEZlg3L3c5c0pUeUw5aE12R1FBQUFBQkpSVTVFcmtKZ2dnPT0iLCJtZWRpYXR5cGUiOiJpbWFnZS9wbmcifV0sImluc3RhbGwiOnsic3BlYyI6eyJjbHVzdGVyUGVybWlzc2lvbnMiOlt7InJ1bGVzIjpbeyJhcGlHcm91cHMiOlsiIl0sInJlc291cmNlcyI6WyJldmVudHMiXSwidmVyYnMiOlsiY3JlYXRlIiwicGF0Y2giXX0seyJhcGlHcm91cHMiOlsiIl0sInJlc291cmNlcyI6WyJzZWNyZXRzIl0sInZlcmJzIjpbImNyZWF0ZSIsImRlbGV0ZSIsImdldCIsImxpc3QiLCJwYXRjaCIsInVwZGF0ZSIsIndhdGNoIl19LHsiYXBpR3JvdXBzIjpbImF0bGFzLm1vbmdvZGIuY29tIl0sInJlc291cmNlcyI6WyJhdGxhc2NsdXN0ZXJzIl0sInZlcmJzIjpbImNyZWF0ZSIsImRlbGV0ZSIsImdldCIsImxpc3QiLCJwYXRjaCIsInVwZGF0ZSIsIndhdGNoIl19LHsiYXBpR3JvdXBzIjpbImF0bGFzLm1vbmdvZGIuY29tIl0sInJlc291cmNlcyI6WyJhdGxhc2NsdXN0ZXJzL3N0YXR1cyJdLCJ2ZXJicyI6WyJnZXQiLCJwYXRjaCIsInVwZGF0ZSJdfSx7ImFwaUdyb3VwcyI6WyJhdGxhcy5tb25nb2RiLmNvbSJdLCJyZXNvdXJjZXMiOlsiYXRsYXNkYXRhYmFzZXVzZXJzIl0sInZlcmJzIjpbImNyZWF0ZSIsImRlbGV0ZSIsImdldCIsImxpc3QiLCJwYXRjaCIsInVwZGF0ZSIsIndhdGNoIl19LHsiYXBpR3JvdXBzIjpbImF0bGFzLm1vbmdvZGIuY29tIl0sInJlc291cmNlcyI6WyJhdGxhc2RhdGFiYXNldXNlcnMvc3RhdHVzIl0sInZlcmJzIjpbImdldCIsInBhdGNoIiwidXBkYXRlIl19LHsiYXBpR3JvdXBzIjpbImF0bGFzLm1vbmdvZGIuY29tIl0sInJlc291cmNlcyI6WyJhdGxhc3Byb2plY3RzIl0sInZlcmJzIjpbImNyZWF0ZSIsImRlbGV0ZSIsImdldCIsImxpc3QiLCJwYXRjaCIsInVwZGF0ZSIsIndhdGNoIl19LHsiYXBpR3JvdXBzIjpbImF0bGFzLm1vbmdvZGIuY29tIl0sInJlc291cmNlcyI6WyJhdGxhc3Byb2plY3RzL3N0YXR1cyJdLCJ2ZXJicyI6WyJnZXQiLCJwYXRjaCIsInVwZGF0ZSJdfV0sInNlcnZpY2VBY2NvdW50TmFtZSI6Im1vbmdvZGItYXRsYXMtb3BlcmF0b3IifV0sImRlcGxveW1lbnRzIjpbeyJuYW1lIjoibW9uZ29kYi1hdGxhcy1vcGVyYXRvciIsInNwZWMiOnsicmVwbGljYXMiOjEsInNlbGVjdG9yIjp7Im1hdGNoTGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ImNvbnRyb2xsZXIiLCJhcHAua3ViZXJuZXRlcy5pby9pbnN0YW5jZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciIsImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiJtb25nb2RiLWF0bGFzLWt1YmVybmV0ZXMtb3BlcmF0b3IifX0sInN0cmF0ZWd5Ijp7fSwidGVtcGxhdGUiOnsibWV0YWRhdGEiOnsibGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL2NvbXBvbmVudCI6ImNvbnRyb2xsZXIiLCJhcHAua3ViZXJuZXRlcy5pby9pbnN0YW5jZSI6Im1vbmdvZGItYXRsYXMta3ViZXJuZXRlcy1vcGVyYXRvciIsImFwcC5rdWJlcm5ldGVzLmlvL25hbWUiOiJtb25nb2RiLWF0bGFzLWt1YmVybmV0ZXMtb3BlcmF0b3IifX0sInNwZWMiOnsiY29udGFpbmVycyI6W3siYXJncyI6WyItLWF0bGFzLWRvbWFpbj1odHRwczovL2Nsb3VkLm1vbmdvZGIuY29tIiwiLS1sZWFkZXItZWxlY3QiLCItLWhlYWx0aC1wcm9iZS1iaW5kLWFkZHJlc3M9OjgwODEiLCItLW1ldHJpY3MtYmluZC1hZGRyZXNzPTEyNy4wLjAuMTo4MDgwIl0sImNvbW1hbmQiOlsiL21hbmFnZXIiXSwiZW52IjpbeyJuYW1lIjoiT1BFUkFUT1JfUE9EX05BTUUiLCJ2YWx1ZUZyb20iOnsiZmllbGRSZWYiOnsiZmllbGRQYXRoIjoibWV0YWRhdGEubmFtZSJ9fX0seyJuYW1lIjoiT1BFUkFUT1JfTkFNRVNQQUNFIiwidmFsdWVGcm9tIjp7ImZpZWxkUmVmIjp7ImZpZWxkUGF0aCI6Im1ldGFkYXRhLm5hbWVzcGFjZSJ9fX0seyJuYW1lIjoiV0FUQ0hfTkFNRVNQQUNFIiwidmFsdWVGcm9tIjp7ImZpZWxkUmVmIjp7ImZpZWxkUGF0aCI6Im1ldGFkYXRhLmFubm90YXRpb25zWydvbG0udGFyZ2V0TmFtZXNwYWNlcyddIn19fV0sImltYWdlIjoiZG9ja2VyLmlvL2lrYXJwdWtoaW4vbW9uZ29kYi1hdGxhcy1vcGVyYXRvcjowLjUuMCIsImltYWdlUHVsbFBvbGljeSI6IkFsd2F5cyIsImxpdmVuZXNzUHJvYmUiOnsiaHR0cEdldCI6eyJwYXRoIjoiL2hlYWx0aHoiLCJwb3J0Ijo4MDgxfSwiaW5pdGlhbERlbGF5U2Vjb25kcyI6MTUsInBlcmlvZFNlY29uZHMiOjIwfSwibmFtZSI6Im1hbmFnZXIiLCJyZWFkaW5lc3NQcm9iZSI6eyJodHRwR2V0Ijp7InBhdGgiOiIvcmVhZHl6IiwicG9ydCI6ODA4MX0sImluaXRpYWxEZWxheVNlY29uZHMiOjUsInBlcmlvZFNlY29uZHMiOjEwfSwicmVzb3VyY2VzIjp7ImxpbWl0cyI6eyJjcHUiOiI1MDBtIiwibWVtb3J5IjoiMjU2TWkifSwicmVxdWVzdHMiOnsiY3B1IjoiMTAwbSIsIm1lbW9yeSI6IjUwTWkifX0sInNlY3VyaXR5Q29udGV4dCI6eyJhbGxvd1ByaXZpbGVnZUVzY2FsYXRpb24iOmZhbHNlfX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJtb25nb2RiLWF0bGFzLW9wZXJhdG9yIiwidGVybWluYXRpb25HcmFjZVBlcmlvZFNlY29uZHMiOjEwfX19fV0sInBlcm1pc3Npb25zIjpbeyJydWxlcyI6W3siYXBpR3JvdXBzIjpbIiIsImNvb3JkaW5hdGlvbi5rOHMuaW8iXSwicmVzb3VyY2VzIjpbImNvbmZpZ21hcHMiLCJsZWFzZXMiXSwidmVyYnMiOlsiZ2V0IiwibGlzdCIsIndhdGNoIiwiY3JlYXRlIiwidXBkYXRlIiwicGF0Y2giLCJkZWxldGUiXX0seyJhcGlHcm91cHMiOlsiIl0sInJlc291cmNlcyI6WyJldmVudHMiXSwidmVyYnMiOlsiY3JlYXRlIiwicGF0Y2giXX1dLCJzZXJ2aWNlQWNjb3VudE5hbWUiOiJtb25nb2RiLWF0bGFzLW9wZXJhdG9yIn1dfSwic3RyYXRlZ3kiOiJkZXBsb3ltZW50In0sImluc3RhbGxNb2RlcyI6W3sic3VwcG9ydGVkIjp0cnVlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOnRydWUsInR5cGUiOiJTaW5nbGVOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6dHJ1ZSwidHlwZSI6Ik11bHRpTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOnRydWUsInR5cGUiOiJBbGxOYW1lc3BhY2VzIn1dLCJrZXl3b3JkcyI6WyJNb25nb0RCIiwiQXRsYXMiLCJEYXRhYmFzZSIsIlJlcGxpY2EgU2V0IiwiQ2x1c3RlciJdLCJsaW5rcyI6W3sibmFtZSI6Ik1vbmdvREIgQXRsYXMgS3ViZXJuZXRlcyIsInVybCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9tb25nb2RiL21vbmdvZGItYXRsYXMta3ViZXJuZXRlcyJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoic3VwcG9ydEBtb25nb2RiLmNvbSIsIm5hbWUiOiJNb25nb0RCLCBJbmMifV0sIm1hdHVyaXR5IjoiYmV0YSIsInByb3ZpZGVyIjp7Im5hbWUiOiJNb25nb0RCLCBJbmMifSwidmVyc2lvbiI6IjAuNS4wIn19 -- type: olm.bundle.object - value: - data: eyJhcGlWZXJzaW9uIjoicmJhYy5hdXRob3JpemF0aW9uLms4cy5pby92MSIsImtpbmQiOiJDbHVzdGVyUm9sZSIsIm1ldGFkYXRhIjp7ImNyZWF0aW9uVGltZXN0YW1wIjpudWxsLCJuYW1lIjoibW9uZ29kYi1hdGxhcy1tZXRyaWNzLXJlYWRlciJ9LCJydWxlcyI6W3sibm9uUmVzb3VyY2VVUkxzIjpbIi9tZXRyaWNzIl0sInZlcmJzIjpbImdldCJdfV19 -relatedImages: -- image: docker.io/ikarpukhin/mongodb-atlas-controller-bundle:0.5.0 - name: "" -- image: docker.io/ikarpukhin/mongodb-atlas-operator:0.5.0 - name: "" -schema: olm.bundle diff --git a/test/e2e/data/atlasdatabaseuserresp_608df5e652e1944293e8584a.json b/test/e2e/data/atlasdatabaseuserresp_608df5e652e1944293e8584a.json new file mode 100644 index 0000000000..17e83352ef --- /dev/null +++ b/test/e2e/data/atlasdatabaseuserresp_608df5e652e1944293e8584a.json @@ -0,0 +1,27 @@ +{ + "awsIAMType":"NONE", + "databaseName":"admin", + "groupId":"608df5e652e1944293e8584a", + "labels":[ + + ], + "ldapAuthType":"NONE", + "links":[ + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/608df5e652e1944293e8584a/databaseUsers/admin/testuser123", + "rel":"self" + } + ], + "roles":[ + { + "databaseName":"admin", + "roleName":"readWriteAnyDatabase" + } + ], + "scopes":[ + + ], + "username":"testuser123", + "x509Type":"NONE" + } + \ No newline at end of file diff --git a/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentcreating.json b/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentcreating.json new file mode 100644 index 0000000000..b81d1bf7c1 --- /dev/null +++ b/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentcreating.json @@ -0,0 +1,92 @@ +{ + "autoScaling":{ + "autoIndexingEnabled":false, + "compute":{ + "enabled":false, + "scaleDownEnabled":false + }, + "diskGBEnabled":false + }, + "backupEnabled":false, + "biConnector":{ + "enabled":false, + "readPreference":"secondary" + }, + "clusterType":"REPLICASET", + "connectionStrings":{ + "standard":"mongodb://mycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-nwp2f7-shard-0", + "standardSrv":"mongodb+srv://mycluster.hhhjj.mongodb.net" + }, + "createDate":"2021-05-02T00:45:25Z", + "diskSizeGB":0.5, + "encryptionAtRestProvider":"NONE", + "groupId":"groupid123", + "id":"clusterid123", + "labels":[ + + ], + "links":[ + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1", + "rel":"self" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1/restoreJobs", + "rel":"http://cloud.mongodb.com/restoreJobs" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1/snapshots", + "rel":"http://cloud.mongodb.com/snapshots" + } + ], + "mongoDBMajorVersion":"4.4", + "mongoDBVersion":"4.4.11", + "mongoURI":"mongodb://dmycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017", + "mongoURIUpdated":"2021-09-13T13:53:50Z", + "mongoURIWithOptions":"mongodb://dmycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-nwp2f7-shard-0", + "name":"mydeploymentcreating", + "numShards":1, + "paused":false, + "pitEnabled":false, + "providerBackupEnabled":false, + "providerSettings":{ + "providerName":"TENANT", + "autoScaling":{ + "compute":{ + "maxInstanceSize":null, + "minInstanceSize":null + } + }, + "backingProviderName":"AWS", + "regionName":"US_EAST_1", + "instanceSizeName":"M0" + }, + "replicationFactor":3, + "replicationSpec":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "replicationSpecs":[ + { + "id":"608df5feb0b61158d95e3ab7", + "numShards":1, + "regionsConfig":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "zoneName":"Zone 1" + } + ], + "rootCertType":"ISRGROOTX1", + "srvAddress":"mongodb+srv://mydeploymentready.hhhjj.mongodb.net", + "stateName":"CREATING", + "versionReleaseSystem":"LTS" +} diff --git a/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentready.json b/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentready.json new file mode 100644 index 0000000000..a6b007e515 --- /dev/null +++ b/test/e2e/data/atlasdeploymentget_groupid123_mydeploymentready.json @@ -0,0 +1,92 @@ +{ + "autoScaling":{ + "autoIndexingEnabled":false, + "compute":{ + "enabled":false, + "scaleDownEnabled":false + }, + "diskGBEnabled":false + }, + "backupEnabled":false, + "biConnector":{ + "enabled":false, + "readPreference":"secondary" + }, + "clusterType":"REPLICASET", + "connectionStrings":{ + "standard":"mongodb://mycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-nwp2f7-shard-0", + "standardSrv":"mongodb+srv://mycluster.hhhjj.mongodb.net" + }, + "createDate":"2021-05-02T00:45:25Z", + "diskSizeGB":0.5, + "encryptionAtRestProvider":"NONE", + "groupId":"groupid123", + "id":"clusterid123", + "labels":[ + + ], + "links":[ + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1", + "rel":"self" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1/restoreJobs", + "rel":"http://cloud.mongodb.com/restoreJobs" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters/DBaaS-Cluster1/snapshots", + "rel":"http://cloud.mongodb.com/snapshots" + } + ], + "mongoDBMajorVersion":"4.4", + "mongoDBVersion":"4.4.11", + "mongoURI":"mongodb://dmycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017", + "mongoURIUpdated":"2021-09-13T13:53:50Z", + "mongoURIWithOptions":"mongodb://dmycluster-shard-00-00.hhhjj.mongodb.net:27017,mycluster-shard-00-01.hhhjj.mongodb.net:27017,mycluster-shard-00-02.hhhjj.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-nwp2f7-shard-0", + "name":"mydeploymentready", + "numShards":1, + "paused":false, + "pitEnabled":false, + "providerBackupEnabled":false, + "providerSettings":{ + "providerName":"TENANT", + "autoScaling":{ + "compute":{ + "maxInstanceSize":null, + "minInstanceSize":null + } + }, + "backingProviderName":"AWS", + "regionName":"US_EAST_1", + "instanceSizeName":"M0" + }, + "replicationFactor":3, + "replicationSpec":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "replicationSpecs":[ + { + "id":"608df5feb0b61158d95e3ab7", + "numShards":1, + "regionsConfig":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "zoneName":"Zone 1" + } + ], + "rootCertType":"ISRGROOTX1", + "srvAddress":"mongodb+srv://mydeploymentready.hhhjj.mongodb.net", + "stateName":"IDLE", + "versionReleaseSystem":"LTS" +} diff --git a/test/e2e/data/atlasdeploymentlistresp_608df5e652e1944293e8584a.json b/test/e2e/data/atlasdeploymentlistresp_608df5e652e1944293e8584a.json new file mode 100644 index 0000000000..e0087bb69c --- /dev/null +++ b/test/e2e/data/atlasdeploymentlistresp_608df5e652e1944293e8584a.json @@ -0,0 +1,105 @@ +{ + "links":[ + { + "href":"$BASEURL/groups/60b798fea37f9f09acc1a154/clusters?pageNum=1&itemsPerPage=100", + "rel":"self" + } + ], + "results":[ + { + "autoScaling":{ + "autoIndexingEnabled":false, + "compute":{ + "enabled":false, + "scaleDownEnabled":false + }, + "diskGBEnabled":true + }, + "backupEnabled":false, + "biConnector":{ + "enabled":false, + "readPreference":"secondary" + }, + "clusterType":"REPLICASET", + "connectionStrings":{ + "standard":"mongodb://testb-shard-00-00.fffff.mongodb.net:27017,testb-shard-00-01.fffff.mongodb.net:27017,testb-shard-00-02.fffff.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-eituqf-shard-0", + "standardSrv":"mongodb+srv://testb.fffff.mongodb.net" + }, + "createDate":"2021-06-02T15:43:43Z", + "diskSizeGB":10.0, + "encryptionAtRestProvider":"NONE", + "groupId":"60b798fea37f9f09acc1a154", + "id":"70b7a72f4877d05880c487ef", + "labels":[ + + ], + "links":[ + { + "href":"$BASEURL/groups/60b798fea37f9f09acc1a154/clusters/testb", + "rel":"self" + }, + { + "href":"$BASEURL/groups/60b798fea37f9f09acc1a154/clusters/testb/restoreJobs", + "rel":"http://cloud.mongodb.com/restoreJobs" + }, + { + "href":"$BASEURL/groups/60b798fea37f9f09acc1a154/clusters/testb/snapshots", + "rel":"http://cloud.mongodb.com/snapshots" + } + ], + "mongoDBMajorVersion":"4.4", + "mongoDBVersion":"4.4.6", + "mongoURI":"mongodb://testb-shard-00-00.fffff.mongodb.net:27017,testb-shard-00-01.fffff.mongodb.net:27017,testb-shard-00-02.fffff.mongodb.net:27017", + "mongoURIUpdated":"2021-06-02T15:55:28Z", + "mongoURIWithOptions":"mongodb://testb-shard-00-00.fffff.mongodb.net:27017,testb-shard-00-01.fffff.mongodb.net:27017,testb-shard-00-02.fffff.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-eituqf-shard-0", + "name":"testb", + "numShards":1, + "paused":true, + "pitEnabled":false, + "providerBackupEnabled":false, + "providerSettings":{ + "providerName":"AWS", + "autoScaling":{ + "compute":{ + "maxInstanceSize":null, + "minInstanceSize":null + } + }, + "diskIOPS":1000, + "encryptEBSVolume":true, + "instanceSizeName":"M10", + "regionName":"US_EAST_1", + "volumeType":"STANDARD" + }, + "replicationFactor":3, + "replicationSpec":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "replicationSpecs":[ + { + "id":"60b7a72f4877d05880c487cc", + "numShards":1, + "regionsConfig":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "zoneName":"Zone 1" + } + ], + "rootCertType":"ISRGROOTX1", + "srvAddress":"mongodb+srv://testb.fffff.mongodb.net", + "stateName":"IDLE", + "versionReleaseSystem":"LTS" + } + ], + "totalCount":1 + } diff --git a/test/e2e/data/atlasdeploymentlistresp_60b798fea37f9f09acc1a154.json b/test/e2e/data/atlasdeploymentlistresp_60b798fea37f9f09acc1a154.json new file mode 100644 index 0000000000..fb23cd2e80 --- /dev/null +++ b/test/e2e/data/atlasdeploymentlistresp_60b798fea37f9f09acc1a154.json @@ -0,0 +1,105 @@ +{ + "links":[ + { + "href":"$BASEURL/groups/608df5e652e1944293e8584a/clusters?pageNum=1&itemsPerPage=100", + "rel":"self" + } + ], + "results":[ + { + "autoScaling":{ + "autoIndexingEnabled":false, + "compute":{ + "enabled":false, + "scaleDownEnabled":false + }, + "diskGBEnabled":true + }, + "backupEnabled":false, + "biConnector":{ + "enabled":false, + "readPreference":"secondary" + }, + "clusterType":"REPLICASET", + "connectionStrings":{ + "standard":"mongodb://testa-shard-00-00.ccccc.mongodb.net:27017,testa-shard-00-01.ccccc.mongodb.net:27017,testa-shard-00-02.ccccc.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-eituqf-shard-0", + "standardSrv":"mongodb+srv://testa.ccccc.mongodb.net" + }, + "createDate":"2021-06-02T15:43:43Z", + "diskSizeGB":10.0, + "encryptionAtRestProvider":"NONE", + "groupId":"608df5e652e1944293e8584a", + "id":"60b7a72f4877d05880c487d2", + "labels":[ + + ], + "links":[ + { + "href":"$BASEURL/groups/608df5e652e1944293e8584a/clusters/testa", + "rel":"self" + }, + { + "href":"$BASEURL/groups/608df5e652e1944293e8584a/clusters/testa/restoreJobs", + "rel":"http://cloud.mongodb.com/restoreJobs" + }, + { + "href":"$BASEURL/groups/608df5e652e1944293e8584a/clusters/testa/snapshots", + "rel":"http://cloud.mongodb.com/snapshots" + } + ], + "mongoDBMajorVersion":"4.4", + "mongoDBVersion":"4.4.6", + "mongoURI":"mongodb://testa-shard-00-00.ccccc.mongodb.net:27017,testa-shard-00-01.ccccc.mongodb.net:27017,testa-shard-00-02.ccccc.mongodb.net:27017", + "mongoURIUpdated":"2021-06-02T15:55:28Z", + "mongoURIWithOptions":"mongodb://testa-shard-00-00.ccccc.mongodb.net:27017,testa-shard-00-01.ccccc.mongodb.net:27017,testa-shard-00-02.ccccc.mongodb.net:27017/?ssl=true&authSource=admin&replicaSet=atlas-eituqf-shard-0", + "name":"testa", + "numShards":1, + "paused":true, + "pitEnabled":false, + "providerBackupEnabled":false, + "providerSettings":{ + "providerName":"AWS", + "autoScaling":{ + "compute":{ + "maxInstanceSize":null, + "minInstanceSize":null + } + }, + "diskIOPS":1000, + "encryptEBSVolume":true, + "instanceSizeName":"M10", + "regionName":"US_EAST_1", + "volumeType":"STANDARD" + }, + "replicationFactor":3, + "replicationSpec":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "replicationSpecs":[ + { + "id":"60b7a72f4877d05880c487cc", + "numShards":1, + "regionsConfig":{ + "US_EAST_1":{ + "analyticsNodes":0, + "electableNodes":3, + "priority":7, + "readOnlyNodes":0 + } + }, + "zoneName":"Zone 1" + } + ], + "rootCertType":"ISRGROOTX1", + "srvAddress":"mongodb+srv://testa.ccccc.mongodb.net", + "stateName":"IDLE", + "versionReleaseSystem":"LTS" + } + ], + "totalCount":1 + } diff --git a/test/e2e/data/atlasdeploymentlistresp_611521839f76ee7b6501dd2b.json b/test/e2e/data/atlasdeploymentlistresp_611521839f76ee7b6501dd2b.json new file mode 100644 index 0000000000..3246e13450 --- /dev/null +++ b/test/e2e/data/atlasdeploymentlistresp_611521839f76ee7b6501dd2b.json @@ -0,0 +1,12 @@ +{ + "links":[ + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/611521839f76ee7b6501dd2b/clusters?pageNum=1&itemsPerPage=100", + "rel":"self" + } + ], + "results":[ + + ], + "totalCount":0 +} diff --git a/test/e2e/data/atlasinventoryexpected.json b/test/e2e/data/atlasinventoryexpected.json new file mode 100644 index 0000000000..2b42138463 --- /dev/null +++ b/test/e2e/data/atlasinventoryexpected.json @@ -0,0 +1,28 @@ +[ + { + "instanceID":"70b7a72f4877d05880c487ef", + "name":"testb", + "instanceInfo":{ + "connectionStringsStandardSrv":"mongodb+srv://testb.fffff.mongodb.net", + "instanceSizeName":"M10", + "state":"Ready", + "projectID":"608df5e652e1944293e8584a", + "projectName":"Project 1", + "providerName":"AWS", + "regionName":"US_EAST_1" + } + }, + { + "instanceID":"60b7a72f4877d05880c487d2", + "name":"testa", + "instanceInfo":{ + "connectionStringsStandardSrv":"mongodb+srv://testa.ccccc.mongodb.net", + "instanceSizeName":"M10", + "state":"Ready", + "projectID":"60b798fea37f9f09acc1a154", + "projectName":"Project 2", + "providerName":"AWS", + "regionName":"US_EAST_1" + } + } + ] diff --git a/test/e2e/data/atlasprojectget_myproject.json b/test/e2e/data/atlasprojectget_myproject.json new file mode 100644 index 0000000000..fdffe4ffd2 --- /dev/null +++ b/test/e2e/data/atlasprojectget_myproject.json @@ -0,0 +1,37 @@ +{ + "clusterCount":0, + "created":"2021-12-21T15:41:07Z", + "id":"groupid123", + "links":[ + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123", + "rel":"self" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/containers", + "rel":"http://cloud.mongodb.com/containers" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/clusters", + "rel":"http://cloud.mongodb.com/clusters" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/databaseUsers", + "rel":"http://cloud.mongodb.com/databaseUsers" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/peers", + "rel":"http://cloud.mongodb.com/peers" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/processes", + "rel":"http://cloud.mongodb.com/processes" + }, + { + "href":"https://cloud.mongodb.com/api/atlas/v1.0/groups/groupid123/whitelist", + "rel":"http://cloud.mongodb.com/whitelist" + } + ], + "name":"myproject", + "orgId":"orgid123" +} diff --git a/test/e2e/data/atlasprojectlistresp.json b/test/e2e/data/atlasprojectlistresp.json new file mode 100644 index 0000000000..0780a5620e --- /dev/null +++ b/test/e2e/data/atlasprojectlistresp.json @@ -0,0 +1,37 @@ +{ + "links":[ + { + "href":"$BASEURL/groups?pageNum=1&itemsPerPage=100", + "rel":"self" + } + ], + "results":[ + { + "clusterCount":1, + "created":"2021-05-02T00:44:24Z", + "id":"608df5e652e1944293e8584a", + "links":[ + { + "href":"$BASEURL/groups/608df5e652e1944293e8584a", + "rel":"self" + } + ], + "name":"Project 1", + "orgId":"605b7e573fb20e3bdff80417" + }, + { + "clusterCount":1, + "created":"2021-06-02T14:43:11Z", + "id":"60b798fea37f9f09acc1a154", + "links":[ + { + "href":"$BASEURL/groups/60b798fea37f9f09acc1a154", + "rel":"self" + } + ], + "name":"Project 2", + "orgId":"605b7e573fb20e3bdff80417" + } + ], + "totalCount":2 +} diff --git a/test/e2e/data/atlasprojectlistresp_single.json b/test/e2e/data/atlasprojectlistresp_single.json new file mode 100644 index 0000000000..c3e6a25f29 --- /dev/null +++ b/test/e2e/data/atlasprojectlistresp_single.json @@ -0,0 +1,24 @@ +{ + "links":[ + { + "href":"$BASEURL/groups?pageNum=1&itemsPerPage=100", + "rel":"self" + } + ], + "results":[ + { + "clusterCount":0, + "created":"2021-06-02T14:43:11Z", + "id":"611521839f76ee7b6501dd2b", + "links":[ + { + "href":"$BASEURL/groups/611521839f76ee7b6501dd2b", + "rel":"self" + } + ], + "name":"Project 3", + "orgId":"605b7e573fb20e3bdff80417" + } + ], + "totalCount":1 +} diff --git a/test/e2e/data/dummy_deployment.json b/test/e2e/data/dummy_deployment.json new file mode 100644 index 0000000000..fb70cd2b35 --- /dev/null +++ b/test/e2e/data/dummy_deployment.json @@ -0,0 +1,82 @@ +{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "operator", + "namespace": "dbaas-operators", + "labels": { + "olm.owner": "mongodb-atlas-kubernetes.v0.0.0", + "olm.owner.kind": "ClusterServiceVersion", + "olm.owner.namespace": "dbaas-operators" + } + }, + "spec": { + "replicas": 1, + "template": { + "metadata": { + "labels": null + }, + "spec": { + "serviceAccountName": "operator", + "containers": [ + { + "command": [ + "/manager" + ], + "image": "controller:latest", + "name": "manager", + "securityContext": { + "allowPrivilegeEscalation": false + }, + "livenessProbe": { + "httpGet": { + "path": "/healthz", + "port": 8081 + }, + "initialDelaySeconds": 15, + "periodSeconds": 20 + }, + "readinessProbe": { + "httpGet": { + "path": "/readyz", + "port": 8081 + }, + "initialDelaySeconds": 5, + "periodSeconds": 10 + }, + "imagePullPolicy": "Always", + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "100m", + "memory": "50Mi" + } + }, + "env": [ + { + "name": "OPERATOR_POD_NAME", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.name" + } + } + }, + { + "name": "OPERATOR_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + } + ] + } + ], + "terminationGracePeriodSeconds": 10 + } + } + } +}