From 052940862ae96756a3643aab3ade1a3fba004908 Mon Sep 17 00:00:00 2001 From: Jonas Brunsgaard Date: Wed, 27 Nov 2019 16:43:46 +0100 Subject: [PATCH 1/3] Introduce crds directory for compatibility with Helm v3 (#738) * Introduce crds directory for compatibility with Helm v3 This commit introduce a crd directory for the helm chart which has all custom resource definitions. The files in the crd directory is plain YAML. The crds got the label `app.kubernetes.io/name: postgres-operator` and removes all the templating. Helm v3 ignores the objects from the `templates` directory which have a `crd-install` hook. This commit addes templates/crds.yaml which generates YAMLs for CRDs. The hooks from these CRDs are detected by Helm v2 as well as v3. Helm v2 executes the hook and Helm v3 ignores the hook (YAML files are not applied) The approach is inspired by the prometheus-operator chart helm/charts@89b233eef6dbc1b6fac418bde3a5a6f4e14406d4 --- .../crds/operatorconfigurations.yaml | 41 +++++++ .../postgres-operator/crds/postgresqls.yaml | 53 +++++++++ charts/postgres-operator/templates/crds.yaml | 6 + .../templates/customrresourcedefinition.yaml | 103 ------------------ docs/quickstart.md | 24 ++-- 5 files changed, 112 insertions(+), 115 deletions(-) create mode 100644 charts/postgres-operator/crds/operatorconfigurations.yaml create mode 100644 charts/postgres-operator/crds/postgresqls.yaml create mode 100644 charts/postgres-operator/templates/crds.yaml delete mode 100644 charts/postgres-operator/templates/customrresourcedefinition.yaml diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml new file mode 100644 index 000000000..acf132edd --- /dev/null +++ b/charts/postgres-operator/crds/operatorconfigurations.yaml @@ -0,0 +1,41 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: operatorconfigurations.acid.zalan.do + labels: + app.kubernetes.io/name: postgres-operator + annotations: + "helm.sh/hook": crd-install +spec: + group: acid.zalan.do + names: + kind: OperatorConfiguration + listKind: OperatorConfigurationList + plural: operatorconfigurations + singular: operatorconfiguration + shortNames: + - opconfig + additionalPrinterColumns: + - name: Image + type: string + description: Spilo image to be used for Pods + JSONPath: .configuration.docker_image + - name: Cluster-Label + type: string + description: Label for K8s resources created by operator + JSONPath: .configuration.kubernetes.cluster_name_label + - name: Service-Account + type: string + description: Name of service account to be used + JSONPath: .configuration.kubernetes.pod_service_account_name + - name: Min-Instances + type: integer + description: Minimum number of instances per Postgres cluster + JSONPath: .configuration.min_instances + - name: Age + type: date + JSONPath: .metadata.creationTimestamp + scope: Namespaced + subresources: + status: {} + version: v1 diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml new file mode 100644 index 000000000..c7505ed67 --- /dev/null +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -0,0 +1,53 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: postgresqls.acid.zalan.do + labels: + app.kubernetes.io/name: postgres-operator + annotations: + "helm.sh/hook": crd-install +spec: + group: acid.zalan.do + names: + kind: postgresql + listKind: postgresqlList + plural: postgresqls + singular: postgresql + shortNames: + - pg + additionalPrinterColumns: + - name: Team + type: string + description: Team responsible for Postgres CLuster + JSONPath: .spec.teamId + - name: Version + type: string + description: PostgreSQL version + JSONPath: .spec.postgresql.version + - name: Pods + type: integer + description: Number of Pods per Postgres cluster + JSONPath: .spec.numberOfInstances + - name: Volume + type: string + description: Size of the bound volume + JSONPath: .spec.volume.size + - name: CPU-Request + type: string + description: Requested CPU for Postgres containers + JSONPath: .spec.resources.requests.cpu + - name: Memory-Request + type: string + description: Requested memory for Postgres containers + JSONPath: .spec.resources.requests.memory + - name: Age + type: date + JSONPath: .metadata.creationTimestamp + - name: Status + type: string + description: Current sync status of postgresql resource + JSONPath: .status.PostgresClusterStatus + scope: Namespaced + subresources: + status: {} + version: v1 diff --git a/charts/postgres-operator/templates/crds.yaml b/charts/postgres-operator/templates/crds.yaml new file mode 100644 index 000000000..733830014 --- /dev/null +++ b/charts/postgres-operator/templates/crds.yaml @@ -0,0 +1,6 @@ +{{ if .Values.crd.create }} +{{- range $path, $bytes := .Files.Glob "crds/*.yaml" }} +{{ $.Files.Get $path }} +--- +{{- end }} +{{- end }} diff --git a/charts/postgres-operator/templates/customrresourcedefinition.yaml b/charts/postgres-operator/templates/customrresourcedefinition.yaml deleted file mode 100644 index 88ee1b614..000000000 --- a/charts/postgres-operator/templates/customrresourcedefinition.yaml +++ /dev/null @@ -1,103 +0,0 @@ -{{ if .Values.crd.create }} -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: postgresqls.acid.zalan.do - labels: - app.kubernetes.io/name: {{ template "postgres-operator.name" . }} - helm.sh/chart: {{ template "postgres-operator.chart" . }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - annotations: - "helm.sh/hook": crd-install -spec: - group: acid.zalan.do - names: - kind: postgresql - listKind: postgresqlList - plural: postgresqls - singular: postgresql - shortNames: - - pg - additionalPrinterColumns: - - name: Team - type: string - description: Team responsible for Postgres CLuster - JSONPath: .spec.teamId - - name: Version - type: string - description: PostgreSQL version - JSONPath: .spec.postgresql.version - - name: Pods - type: integer - description: Number of Pods per Postgres cluster - JSONPath: .spec.numberOfInstances - - name: Volume - type: string - description: Size of the bound volume - JSONPath: .spec.volume.size - - name: CPU-Request - type: string - description: Requested CPU for Postgres containers - JSONPath: .spec.resources.requests.cpu - - name: Memory-Request - type: string - description: Requested memory for Postgres containers - JSONPath: .spec.resources.requests.memory - - name: Age - type: date - JSONPath: .metadata.creationTimestamp - - name: Status - type: string - description: Current sync status of postgresql resource - JSONPath: .status.PostgresClusterStatus - scope: Namespaced - subresources: - status: {} - version: v1 ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: operatorconfigurations.acid.zalan.do - labels: - app.kubernetes.io/name: {{ template "postgres-operator.name" . }} - helm.sh/chart: {{ template "postgres-operator.chart" . }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - app.kubernetes.io/instance: {{ .Release.Name }} - annotations: - "helm.sh/hook": crd-install -spec: - group: acid.zalan.do - names: - kind: OperatorConfiguration - listKind: OperatorConfigurationList - plural: operatorconfigurations - singular: operatorconfiguration - shortNames: - - opconfig - additionalPrinterColumns: - - name: Image - type: string - description: Spilo image to be used for Pods - JSONPath: .configuration.docker_image - - name: Cluster-Label - type: string - description: Label for K8s resources created by operator - JSONPath: .configuration.kubernetes.cluster_name_label - - name: Service-Account - type: string - description: Name of service account to be used - JSONPath: .configuration.kubernetes.pod_service_account_name - - name: Min-Instances - type: integer - description: Minimum number of instances per Postgres cluster - JSONPath: .configuration.min_instances - - name: Age - type: date - JSONPath: .metadata.creationTimestamp - scope: Namespaced - subresources: - status: {} - version: v1 -{{ end }} diff --git a/docs/quickstart.md b/docs/quickstart.md index 500d4db30..8fca8b62c 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -73,22 +73,22 @@ manifest. ### Helm chart Alternatively, the operator can be installed by using the provided [Helm](https://helm.sh/) -chart which saves you the manual steps. Therefore, install the helm CLI on your -machine. After initializing helm (and its server component Tiller) in your local -cluster you can install the operator chart. You can define a release name that -is prepended to the operator resource's names. - -Use `--name zalando` to match with the default service account name as older -operator versions do not support custom names for service accounts. To use -CRD-based configuration you need to specify the [values-crd yaml file](../charts/postgres-operator/values-crd.yaml). +chart which saves you the manual steps. Clone this repo and change directory to +the repo root. With Helm v3 installed you should be able to run: ```bash -# 1) initialize helm -helm init -# 2) install postgres-operator chart -helm install --name zalando ./charts/postgres-operator +helm install postgres-operator ./charts/postgres-operator ``` +To use CRD-based configuration you need to specify the [values-crd yaml file](../charts/postgres-operator/values-crd.yaml). + +```bash +helm install postgres-operator ./charts/postgres-operator -f ./charts/postgres-operator/values-crd.yaml +``` + +The chart works with both Helm 2 and Helm 3. Documentation for installing +applications with helm2 can be found in the [helm2 docs](https://v2.helm.sh/docs/). + ### Operator Lifecycle Manager (OLM) The [Operator Lifecycle Manager (OLM)](https://github.com/operator-framework/operator-lifecycle-manager) From a3b34f146f1be5cd0e6e71b8882a5cdd1be62639 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Thu, 28 Nov 2019 12:02:05 +0100 Subject: [PATCH 2/3] Add CRD validation (#599) * add CRD manifests with validation * update documentation * patroni slots is not an array but a nested hash map * make deps call tools * cover validation in docs and export it in crds.go * add toggle to disable creation of CRD validation and document it * use templated service account also for CRD-configured helm deployment --- Makefile | 2 +- .../crds/operatorconfigurations.yaml | 259 +++++ .../postgres-operator/crds/postgresqls.yaml | 310 ++++++ .../templates/operatorconfiguration.yaml | 2 +- charts/postgres-operator/values-crd.yaml | 23 +- charts/postgres-operator/values.yaml | 13 +- delivery.yaml | 2 +- docs/administrator.md | 82 +- docs/developer.md | 4 +- docs/quickstart.md | 27 +- docs/reference/operator_parameters.md | 18 +- manifests/complete-postgres-manifest.yaml | 52 +- manifests/configmap.yaml | 9 +- manifests/operatorconfiguration.crd.yaml | 276 ++++++ ...gresql-operator-default-configuration.yaml | 16 +- manifests/postgresql.crd.yaml | 327 +++++++ pkg/apis/acid.zalan.do/v1/crds.go | 922 +++++++++++++++++- .../v1/operator_configuration_type.go | 1 + .../acid.zalan.do/v1/zz_generated.deepcopy.go | 5 + pkg/controller/controller.go | 6 +- pkg/controller/operator_config.go | 1 + pkg/controller/util.go | 10 +- pkg/util/config/config.go | 9 +- run_operator_locally.sh | 2 +- 24 files changed, 2270 insertions(+), 108 deletions(-) create mode 100644 manifests/operatorconfiguration.crd.yaml create mode 100644 manifests/postgresql.crd.yaml diff --git a/Makefile b/Makefile index 8710f17ee..f42cfe09a 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ vet: @go vet $(PKG) @staticcheck $(PKG) -deps: +deps: tools GO111MODULE=on go mod vendor test: diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml index acf132edd..ff92bc064 100644 --- a/charts/postgres-operator/crds/operatorconfigurations.yaml +++ b/charts/postgres-operator/crds/operatorconfigurations.yaml @@ -39,3 +39,262 @@ spec: subresources: status: {} version: v1 + validation: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - configuration + properties: + kind: + type: string + enum: + - OperatorConfiguration + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + configuration: + type: object + properties: + docker_image: + type: string + enable_crd_validation: + type: boolean + enable_shm_volume: + type: boolean + etcd_host: + type: string + max_instances: + type: integer + minimum: -1 # -1 = disabled + min_instances: + type: integer + minimum: -1 # -1 = disabled + resync_period: + type: string + repair_period: + type: string + set_memory_request_to_limit: + type: boolean + sidecar_docker_images: + type: object + additionalProperties: + type: string + workers: + type: integer + minimum: 1 + users: + type: object + properties: + replication_username: + type: string + super_username: + type: string + kubernetes: + type: object + properties: + cluster_domain: + type: string + cluster_labels: + type: object + additionalProperties: + type: string + cluster_name_label: + type: string + custom_pod_annotations: + type: object + additionalProperties: + type: string + enable_pod_antiaffinity: + type: boolean + enable_pod_disruption_budget: + type: boolean + infrastructure_roles_secret_name: + type: string + inherited_labels: + type: array + items: + type: string + node_readiness_label: + type: object + additionalProperties: + type: string + oauth_token_secret_name: + type: string + pdb_name_format: + type: string + pod_antiaffinity_topology_key: + type: string + pod_environment_configmap: + type: string + pod_management_policy: + type: string + enum: + - "ordered_ready" + - "parallel" + pod_role_label: + type: string + pod_service_account_name: + type: string + pod_terminate_grace_period: + type: string + secret_name_template: + type: string + spilo_fsgroup: + type: integer + spilo_privileged: + type: boolean + toleration: + type: object + additionalProperties: + type: string + watched_namespace: + type: string + postgres_pod_resources: + type: object + properties: + default_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + timeouts: + type: object + properties: + pod_label_wait_timeout: + type: string + pod_deletion_wait_timeout: + type: string + ready_wait_interval: + type: string + ready_wait_timeout: + type: string + resource_check_interval: + type: string + resource_check_timeout: + type: string + load_balancer: + type: object + properties: + db_hosted_zone: + type: string + enable_master_load_balancer: + type: boolean + enable_replica_load_balancer: + type: boolean + custom_service_annotations: + type: object + additionalProperties: + type: string + master_dns_name_format: + type: string + replica_dns_name_format: + type: string + aws_or_gcp: + type: object + properties: + additional_secret_mount: + type: string + additional_secret_mount_path: + type: string + aws_region: + type: string + kube_iam_role: + type: string + log_s3_bucket: + type: string + wal_s3_bucket: + type: string + logical_backup: + type: object + properties: + logical_backup_schedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + logical_backup_docker_image: + type: string + logical_backup_s3_bucket: + type: string + logical_backup_s3_endpoint: + type: string + logical_backup_s3_sse: + type: string + logical_backup_s3_access_key_id: + type: string + logical_backup_s3_secret_access_key: + type: string + debug: + type: object + properties: + debug_logging: + type: boolean + enable_database_access: + type: boolean + teams_api: + type: object + properties: + enable_admin_role_for_users: + type: boolean + enable_team_superuser: + type: boolean + enable_teams_api: + type: boolean + pam_configuration: + type: string + pam_role_name: + type: string + postgres_superuser_teams: + type: array + items: + type: string + protected_role_names: + type: array + items: + type: string + team_admin_role: + type: string + team_api_role_configuration: + type: object + additionalProperties: + type: string + teams_api_url: + type: string + logging_rest_api: + type: object + properties: + api_port: + type: integer + cluster_history_entries: + type: integer + ring_log_lines: + type: integer + scalyr: + type: object + properties: + scalyr_api_key: + type: string + scalyr_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + scalyr_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + scalyr_image: + type: string + scalyr_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + scalyr_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + scalyr_server_url: + type: string diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml index c7505ed67..a8c5f2954 100644 --- a/charts/postgres-operator/crds/postgresqls.yaml +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -51,3 +51,313 @@ spec: subresources: status: {} version: v1 + validation: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - spec + properties: + kind: + type: string + enum: + - postgresql + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + spec: + type: object + required: + - numberOfInstances + - teamId + - postgresql + properties: + allowedSourceRanges: + type: array + nullable: true + items: + type: string + pattern: '^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\/(\d|[1-2]\d|3[0-2])$' + clone: + type: object + required: + - cluster + properties: + cluster: + type: string + s3_endpoint: + type: string + s3_access_key_id: + type: string + s3_secret_access_key: + type: string + s3_force_path_style: + type: string + s3_wal_path: + type: string + timestamp: + type: string + pattern: '^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$' + # The regexp matches the date-time format (RFC 3339 Section 5.6) that specifies a timezone as an offset relative to UTC + # Example: 1996-12-19T16:39:57-08:00 + # Note: this field requires a timezone + uid: + format: uuid + type: string + databases: + type: object + additionalProperties: + type: string + # Note: usernames specified here as database owners must be declared in the users key of the spec key. + dockerImage: + type: string + enableLogicalBackup: + type: boolean + enableMasterLoadBalancer: + type: boolean + enableReplicaLoadBalancer: + type: boolean + enableShmVolume: + type: boolean + init_containers: # deprecated + type: array + nullable: true + items: + type: object + additionalProperties: true + initContainers: + type: array + nullable: true + items: + type: object + additionalProperties: true + logicalBackupSchedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + maintenanceWindows: + type: array + items: + type: string + pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$' + numberOfInstances: + type: integer + minimum: 0 + patroni: + type: object + properties: + initdb: + type: object + additionalProperties: + type: string + pg_hba: + type: array + items: + type: string + slots: + type: object + additionalProperties: + type: object + additionalProperties: + type: string + ttl: + type: integer + loop_wait: + type: integer + retry_timeout: + type: integer + maximum_lag_on_failover: + type: integer + podAnnotations: + type: object + additionalProperties: + type: string + pod_priority_class_name: # deprecated + type: string + podPriorityClassName: + type: string + postgresql: + type: object + required: + - version + properties: + version: + type: string + enum: + - "9.3" + - "9.4" + - "9.5" + - "9.6" + - "10" + - "11" + - "12" + parameters: + type: object + additionalProperties: + type: string + replicaLoadBalancer: # deprecated + type: boolean + resources: + type: object + required: + - requests + - limits + properties: + limits: + type: object + required: + - cpu + - memory + properties: + cpu: + type: string + # Decimal natural followed by m, or decimal natural followed by + # dot followed by up to three decimal digits. + # + # This is because the Kubernetes CPU resource has millis as the + # maximum precision. The actual values are checked in code + # because the regular expression would be huge and horrible and + # not very helpful in validation error messages; this one checks + # only the format of the given number. + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu + pattern: '^(\d+m|\d+\.\d{1,3})$' + # Note: the value specified here must not be zero or be lower + # than the corresponding request. + memory: + type: string + # You can express memory as a plain integer or as a fixed-point + # integer using one of these suffixes: E, P, T, G, M, k. You can + # also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero or be lower + # than the corresponding request. + requests: + type: object + required: + - cpu + - memory + properties: + cpu: + type: string + # Decimal natural followed by m, or decimal natural followed by + # dot followed by up to three decimal digits. + # + # This is because the Kubernetes CPU resource has millis as the + # maximum precision. The actual values are checked in code + # because the regular expression would be huge and horrible and + # not very helpful in validation error messages; this one checks + # only the format of the given number. + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu + pattern: '^(\d+m|\d+\.\d{1,3})$' + # Note: the value specified here must not be zero or be higher + # than the corresponding limit. + memory: + type: string + # You can express memory as a plain integer or as a fixed-point + # integer using one of these suffixes: E, P, T, G, M, k. You can + # also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero or be higher + # than the corresponding limit. + sidecars: + type: array + nullable: true + items: + type: object + additionalProperties: true + spiloFSGroup: + type: integer + standby: + type: object + required: + - s3_wal_path + properties: + s3_wal_path: + type: string + teamId: + type: string + tolerations: + type: array + items: + type: object + required: + - key + - operator + - effect + properties: + key: + type: string + operator: + type: string + enum: + - Equal + - Exists + value: + type: string + effect: + type: string + enum: + - NoExecute + - NoSchedule + - PreferNoSchedule + tolerationSeconds: + type: integer + useLoadBalancer: # deprecated + type: boolean + users: + type: object + additionalProperties: + type: array + nullable: true + description: "Role flags specified here must not contradict each other" + items: + type: string + enum: + - bypassrls + - BYPASSRLS + - nobypassrls + - NOBYPASSRLS + - createdb + - CREATEDB + - nocreatedb + - NOCREATEDB + - createrole + - CREATEROLE + - nocreaterole + - NOCREATEROLE + - inherit + - INHERIT + - noinherit + - NOINHERIT + - login + - LOGIN + - nologin + - NOLOGIN + - replication + - REPLICATION + - noreplication + - NOREPLICATION + - superuser + - SUPERUSER + - nosuperuser + - NOSUPERUSER + volume: + type: object + required: + - size + properties: + size: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero. + storageClass: + type: string + subPath: + type: string diff --git a/charts/postgres-operator/templates/operatorconfiguration.yaml b/charts/postgres-operator/templates/operatorconfiguration.yaml index c6e9f78b7..6a301c1fb 100644 --- a/charts/postgres-operator/templates/operatorconfiguration.yaml +++ b/charts/postgres-operator/templates/operatorconfiguration.yaml @@ -14,7 +14,7 @@ configuration: {{ toYaml .Values.configUsers | indent 4 }} kubernetes: oauth_token_secret_name: {{ template "postgres-operator.fullname" . }} - pod_service_account_name: operator + pod_service_account_name: {{ include "postgres-operator.serviceAccountName" . }} {{ toYaml .Values.configKubernetes | indent 4 }} postgres_pod_resources: {{ toYaml .Values.configPostgresPodResources | indent 4 }} diff --git a/charts/postgres-operator/values-crd.yaml b/charts/postgres-operator/values-crd.yaml index af05ae56c..c6f11e493 100644 --- a/charts/postgres-operator/values-crd.yaml +++ b/charts/postgres-operator/values-crd.yaml @@ -17,6 +17,8 @@ configTarget: "OperatorConfigurationCRD" # general top-level configuration parameters configGeneral: + # choose if deployment creates/updates CRDs with OpenAPIV3Validation + enable_crd_validation: true # start any new database pod without limitations on shm memory enable_shm_volume: true # etcd connection string for Patroni. Empty uses K8s-native DCS. @@ -57,7 +59,10 @@ configKubernetes: # label assigned to Kubernetes objects created by the operator cluster_name_label: cluster-name # additional annotations to add to every database pod - custom_pod_annotations: + # custom_pod_annotations: + # keya: valuea + # keyb: valueb + # toggles pod anti affinity on the Postgres pods enable_pod_antiaffinity: false # toggles PDB to set to MinAvailabe 0 or 1 @@ -74,7 +79,8 @@ configKubernetes: # master_pod_move_timeout: 20m # set of labels that a running and active node should possess to be considered ready - # node_readiness_label: "" + # node_readiness_label: + # status: ready # name of the secret containing the OAuth2 token to pass to the teams API # oauth_token_secret_name: postgresql-operator @@ -186,7 +192,7 @@ configAwsOrGcp: configLogicalBackup: # image for pods of the logical backup job (example runs pg_dumpall) logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup" - # S3 Access Key ID + # S3 Access Key ID logical_backup_s3_access_key_id: "" # S3 bucket to store backup results logical_backup_s3_bucket: "my-bucket-url" @@ -194,7 +200,7 @@ configLogicalBackup: logical_backup_s3_endpoint: "" # S3 Secret Access Key logical_backup_s3_secret_access_key: "" - # S3 server side encription + # S3 server side encription logical_backup_s3_sse: "AES256" # backup schedule in the cron format logical_backup_schedule: "30 00 * * *" @@ -214,7 +220,8 @@ configTeamsApi: # operator will add all team member roles to this group and add a pg_hba line pam_role_name: zalandos # List of teams which members need the superuser role in each Postgres cluster - # postgres_superuser_teams: "postgres_superusers" + # postgres_superuser_teams: + # - postgres_superusers # List of roles that cannot be overwritten by an application, team or infrastructure role protected_role_names: @@ -228,7 +235,7 @@ configTeamsApi: # teams_api_url: http://fake-teams-api.default.svc.cluster.local # Scalyr is a log management tool that Zalando uses as a sidecar -scalyr: +configScalyr: # API key for the Scalyr sidecar # scalyr_api_key: "" @@ -257,9 +264,7 @@ serviceAccount: create: true # The name of the ServiceAccount to use. # If not set and create is true, a name is generated using the fullname template - # When relying solely on the OperatorConfiguration CRD, this value has to be "operator" - # Otherwise, the operator tries to use the "default" service account which is forbidden - name: operator + name: priorityClassName: "" diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index b572b5844..ae9e06fe9 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -17,6 +17,8 @@ configTarget: "ConfigMap" # general configuration parameters configGeneral: + # choose if deployment creates/updates CRDs with OpenAPIV3Validation + enable_crd_validation: "true" # start any new database pod without limitations on shm memory enable_shm_volume: "true" # etcd connection string for Patroni. Empty uses K8s-native DCS. @@ -55,7 +57,8 @@ configKubernetes: # label assigned to Kubernetes objects created by the operator cluster_name_label: version # annotations attached to each database pod - # custom_pod_annotations: keya:valuea + # custom_pod_annotations: keya:valuea,keyb:valueb + # toggles pod anti affinity on the Postgres pods enable_pod_antiaffinity: "false" # toggles PDB to set to MinAvailabe 0 or 1 @@ -136,9 +139,9 @@ configLoadBalancer: # toggles service type load balancer pointing to the replica pod of the cluster enable_replica_load_balancer: "false" # defines the DNS name string template for the master load balancer cluster - master_dns_name_format: '{cluster}.{team}.staging.{hostedzone}' + master_dns_name_format: '{cluster}.{team}.{hostedzone}' # defines the DNS name string template for the replica load balancer cluster - replica_dns_name_format: '{cluster}-repl.{team}.staging.{hostedzone}' + replica_dns_name_format: '{cluster}-repl.{team}.{hostedzone}' # options to aid debugging of the operator itself configDebug: @@ -180,7 +183,7 @@ configAwsOrGcp: configLogicalBackup: # image for pods of the logical backup job (example runs pg_dumpall) logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup" - # S3 Access Key ID + # S3 Access Key ID logical_backup_s3_access_key_id: "" # S3 bucket to store backup results logical_backup_s3_bucket: "my-bucket-url" @@ -188,7 +191,7 @@ configLogicalBackup: logical_backup_s3_endpoint: "" # S3 Secret Access Key logical_backup_s3_secret_access_key: "" - # S3 server side encription + # S3 server side encription logical_backup_s3_sse: "AES256" # backup schedule in the cron format logical_backup_schedule: "30 00 * * *" diff --git a/delivery.yaml b/delivery.yaml index ef249292c..be35d3e27 100644 --- a/delivery.yaml +++ b/delivery.yaml @@ -28,7 +28,7 @@ pipeline: IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator-test fi export IMAGE - make tools deps docker + make deps docker - desc: 'Run unit tests' cmd: | export PATH=$PATH:$HOME/go/bin diff --git a/docs/administrator.md b/docs/administrator.md index ab5368e7d..5cde06ade 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -3,6 +3,30 @@ Learn how to configure and manage the Postgres Operator in your Kubernetes (K8s) environment. +## CRD Validation + +[CustomResourceDefinitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions) +will be registered with schema validation by default when the operator is +deployed. The `OperatorConfiguration` CRD will only get created if the +`POSTGRES_OPERATOR_CONFIGURATION_OBJECT` [environment variable](../manifests/postgres-operator.yaml#L36) +in the deployment yaml is set and not empty. + +When submitting manifests of [`postgresql`](../manifests/postgresql.crd.yaml) or +[`OperatorConfiguration`](../manifests/operatorconfiguration.crd.yaml) custom +resources with kubectl, validation can be bypassed with `--validate=false`. The +operator can also be configured to not register CRDs with validation on `ADD` or +`UPDATE` events. Running instances are not affected when enabling the validation +afterwards unless the manifests is not changed then. Note, that the provided CRD +manifests contain the validation for users to understand what schema is +enforced. + +Once the validation is enabled it can only be disabled manually by editing or +patching the CRD manifest: + +```bash +zk8 patch crd postgresqls.acid.zalan.do -p '{"spec":{"validation": null}}' +``` + ## Namespaces ### Select the namespace to deploy to @@ -32,7 +56,7 @@ By default, the operator watches the namespace it is deployed to. You can change this by setting the `WATCHED_NAMESPACE` var in the `env` section of the [operator deployment](../manifests/postgres-operator.yaml) manifest or by altering the `watched_namespace` field in the operator -[ConfigMap](../manifests/configmap.yaml#L79). +[configuration](../manifests/postgresql-operator-default-configuration.yaml#L49). In the case both are set, the env var takes the precedence. To make the operator listen to all namespaces, explicitly set the field/env var to "`*`". @@ -115,7 +139,7 @@ that are aggregated into the K8s [default roles](https://kubernetes.io/docs/refe To ensure Postgres pods are running on nodes without any other application pods, you can use [taints and tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) -and configure the required toleration in the operator ConfigMap. +and configure the required toleration in the operator configuration. As an example you can set following node taint: @@ -136,6 +160,21 @@ data: ... ``` +For an OperatorConfiguration resource the toleration should be defined like +this: + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: OperatorConfiguration +metadata: + name: postgresql-configuration +configuration: + kubernetes: + toleration: + postgres: "key:postgres,operator:Exists,effect:NoSchedule" + ... +``` + Note that the K8s version 1.13 brings [taint-based eviction](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/#taint-based-evictions) to the beta stage and enables it by default. Postgres pods by default receive tolerations for `unreachable` and `noExecute` taints with the timeout of `5m`. @@ -148,7 +187,7 @@ completely, specify the toleration by leaving out the `tolerationSeconds` value To ensure Postgres pods are running on different topologies, you can use [pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) -and configure the required topology in the operator ConfigMap. +and configure the required topology in the operator configuration. Enable pod anti affinity by adding following line to the operator ConfigMap: @@ -161,21 +200,22 @@ data: enable_pod_antiaffinity: "true" ``` -By default the topology key for the pod anti affinity is set to -`kubernetes.io/hostname`, you can set another topology key e.g. -`failure-domain.beta.kubernetes.io/zone` by adding following line to the -operator ConfigMap, see [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys: +Likewise, when using an OperatorConfiguration resource add: ```yaml -apiVersion: v1 -kind: ConfigMap +apiVersion: "acid.zalan.do/v1" +kind: OperatorConfiguration metadata: - name: postgres-operator -data: - enable_pod_antiaffinity: "true" - pod_antiaffinity_topology_key: "failure-domain.beta.kubernetes.io/zone" + name: postgresql-configuration +configuration: + kubernetes: + enable_pod_antiaffinity: true ``` +By default the topology key for the pod anti affinity is set to +`kubernetes.io/hostname`, you can set another topology key e.g. +`failure-domain.beta.kubernetes.io/zone`. See [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys. + ## Pod Disruption Budget By default the operator uses a PodDisruptionBudget (PDB) to protect the cluster @@ -280,6 +320,20 @@ data: ... ``` +**OperatorConfiguration** + +```yaml +apiVersion: "acid.zalan.do/v1" +kind: OperatorConfiguration +metadata: + name: postgresql-operator-configuration +configuration: + kubernetes: + # referencing config map with custom settings + pod_environment_configmap: postgres-pod-config + ... +``` + **referenced ConfigMap `postgres-pod-config`** ```yaml @@ -312,7 +366,7 @@ services: one for the master pod and one for replica pods. To expose these services to an outer network, one can attach load balancers to them by setting `enableMasterLoadBalancer` and/or `enableReplicaLoadBalancer` to `true` in the cluster manifest. In the case any of these variables are omitted from the -manifest, the operator configmap's settings `enable_master_load_balancer` and +manifest, the operator configuration settings `enable_master_load_balancer` and `enable_replica_load_balancer` apply. Note that the operator settings affect all Postgresql services running in all namespaces watched by the operator. diff --git a/docs/developer.md b/docs/developer.md index 490217362..f8351e28a 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -33,7 +33,7 @@ by setting the `GO111MODULE` environment variable to `on`. The make targets do this for you, so simply run ```bash -make tools deps +make deps ``` This would take a while to complete. You have to redo `make deps` every time @@ -284,6 +284,7 @@ manifest files: Postgres manifest parameters are defined in the [api package](../pkg/apis/acid.zalan.do/v1/postgresql_type.go). The operator behavior has to be implemented at least in [k8sres.go](../pkg/cluster/k8sres.go). +Validation of CRD parameters is controlled in [crd.go](../pkg/apis/acid.zalan.do/v1/crds.go). Please, reflect your changes in tests, for example in: * [config_test.go](../pkg/util/config/config_test.go) * [k8sres_test.go](../pkg/cluster/k8sres_test.go) @@ -294,6 +295,7 @@ Please, reflect your changes in tests, for example in: For the CRD-based configuration, please update the following files: * the default [OperatorConfiguration](../manifests/postgresql-operator-default-configuration.yaml) * the Helm chart's [values-crd file](../charts/postgres-operator/values.yaml) +* the CRD's [validation](../manifests/operatorconfiguration.crd.yaml) Reflect the changes in the ConfigMap configuration as well (note that numeric and boolean parameters have to use double quotes here): diff --git a/docs/quickstart.md b/docs/quickstart.md index 8fca8b62c..2da2cab7c 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -55,8 +55,8 @@ kubectl create -f manifests/postgres-operator.yaml # deployment ``` There is a [Kustomization](https://github.com/kubernetes-sigs/kustomize) -manifest that [combines the mentioned resources](../manifests/kustomization.yaml) - -it can be used with kubectl 1.14 or newer as easy as: +manifest that [combines the mentioned resources](../manifests/kustomization.yaml) +(except for the CRD) - it can be used with kubectl 1.14 or newer as easy as: ```bash kubectl apply -k github.com/zalando/postgres-operator/manifests @@ -86,8 +86,9 @@ To use CRD-based configuration you need to specify the [values-crd yaml file](.. helm install postgres-operator ./charts/postgres-operator -f ./charts/postgres-operator/values-crd.yaml ``` -The chart works with both Helm 2 and Helm 3. Documentation for installing -applications with helm2 can be found in the [helm2 docs](https://v2.helm.sh/docs/). +The chart works with both Helm 2 and Helm 3. The `crd-install` hook from v2 will +be skipped with warning when using v3. Documentation for installing applications +with Helm 2 can be found in the [v2 docs](https://v2.helm.sh/docs/). ### Operator Lifecycle Manager (OLM) @@ -119,15 +120,15 @@ kubectl get pod -l app.kubernetes.io/name=postgres-operator kubectl create -f manifests/minimal-postgres-manifest.yaml ``` -After the cluster manifest is submitted the operator will create Service and -Endpoint resources and a StatefulSet which spins up new Pod(s) given the number -of instances specified in the manifest. All resources are named like the -cluster. The database pods can be identified by their number suffix, starting -from `-0`. They run the [Spilo](https://github.com/zalando/spilo) container -image by Zalando. As for the services and endpoints, there will be one for the -master pod and another one for all the replicas (`-repl` suffix). Check if all -components are coming up. Use the label `application=spilo` to filter and list -the label `spilo-role` to see who is currently the master. +After the cluster manifest is submitted and passed the validation the operator +will create Service and Endpoint resources and a StatefulSet which spins up new +Pod(s) given the number of instances specified in the manifest. All resources +are named like the cluster. The database pods can be identified by their number +suffix, starting from `-0`. They run the [Spilo](https://github.com/zalando/spilo) +container image by Zalando. As for the services and endpoints, there will be one +for the master pod and another one for all the replicas (`-repl` suffix). Check +if all components are coming up. Use the label `application=spilo` to filter and +list the label `spilo-role` to see who is currently the master. ```bash # check the deployed cluster diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index a024aad1f..e16282fd2 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -29,21 +29,20 @@ configuration. To test the CRD-based configuration locally, use the following ```bash + kubectl create -f manifests/operatorconfiguration.crd.yaml # registers the CRD + kubectl create -f manifests/postgresql-operator-default-configuration.yaml + kubectl create -f manifests/operator-service-account-rbac.yaml kubectl create -f manifests/postgres-operator.yaml # set the env var as mentioned above - kubectl create -f manifests/postgresql-operator-default-configuration.yaml + kubectl get operatorconfigurations postgresql-operator-default-configuration -o yaml ``` - Note that the operator first attempts to register the CRD of the - `OperatorConfiguration` and then waits for an instance to be created. In - between these two event the operator pod may be failing since it cannot fetch - the not-yet-existing `OperatorConfiguration` instance. The CRD-based configuration is more powerful than the one based on ConfigMaps and should be used unless there is a compatibility requirement to use an already existing configuration. Even in that case, it should be rather straightforward -to convert the configmap based configuration into the CRD-based one and restart -the operator. The ConfigMaps-based configuration will be deprecated and +to convert the ConfigMap-based configuration into the CRD-based one and restart +the operator. The ConfigMap-based configuration will be deprecated and subsequently removed in future releases. Note that for the CRD-based configuration groups of configuration options below @@ -71,6 +70,11 @@ Variable names are underscore-separated words. Those are top-level keys, containing both leaf keys and groups. +* **enable_crd_validation** + toggles if the operator will create or update CRDs with + [OpenAPI v3 schema validation](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#validation) + The default is `true`. + * **etcd_host** Etcd connection string for Patroni defined as `host:port`. Not required when Patroni native Kubernetes support is used. The default is empty (use diff --git a/manifests/complete-postgres-manifest.yaml b/manifests/complete-postgres-manifest.yaml index 34dd6cf83..f8495caad 100644 --- a/manifests/complete-postgres-manifest.yaml +++ b/manifests/complete-postgres-manifest.yaml @@ -13,7 +13,7 @@ spec: teamId: "ACID" volume: size: 1Gi -# storageClass: my-sc +# storageClass: my-sc numberOfInstances: 2 users: # Application/Robot users zalando: @@ -30,7 +30,7 @@ spec: # Expert section enableShmVolume: true -# spiloFSGroup: 103 +# spiloFSGroup: 103 postgresql: version: "11" parameters: @@ -52,13 +52,13 @@ spec: pg_hba: - hostssl all all 0.0.0.0/0 md5 - host all all 0.0.0.0/0 md5 -# slots: -# - permanent_physical_1: -# type: physical -# - permanent_logical_1: -# type: logical -# database: foo -# plugin: pgoutput +# slots: +# permanent_physical_1: +# type: physical +# permanent_logical_1: +# type: logical +# database: foo +# plugin: pgoutput ttl: 30 loop_wait: &loop_wait 10 retry_timeout: 10 @@ -66,28 +66,28 @@ spec: # restore a Postgres DB with point-in-time-recovery # with a non-empty timestamp, clone from an S3 bucket using the latest backup before the timestamp # with an empty/absent timestamp, clone from an existing alive cluster using pg_basebackup -# clone: -# uid: "efd12e58-5786-11e8-b5a7-06148230260c" -# cluster: "acid-batman" -# timestamp: "2017-12-19T12:40:33+01:00" # timezone required (offset relative to UTC, see RFC 3339 section 5.6) -# s3_wal_path: "s3://custom/path/to/bucket" +# clone: +# uid: "efd12e58-5786-11e8-b5a7-06148230260c" +# cluster: "acid-batman" +# timestamp: "2017-12-19T12:40:33+01:00" # timezone required (offset relative to UTC, see RFC 3339 section 5.6) +# s3_wal_path: "s3://custom/path/to/bucket" # run periodic backups with k8s cron jobs -# enableLogicalBackup: true -# logicalBackupSchedule: "30 00 * * *" +# enableLogicalBackup: true +# logicalBackupSchedule: "30 00 * * *" maintenanceWindows: - 01:00-06:00 #UTC - Sat:00:00-04:00 -# sidecars: -# - name: "telegraf-sidecar" -# image: "telegraf:latest" -# resources: -# limits: -# cpu: 500m -# memory: 500Mi -# requests: -# cpu: 100m -# memory: 100Mi +# sidecars: +# - name: "telegraf-sidecar" +# image: "telegraf:latest" +# resources: +# limits: +# cpu: 500m +# memory: 500Mi +# requests: +# cpu: 100m +# memory: 100Mi # env: # - name: "USEFUL_VAR" # value: "perhaps-true" diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index 40aca9716..59d3abfde 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -12,7 +12,7 @@ data: cluster_labels: application:spilo cluster_name_label: version # custom_service_annotations: "keyx:valuez,keya:valuea" - # custom_pod_annotations: "keya:valuea" + # custom_pod_annotations: "keya:valuea,keyb:valueb" db_hosted_zone: db.example.com debug_logging: "true" # default_cpu_limit: "3" @@ -21,6 +21,7 @@ data: # default_memory_request: 100Mi docker_image: registry.opensource.zalan.do/acid/spilo-11:1.6-p1 # enable_admin_role_for_users: "true" + # enable_crd_validation: "true" # enable_database_access: "true" enable_master_load_balancer: "false" # enable_pod_antiaffinity: "false" @@ -41,7 +42,7 @@ data: # logical_backup_s3_secret_access_key: "" # logical_backup_s3_sse: "AES256" # logical_backup_schedule: "30 00 * * *" - master_dns_name_format: "{cluster}.{team}.staging.{hostedzone}" + master_dns_name_format: "{cluster}.{team}.{hostedzone}" # master_pod_move_timeout: 10m # max_instances: "-1" # min_instances: "-1" @@ -64,11 +65,11 @@ data: ready_wait_interval: 3s ready_wait_timeout: 30s repair_period: 5m - replica_dns_name_format: "{cluster}-repl.{team}.staging.{hostedzone}" + replica_dns_name_format: "{cluster}-repl.{team}.{hostedzone}" replication_username: standby resource_check_interval: 3s resource_check_timeout: 10m - resync_period: 5m + resync_period: 30m ring_log_lines: "100" secret_name_template: "{username}.{cluster}.credentials" # sidecar_docker_images: "" diff --git a/manifests/operatorconfiguration.crd.yaml b/manifests/operatorconfiguration.crd.yaml new file mode 100644 index 000000000..753415a15 --- /dev/null +++ b/manifests/operatorconfiguration.crd.yaml @@ -0,0 +1,276 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: operatorconfigurations.acid.zalan.do +spec: + group: acid.zalan.do + names: + kind: OperatorConfiguration + listKind: OperatorConfigurationList + plural: operatorconfigurations + singular: operatorconfiguration + shortNames: + - opconfig + scope: Namespaced + subresources: + status: {} + version: v1 + validation: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - configuration + properties: + kind: + type: string + enum: + - OperatorConfiguration + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + configuration: + type: object + properties: + docker_image: + type: string + enable_crd_validation: + type: boolean + enable_shm_volume: + type: boolean + etcd_host: + type: string + max_instances: + type: integer + minimum: -1 # -1 = disabled + min_instances: + type: integer + minimum: -1 # -1 = disabled + resync_period: + type: string + repair_period: + type: string + set_memory_request_to_limit: + type: boolean + sidecar_docker_images: + type: object + additionalProperties: + type: string + workers: + type: integer + minimum: 1 + users: + type: object + properties: + replication_username: + type: string + super_username: + type: string + kubernetes: + type: object + properties: + cluster_domain: + type: string + cluster_labels: + type: object + additionalProperties: + type: string + cluster_name_label: + type: string + custom_pod_annotations: + type: object + additionalProperties: + type: string + enable_pod_antiaffinity: + type: boolean + enable_pod_disruption_budget: + type: boolean + infrastructure_roles_secret_name: + type: string + inherited_labels: + type: array + items: + type: string + node_readiness_label: + type: object + additionalProperties: + type: string + oauth_token_secret_name: + type: string + pdb_name_format: + type: string + pod_antiaffinity_topology_key: + type: string + pod_environment_configmap: + type: string + pod_management_policy: + type: string + enum: + - "ordered_ready" + - "parallel" + pod_role_label: + type: string + pod_service_account_name: + type: string + pod_terminate_grace_period: + type: string + secret_name_template: + type: string + spilo_fsgroup: + type: integer + spilo_privileged: + type: boolean + toleration: + type: object + additionalProperties: + type: string + watched_namespace: + type: string + postgres_pod_resources: + type: object + properties: + default_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + timeouts: + type: object + properties: + pod_label_wait_timeout: + type: string + pod_deletion_wait_timeout: + type: string + ready_wait_interval: + type: string + ready_wait_timeout: + type: string + resource_check_interval: + type: string + resource_check_timeout: + type: string + load_balancer: + type: object + properties: + db_hosted_zone: + type: string + enable_master_load_balancer: + type: boolean + enable_replica_load_balancer: + type: boolean + custom_service_annotations: + type: object + additionalProperties: + type: string + master_dns_name_format: + type: string + replica_dns_name_format: + type: string + aws_or_gcp: + type: object + properties: + additional_secret_mount: + type: string + additional_secret_mount_path: + type: string + aws_region: + type: string + kube_iam_role: + type: string + log_s3_bucket: + type: string + wal_s3_bucket: + type: string + logical_backup: + type: object + properties: + logical_backup_schedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + logical_backup_docker_image: + type: string + logical_backup_s3_bucket: + type: string + logical_backup_s3_endpoint: + type: string + logical_backup_s3_sse: + type: string + logical_backup_s3_access_key_id: + type: string + logical_backup_s3_secret_access_key: + type: string + debug: + type: object + properties: + debug_logging: + type: boolean + enable_database_access: + type: boolean + teams_api: + type: object + properties: + enable_admin_role_for_users: + type: boolean + enable_team_superuser: + type: boolean + enable_teams_api: + type: boolean + pam_configuration: + type: string + pam_role_name: + type: string + postgres_superuser_teams: + type: array + items: + type: string + protected_role_names: + type: array + items: + type: string + team_admin_role: + type: string + team_api_role_configuration: + type: object + additionalProperties: + type: string + teams_api_url: + type: string + logging_rest_api: + type: object + properties: + api_port: + type: integer + cluster_history_entries: + type: integer + ring_log_lines: + type: integer + scalyr: + type: object + properties: + scalyr_api_key: + type: string + scalyr_cpu_limit: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + scalyr_cpu_request: + type: string + pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + scalyr_image: + type: string + scalyr_memory_limit: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + scalyr_memory_request: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + scalyr_server_url: + type: string diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index 94f91f1f0..7a867d5df 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -3,6 +3,7 @@ kind: OperatorConfiguration metadata: name: postgresql-operator-default-configuration configuration: + # enable_crd_validation: true etcd_host: "" docker_image: registry.opensource.zalan.do/acid/spilo-11:1.6-p1 # enable_shm_volume: true @@ -27,24 +28,25 @@ configuration: # keyb: valueb enable_pod_antiaffinity: false enable_pod_disruption_budget: true - # infrastructure_roles_secret_name: "" + # infrastructure_roles_secret_name: postgresql-infrastructure-roles # inherited_labels: # - application # - environment - # node_readiness_label: "" + # node_readiness_label: + # status: ready oauth_token_secret_name: postgresql-operator pdb_name_format: "postgres-{cluster}-pdb" pod_antiaffinity_topology_key: "kubernetes.io/hostname" # pod_environment_configmap: "" pod_management_policy: "ordered_ready" pod_role_label: spilo-role - pod_service_account_name: operator + pod_service_account_name: zalando-postgres-operator pod_terminate_grace_period: 5m secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" # spilo_fsgroup: 103 spilo_privileged: false # toleration: {} - # watched_namespace:"" + # watched_namespace: "" postgres_pod_resources: default_cpu_limit: "3" default_cpu_request: 100m @@ -74,7 +76,6 @@ configuration: # log_s3_bucket: "" # wal_s3_bucket: "" logical_backup: - log_s3_bucket: "" logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup" logical_backup_s3_access_key_id: "" logical_backup_s3_bucket: "my-bucket-url" @@ -91,9 +92,10 @@ configuration: enable_teams_api: false # pam_configuration: "" pam_role_name: zalandos - # postgres_superuser_teams: "postgres_superusers" + # postgres_superuser_teams: + # - postgres_superusers protected_role_names: - - admin + - admin team_admin_role: admin team_api_role_configuration: log_statement: all diff --git a/manifests/postgresql.crd.yaml b/manifests/postgresql.crd.yaml new file mode 100644 index 000000000..4a578b324 --- /dev/null +++ b/manifests/postgresql.crd.yaml @@ -0,0 +1,327 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: postgresqls.acid.zalan.do +spec: + group: acid.zalan.do + names: + kind: postgresql + listKind: postgresqlList + plural: postgresqls + singular: postgresql + shortNames: + - pg + scope: Namespaced + subresources: + status: {} + version: v1 + validation: + openAPIV3Schema: + type: object + required: + - kind + - apiVersion + - spec + properties: + kind: + type: string + enum: + - postgresql + apiVersion: + type: string + enum: + - acid.zalan.do/v1 + spec: + type: object + required: + - numberOfInstances + - teamId + - postgresql + properties: + allowedSourceRanges: + type: array + nullable: true + items: + type: string + pattern: '^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\/(\d|[1-2]\d|3[0-2])$' + clone: + type: object + required: + - cluster + properties: + cluster: + type: string + s3_endpoint: + type: string + s3_access_key_id: + type: string + s3_secret_access_key: + type: string + s3_force_path_style: + type: string + s3_wal_path: + type: string + timestamp: + type: string + pattern: '^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$' + # The regexp matches the date-time format (RFC 3339 Section 5.6) that specifies a timezone as an offset relative to UTC + # Example: 1996-12-19T16:39:57-08:00 + # Note: this field requires a timezone + uid: + format: uuid + type: string + databases: + type: object + additionalProperties: + type: string + # Note: usernames specified here as database owners must be declared in the users key of the spec key. + dockerImage: + type: string + enableLogicalBackup: + type: boolean + enableMasterLoadBalancer: + type: boolean + enableReplicaLoadBalancer: + type: boolean + enableShmVolume: + type: boolean + init_containers: # deprecated + type: array + nullable: true + items: + type: object + additionalProperties: true + initContainers: + type: array + nullable: true + items: + type: object + additionalProperties: true + logicalBackupSchedule: + type: string + pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + maintenanceWindows: + type: array + items: + type: string + pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$' + numberOfInstances: + type: integer + minimum: 0 + patroni: + type: object + properties: + initdb: + type: object + additionalProperties: + type: string + pg_hba: + type: array + items: + type: string + slots: + type: object + additionalProperties: + type: object + additionalProperties: + type: string + ttl: + type: integer + loop_wait: + type: integer + retry_timeout: + type: integer + maximum_lag_on_failover: + type: integer + podAnnotations: + type: object + additionalProperties: + type: string + pod_priority_class_name: # deprecated + type: string + podPriorityClassName: + type: string + postgresql: + type: object + required: + - version + properties: + version: + type: string + enum: + - "9.3" + - "9.4" + - "9.5" + - "9.6" + - "10" + - "11" + - "12" + parameters: + type: object + additionalProperties: + type: string + replicaLoadBalancer: # deprecated + type: boolean + resources: + type: object + required: + - requests + - limits + properties: + limits: + type: object + required: + - cpu + - memory + properties: + cpu: + type: string + # Decimal natural followed by m, or decimal natural followed by + # dot followed by up to three decimal digits. + # + # This is because the Kubernetes CPU resource has millis as the + # maximum precision. The actual values are checked in code + # because the regular expression would be huge and horrible and + # not very helpful in validation error messages; this one checks + # only the format of the given number. + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu + pattern: '^(\d+m|\d+\.\d{1,3})$' + # Note: the value specified here must not be zero or be lower + # than the corresponding request. + memory: + type: string + # You can express memory as a plain integer or as a fixed-point + # integer using one of these suffixes: E, P, T, G, M, k. You can + # also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero or be lower + # than the corresponding request. + requests: + type: object + required: + - cpu + - memory + properties: + cpu: + type: string + # Decimal natural followed by m, or decimal natural followed by + # dot followed by up to three decimal digits. + # + # This is because the Kubernetes CPU resource has millis as the + # maximum precision. The actual values are checked in code + # because the regular expression would be huge and horrible and + # not very helpful in validation error messages; this one checks + # only the format of the given number. + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu + pattern: '^(\d+m|\d+\.\d{1,3})$' + # Note: the value specified here must not be zero or be higher + # than the corresponding limit. + memory: + type: string + # You can express memory as a plain integer or as a fixed-point + # integer using one of these suffixes: E, P, T, G, M, k. You can + # also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki + # + # https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero or be higher + # than the corresponding limit. + sidecars: + type: array + nullable: true + items: + type: object + additionalProperties: true + spiloFSGroup: + type: integer + standby: + type: object + required: + - s3_wal_path + properties: + s3_wal_path: + type: string + teamId: + type: string + tolerations: + type: array + items: + type: object + required: + - key + - operator + - effect + properties: + key: + type: string + operator: + type: string + enum: + - Equal + - Exists + value: + type: string + effect: + type: string + enum: + - NoExecute + - NoSchedule + - PreferNoSchedule + tolerationSeconds: + type: integer + useLoadBalancer: # deprecated + type: boolean + users: + type: object + additionalProperties: + type: array + nullable: true + description: "Role flags specified here must not contradict each other" + items: + type: string + enum: + - bypassrls + - BYPASSRLS + - nobypassrls + - NOBYPASSRLS + - createdb + - CREATEDB + - nocreatedb + - NOCREATEDB + - createrole + - CREATEROLE + - nocreaterole + - NOCREATEROLE + - inherit + - INHERIT + - noinherit + - NOINHERIT + - login + - LOGIN + - nologin + - NOLOGIN + - replication + - REPLICATION + - noreplication + - NOREPLICATION + - superuser + - SUPERUSER + - nosuperuser + - NOSUPERUSER + volume: + type: object + required: + - size + properties: + size: + type: string + pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + # Note: the value specified here must not be zero. + storageClass: + type: string + subPath: + type: string diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go index 50833db26..9ee76103f 100644 --- a/pkg/apis/acid.zalan.do/v1/crds.go +++ b/pkg/apis/acid.zalan.do/v1/crds.go @@ -1,7 +1,7 @@ package v1 import ( - "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do" + acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -103,7 +103,902 @@ var OperatorConfigCRDResourceColumns = []apiextv1beta1.CustomResourceColumnDefin }, } -func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomResourceColumnDefinition) *apiextv1beta1.CustomResourceDefinition { +var min0 = 0.0 +var min1 = 1.0 +var minDisable = -1.0 + +// PostgresCRDResourceValidation to check applied manifest parameters +var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + Required: []string{"kind", "apiVersion", "spec"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "kind": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"postgresql"`), + }, + }, + }, + "apiVersion": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"acid.zalan.do/v1"`), + }, + }, + }, + "spec": { + Type: "object", + Required: []string{"numberOfInstances", "teamId", "postgresql"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "allowedSourceRanges": { + Type: "array", + Nullable: true, + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + Pattern: "^(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\/(\\d|[1-2]\\d|3[0-2])$", + }, + }, + }, + "clone": { + Type: "object", + Required: []string{"cluster"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "cluster": { + Type: "string", + }, + "s3_endpoint": { + Type: "string", + }, + "s3_access_key_id": { + Type: "string", + }, + "s3_secret_access_key": { + Type: "string", + }, + "s3_force_path_style": { + Type: "string", + }, + "s3_wal_path": { + Type: "string", + }, + "timestamp": { + Type: "string", + Description: "Date-time format that specifies a timezone as an offset relative to UTC e.g. 1996-12-19T16:39:57-08:00", + Pattern: "^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$", + }, + "uid": { + Type: "string", + Format: "uuid", + }, + }, + }, + "databases": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + Description: "User names specified here as database owners must be declared in the users key of the spec key", + }, + }, + }, + "dockerImage": { + Type: "string", + }, + "enableLogicalBackup": { + Type: "boolean", + }, + "enableMasterLoadBalancer": { + Type: "boolean", + }, + "enableReplicaLoadBalancer": { + Type: "boolean", + }, + "enableShmVolume": { + Type: "boolean", + }, + "init_containers": { + Type: "array", + Description: "Deprecated", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Allows: true, + }, + }, + }, + }, + "initContainers": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Allows: true, + }, + }, + }, + }, + "logicalBackupSchedule": { + Type: "string", + Pattern: "^(\\d+|\\*)(/\\d+)?(\\s+(\\d+|\\*)(/\\d+)?){4}$", + }, + "maintenanceWindows": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + Pattern: "^\\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))\\ *$", + }, + }, + }, + "numberOfInstances": { + Type: "integer", + Minimum: &min0, + }, + "patroni": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "initdb": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "pg_hba": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "slots": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + }, + }, + "ttl": { + Type: "integer", + }, + "loop_wait": { + Type: "integer", + }, + "retry_timeout": { + Type: "integer", + }, + "maximum_lag_on_failover": { + Type: "integer", + }, + }, + }, + "podAnnotations": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "pod_priority_class_name": { + Type: "string", + Description: "Deprecated", + }, + "podPriorityClassName": { + Type: "string", + }, + "postgresql": { + Type: "object", + Required: []string{"version"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "version": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"9.3"`), + }, + { + Raw: []byte(`"9.4"`), + }, + { + Raw: []byte(`"9.5"`), + }, + { + Raw: []byte(`"9.6"`), + }, + { + Raw: []byte(`"10"`), + }, + { + Raw: []byte(`"11"`), + }, + { + Raw: []byte(`"12"`), + }, + }, + }, + "parameters": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + }, + }, + "replicaLoadBalancer": { + Type: "boolean", + Description: "Deprecated", + }, + "resources": { + Type: "object", + Required: []string{"requests", "limits"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "limits": { + Type: "object", + Required: []string{"cpu", "memory"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "cpu": { + Type: "string", + Description: "Decimal natural followed by m, or decimal natural followed by dot followed by up to three decimal digits (precision used by Kubernetes). Must be greater than 0", + Pattern: "^(\\d+m|\\d+\\.\\d{1,3})$", + }, + "memory": { + Type: "string", + Description: "Plain integer or fixed-point integer using one of these suffixes: E, P, T, G, M, k (with or without a tailing i). Must be greater than 0", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + }, + }, + "requests": { + Type: "object", + Required: []string{"cpu", "memory"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "cpu": { + Type: "string", + Description: "Decimal natural followed by m, or decimal natural followed by dot followed by up to three decimal digits (precision used by Kubernetes). Must be greater than 0", + Pattern: "^(\\d+m|\\d+\\.\\d{1,3})$", + }, + "memory": { + Type: "string", + Description: "Plain integer or fixed-point integer using one of these suffixes: E, P, T, G, M, k (with or without a tailing i). Must be greater than 0", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + }, + }, + }, + }, + "sidecars": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Allows: true, + }, + }, + }, + }, + "spiloFSGroup": { + Type: "integer", + }, + "standby": { + Type: "object", + Required: []string{"s3_wal_path"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "s3_wal_path": { + Type: "string", + }, + }, + }, + "teamId": { + Type: "string", + }, + "tolerations": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + Required: []string{"key", "operator", "effect"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "key": { + Type: "string", + }, + "operator": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"Equal"`), + }, + { + Raw: []byte(`"Exists"`), + }, + }, + }, + "value": { + Type: "string", + }, + "effect": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"NoExecute"`), + }, + { + Raw: []byte(`"NoSchedule"`), + }, + { + Raw: []byte(`"PreferNoSchedule"`), + }, + }, + }, + "tolerationSeconds": { + Type: "integer", + }, + }, + }, + }, + }, + "useLoadBalancer": { + Type: "boolean", + Description: "Deprecated", + }, + "users": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "array", + Description: "Role flags specified here must not contradict each other", + Nullable: true, + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"bypassrls"`), + }, + { + Raw: []byte(`"BYPASSRLS"`), + }, + { + Raw: []byte(`"nobypassrls"`), + }, + { + Raw: []byte(`"NOBYPASSRLS"`), + }, + { + Raw: []byte(`"createdb"`), + }, + { + Raw: []byte(`"CREATEDB"`), + }, + { + Raw: []byte(`"nocreatedb"`), + }, + { + Raw: []byte(`"NOCREATEDB"`), + }, + { + Raw: []byte(`"createrole"`), + }, + { + Raw: []byte(`"CREATEROLE"`), + }, + { + Raw: []byte(`"nocreaterole"`), + }, + { + Raw: []byte(`"NOCREATEROLE"`), + }, + { + Raw: []byte(`"inherit"`), + }, + { + Raw: []byte(`"INHERIT"`), + }, + { + Raw: []byte(`"noinherit"`), + }, + { + Raw: []byte(`"NOINHERIT"`), + }, + { + Raw: []byte(`"login"`), + }, + { + Raw: []byte(`"LOGIN"`), + }, + { + Raw: []byte(`"nologin"`), + }, + { + Raw: []byte(`"NOLOGIN"`), + }, + { + Raw: []byte(`"replication"`), + }, + { + Raw: []byte(`"REPLICATION"`), + }, + { + Raw: []byte(`"noreplication"`), + }, + { + Raw: []byte(`"NOREPLICATION"`), + }, + { + Raw: []byte(`"superuser"`), + }, + { + Raw: []byte(`"SUPERUSER"`), + }, + { + Raw: []byte(`"nosuperuser"`), + }, + { + Raw: []byte(`"NOSUPERUSER"`), + }, + }, + }, + }, + }, + }, + }, + "volume": { + Type: "object", + Required: []string{"size"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "size": { + Type: "string", + Description: "Value must not be zero", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + "storageClass": { + Type: "string", + }, + "subPath": { + Type: "string", + }, + }, + }, + }, + }, + }, + }, +} + +// OperatorConfigCRDResourceValidation to check applied manifest parameters +var OperatorConfigCRDResourceValidation = apiextv1beta1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "object", + Required: []string{"kind", "apiVersion", "configuration"}, + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "kind": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"OperatorConfiguration"`), + }, + }, + }, + "apiVersion": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"acid.zalan.do/v1"`), + }, + }, + }, + "configuration": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "docker_image": { + Type: "string", + }, + "enable_crd_validation": { + Type: "boolean", + }, + "enable_shm_volume": { + Type: "boolean", + }, + "etcd_host": { + Type: "string", + }, + "max_instances": { + Type: "integer", + Description: "-1 = disabled", + Minimum: &minDisable, + }, + "min_instances": { + Type: "integer", + Description: "-1 = disabled", + Minimum: &minDisable, + }, + "resync_period": { + Type: "string", + }, + "repair_period": { + Type: "string", + }, + "set_memory_request_to_limit": { + Type: "boolean", + }, + "sidecar_docker_images": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "workers": { + Type: "integer", + Minimum: &min1, + }, + "users": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "replication_username": { + Type: "string", + }, + "super_username": { + Type: "string", + }, + }, + }, + "kubernetes": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "cluster_domain": { + Type: "string", + }, + "cluster_labels": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "cluster_name_label": { + Type: "string", + }, + "custom_pod_annotations": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "enable_pod_antiaffinity": { + Type: "boolean", + }, + "enable_pod_disruption_budget": { + Type: "boolean", + }, + "infrastructure_roles_secret_name": { + Type: "string", + }, + "inherited_labels": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "node_readiness_label": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "oauth_token_secret_name": { + Type: "string", + }, + "pdb_name_format": { + Type: "string", + }, + "pod_antiaffinity_topology_key": { + Type: "string", + }, + "pod_environment_configmap": { + Type: "string", + }, + "pod_management_policy": { + Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"ordered_ready"`), + }, + { + Raw: []byte(`"parallel"`), + }, + }, + }, + "pod_role_label": { + Type: "string", + }, + "pod_service_account_name": { + Type: "string", + }, + "pod_terminate_grace_period": { + Type: "string", + }, + "secret_name_template": { + Type: "string", + }, + "spilo_fsgroup": { + Type: "integer", + }, + "spilo_privileged": { + Type: "boolean", + }, + "toleration": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "watched_namespace": { + Type: "string", + }, + }, + }, + "postgres_pod_resources": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "default_cpu_limit": { + Type: "string", + Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$", + }, + "default_cpu_request": { + Type: "string", + Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$", + }, + "default_memory_limit": { + Type: "string", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + "default_memory_request": { + Type: "string", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + }, + }, + "timeouts": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "pod_label_wait_timeout": { + Type: "string", + }, + "pod_deletion_wait_timeout": { + Type: "string", + }, + "ready_wait_interval": { + Type: "string", + }, + "ready_wait_timeout": { + Type: "string", + }, + "resource_check_interval": { + Type: "string", + }, + "resource_check_timeout": { + Type: "string", + }, + }, + }, + "load_balancer": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "db_hosted_zone": { + Type: "string", + }, + "enable_master_load_balancer": { + Type: "boolean", + }, + "enable_replica_load_balancer": { + Type: "boolean", + }, + "custom_service_annotations": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "master_dns_name_format": { + Type: "string", + }, + "replica_dns_name_format": { + Type: "string", + }, + }, + }, + "aws_or_gcp": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "additional_secret_mount": { + Type: "string", + }, + "additional_secret_mount_path": { + Type: "string", + }, + "aws_region": { + Type: "string", + }, + "kube_iam_role": { + Type: "string", + }, + "log_s3_bucket": { + Type: "string", + }, + "wal_s3_bucket": { + Type: "string", + }, + }, + }, + "logical_backup": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "logical_backup_schedule": { + Type: "string", + Pattern: "^(\\d+|\\*)(/\\d+)?(\\s+(\\d+|\\*)(/\\d+)?){4}$", + }, + "logical_backup_docker_image": { + Type: "string", + }, + "logical_backup_s3_bucket": { + Type: "string", + }, + "logical_backup_s3_endpoint": { + Type: "string", + }, + "logical_backup_s3_sse": { + Type: "string", + }, + "logical_backup_s3_access_key_id": { + Type: "string", + }, + "logical_backup_s3_secret_access_key": { + Type: "string", + }, + }, + }, + "debug": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "debug_logging": { + Type: "boolean", + }, + "enable_database_access": { + Type: "boolean", + }, + }, + }, + "teams_api": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "enable_admin_role_for_users": { + Type: "boolean", + }, + "enable_team_superuser": { + Type: "boolean", + }, + "enable_teams_api": { + Type: "boolean", + }, + "pam_configuration": { + Type: "string", + }, + "pam_role_name": { + Type: "string", + }, + "postgres_superuser_teams": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "protected_role_names": { + Type: "array", + Items: &apiextv1beta1.JSONSchemaPropsOrArray{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "team_admin_role": { + Type: "string", + }, + "team_api_role_configuration": { + Type: "object", + AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{ + Schema: &apiextv1beta1.JSONSchemaProps{ + Type: "string", + }, + }, + }, + "teams_api_url": { + Type: "string", + }, + }, + }, + "logging_rest_api": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "api_port": { + Type: "integer", + }, + "cluster_history_entries": { + Type: "integer", + }, + "ring_log_lines": { + Type: "integer", + }, + }, + }, + "scalyr": { + Type: "object", + Properties: map[string]apiextv1beta1.JSONSchemaProps{ + "scalyr_api_key": { + Type: "string", + }, + "scalyr_cpu_limit": { + Type: "string", + Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$", + }, + "scalyr_cpu_request": { + Type: "string", + Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$", + }, + "scalyr_image": { + Type: "string", + }, + "scalyr_memory_limit": { + Type: "string", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + "scalyr_memory_request": { + Type: "string", + Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", + }, + "scalyr_server_url": { + Type: "string", + }, + }, + }, + }, + }, + }, + }, +} + +func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomResourceColumnDefinition, validation apiextv1beta1.CustomResourceValidation) *apiextv1beta1.CustomResourceDefinition { return &apiextv1beta1.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -121,24 +1016,39 @@ func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomRe Status: &apiextv1beta1.CustomResourceSubresourceStatus{}, }, AdditionalPrinterColumns: columns, + Validation: &validation, }, } } // PostgresCRD returns CustomResourceDefinition built from PostgresCRDResource -func PostgresCRD() *apiextv1beta1.CustomResourceDefinition { +func PostgresCRD(enableValidation *bool) *apiextv1beta1.CustomResourceDefinition { + postgresCRDvalidation := apiextv1beta1.CustomResourceValidation{} + + if enableValidation != nil && *enableValidation { + postgresCRDvalidation = PostgresCRDResourceValidation + } + return buildCRD(PostgresCRDResouceName, PostgresCRDResourceKind, PostgresCRDResourcePlural, PostgresCRDResourceShort, - PostgresCRDResourceColumns) + PostgresCRDResourceColumns, + postgresCRDvalidation) } // ConfigurationCRD returns CustomResourceDefinition built from OperatorConfigCRDResource -func ConfigurationCRD() *apiextv1beta1.CustomResourceDefinition { +func ConfigurationCRD(enableValidation *bool) *apiextv1beta1.CustomResourceDefinition { + opconfigCRDvalidation := apiextv1beta1.CustomResourceValidation{} + + if enableValidation != nil && *enableValidation { + opconfigCRDvalidation = OperatorConfigCRDResourceValidation + } + return buildCRD(OperatorConfigCRDResourceName, OperatorConfigCRDResouceKind, OperatorConfigCRDResourcePlural, OperatorConfigCRDResourceShort, - OperatorConfigCRDResourceColumns) + OperatorConfigCRDResourceColumns, + opconfigCRDvalidation) } diff --git a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go index d00d40532..d97852b2f 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -150,6 +150,7 @@ type ScalyrConfiguration struct { // OperatorConfigurationData defines the operation config type OperatorConfigurationData struct { + EnableCRDValidation *bool `json:"enable_crd_validation,omitempty"` EtcdHost string `json:"etcd_host,omitempty"` DockerImage string `json:"docker_image,omitempty"` Workers uint32 `json:"workers,omitempty"` diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index 793f236a5..433d37f87 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -216,6 +216,11 @@ func (in *OperatorConfiguration) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData) { *out = *in + if in.EnableCRDValidation != nil { + in, out := &in.EnableCRDValidation, &out.EnableCRDValidation + *out = new(bool) + **out = **in + } if in.ShmVolume != nil { in, out := &in.ShmVolume, &out.ShmVolume *out = new(bool) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 9162ce27d..9db03ceb1 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/sirupsen/logrus" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -240,7 +240,7 @@ func (c *Controller) initController() { c.initClients() if configObjectName := os.Getenv("POSTGRES_OPERATOR_CONFIGURATION_OBJECT"); configObjectName != "" { - if err := c.createConfigurationCRD(); err != nil { + if err := c.createConfigurationCRD(c.opConfig.EnableCRDValidation); err != nil { c.logger.Fatalf("could not register Operator Configuration CustomResourceDefinition: %v", err) } if cfg, err := c.readOperatorConfigurationFromCRD(spec.GetOperatorNamespace(), configObjectName); err != nil { @@ -256,7 +256,7 @@ func (c *Controller) initController() { c.modifyConfigFromEnvironment() - if err := c.createPostgresCRD(); err != nil { + if err := c.createPostgresCRD(c.opConfig.EnableCRDValidation); err != nil { c.logger.Fatalf("could not register Postgres CustomResourceDefinition: %v", err) } diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index 3ea513879..9bed7ed13 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -25,6 +25,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result := &config.Config{} // general config + result.EnableCRDValidation = fromCRD.EnableCRDValidation result.EtcdHost = fromCRD.EtcdHost result.DockerImage = fromCRD.DockerImage result.Workers = fromCRD.Workers diff --git a/pkg/controller/util.go b/pkg/controller/util.go index 0adb85dbd..9b7dca063 100644 --- a/pkg/controller/util.go +++ b/pkg/controller/util.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -91,12 +91,12 @@ func (c *Controller) createOperatorCRD(crd *apiextv1beta1.CustomResourceDefiniti }) } -func (c *Controller) createPostgresCRD() error { - return c.createOperatorCRD(acidv1.PostgresCRD()) +func (c *Controller) createPostgresCRD(enableValidation *bool) error { + return c.createOperatorCRD(acidv1.PostgresCRD(enableValidation)) } -func (c *Controller) createConfigurationCRD() error { - return c.createOperatorCRD(acidv1.ConfigurationCRD()) +func (c *Controller) createConfigurationCRD(enableValidation *bool) error { + return c.createOperatorCRD(acidv1.ConfigurationCRD(enableValidation)) } func readDecodedRole(s string) (*spec.PgUser, error) { diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index e8de85e20..52a0c4020 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -12,10 +12,11 @@ import ( // CRD describes CustomResourceDefinition specific configuration parameters type CRD struct { - ReadyWaitInterval time.Duration `name:"ready_wait_interval" default:"4s"` - ReadyWaitTimeout time.Duration `name:"ready_wait_timeout" default:"30s"` - ResyncPeriod time.Duration `name:"resync_period" default:"30m"` - RepairPeriod time.Duration `name:"repair_period" default:"5m"` + ReadyWaitInterval time.Duration `name:"ready_wait_interval" default:"4s"` + ReadyWaitTimeout time.Duration `name:"ready_wait_timeout" default:"30s"` + ResyncPeriod time.Duration `name:"resync_period" default:"30m"` + RepairPeriod time.Duration `name:"repair_period" default:"5m"` + EnableCRDValidation *bool `name:"enable_crd_validation" default:"true"` } // Resources describes kubernetes resource specific configuration parameters diff --git a/run_operator_locally.sh b/run_operator_locally.sh index f5044dc14..9e3e082da 100755 --- a/run_operator_locally.sh +++ b/run_operator_locally.sh @@ -98,7 +98,7 @@ function build_operator_binary(){ # redirecting stderr greatly reduces non-informative output during normal builds echo "Build operator binary (stderr redirected to /dev/null)..." - make clean tools deps local test > /dev/null 2>&1 + make clean deps local test > /dev/null 2>&1 } From 551564011139d5a6cb9f635d091b2b54f56f125d Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Thu, 28 Nov 2019 17:39:25 +0100 Subject: [PATCH 3/3] install kind as GO module (#742) * install kind as GO modules * no need to set KIND_PATH --- .gitignore | 3 + e2e/Makefile | 6 +- e2e/run.sh | 14 ++-- go.mod | 20 ++++-- go.sum | 194 ++++++++++++++++++++++++++++++++++++++------------- 5 files changed, 171 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 34d526578..991fe754f 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,9 @@ coverage.xml .hypothesis/ .pytest_cache/ +# e2e tests +e2e/manifests + # Translations *.mo *.pot diff --git a/e2e/Makefile b/e2e/Makefile index ab19539f8..77059f3eb 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -23,7 +23,6 @@ ifndef GOPATH GOPATH := $(HOME)/go endif -KIND_PATH := $(GOPATH)/bin PATH := $(GOPATH)/bin:$(PATH) default: tools @@ -43,10 +42,7 @@ push: docker tools: docker # install pinned version of 'kind' - # leave the name as is to avoid overwriting official binary named `kind` - wget https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-linux-amd64 - chmod +x kind-linux-amd64 - mv kind-linux-amd64 $(KIND_PATH) + GO111MODULE=on go get sigs.k8s.io/kind@v0.5.1 test: ./run.sh diff --git a/e2e/run.sh b/e2e/run.sh index 237960b89..c7825bfd3 100755 --- a/e2e/run.sh +++ b/e2e/run.sh @@ -30,15 +30,15 @@ function pull_images(){ function start_kind(){ # avoid interference with previous test runs - if [[ $(kind-linux-amd64 get clusters | grep "^${cluster_name}*") != "" ]] + if [[ $(kind get clusters | grep "^${cluster_name}*") != "" ]] then - kind-linux-amd64 delete cluster --name ${cluster_name} + kind delete cluster --name ${cluster_name} fi - kind-linux-amd64 create cluster --name ${cluster_name} --config kind-cluster-postgres-operator-e2e-tests.yaml - kind-linux-amd64 load docker-image "${operator_image}" --name ${cluster_name} - kind-linux-amd64 load docker-image "${e2e_test_image}" --name ${cluster_name} - KUBECONFIG="$(kind-linux-amd64 get kubeconfig-path --name=${cluster_name})" + kind create cluster --name ${cluster_name} --config kind-cluster-postgres-operator-e2e-tests.yaml + kind load docker-image "${operator_image}" --name ${cluster_name} + kind load docker-image "${e2e_test_image}" --name ${cluster_name} + KUBECONFIG="$(kind get kubeconfig-path --name=${cluster_name})" export KUBECONFIG } @@ -58,7 +58,7 @@ function run_tests(){ function clean_up(){ unset KUBECONFIG - kind-linux-amd64 delete cluster --name ${cluster_name} + kind delete cluster --name ${cluster_name} rm -rf ${kubeconfig_path} } diff --git a/go.mod b/go.mod index 8efd4939d..9012721d1 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,22 @@ go 1.12 require ( github.com/aws/aws-sdk-go v1.25.1 + github.com/emicklei/go-restful v2.9.6+incompatible // indirect + github.com/evanphx/json-patch v4.5.0+incompatible // indirect + github.com/googleapis/gnostic v0.3.0 // indirect github.com/imdario/mergo v0.3.7 // indirect github.com/lib/pq v1.2.0 github.com/motomux/pretty v0.0.0-20161209205251-b2aad2c9a95d github.com/sirupsen/logrus v1.4.2 - gopkg.in/yaml.v2 v2.2.2 - k8s.io/api v0.0.0-20190927115716-5d581ce610b0 - k8s.io/apiextensions-apiserver v0.0.0-20190927042040-728319705b32 - k8s.io/apimachinery v0.0.0-20190927035529-0104e33c351d - k8s.io/client-go v0.0.0-20190926235751-95884bf844a9 - k8s.io/code-generator v0.0.0-20190927075303-016f2b3d74d0 + golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c // indirect + golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect + golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect + golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/yaml.v2 v2.2.5 + k8s.io/api v0.0.0-20191121015604-11707872ac1c + k8s.io/apiextensions-apiserver v0.0.0-20191121021419-88daf26ec3b8 + k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a + k8s.io/client-go v11.0.0+incompatible + k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e ) diff --git a/go.sum b/go.sum index 8995710ba..e7a0a15e3 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -19,8 +20,10 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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= @@ -28,18 +31,21 @@ github.com/aws/aws-sdk-go v1.25.1 h1:d7zDXFT2Tgq/yw7Wku49+lKisE8Xc85erb+8PlE/Shk github.com/aws/aws-sdk-go v1.25.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -47,16 +53,27 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 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/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +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/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w= +github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -66,6 +83,7 @@ github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70t 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.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= 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= @@ -74,37 +92,51 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/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 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.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.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/spec v0.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 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= 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 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 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.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/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 h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -112,7 +144,10 @@ github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -122,20 +157,25 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0= +github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +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/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= @@ -148,13 +188,17 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= @@ -168,6 +212,12 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= 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 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -181,41 +231,56 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/motomux/pretty v0.0.0-20161209205251-b2aad2c9a95d h1:LznySqW8MqVeFh+pW6rOkFdld9QQ7jRydBKKM6jyPVI= github.com/motomux/pretty v0.0.0-20161209205251-b2aad2c9a95d/go.mod h1:u3hJ0kqCQu/cPpsu3RbCOPZ0d7V3IjPjv1adNRleM9I= 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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 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= @@ -223,14 +288,24 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -238,8 +313,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= 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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4= +golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -253,14 +333,19 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r 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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= +golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -274,6 +359,7 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -284,17 +370,25 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU= +golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-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= @@ -302,11 +396,15 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f h1:3MlESg/jvTr87F4ttA/q4B+uhe/q6qleC9/DP+IwQmY= +golang.org/x/tools v0.0.0-20191127201027-ecd32218bd7f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -318,65 +416,65 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48= -k8s.io/api v0.0.0-20190925180651-d58b53da08f5/go.mod h1:blPYY5r6fKug8SVOnjDtFAlzZzInCRL9NNls66SFhFI= -k8s.io/api v0.0.0-20190927115716-5d581ce610b0 h1:fwx2jAKNlXBQ8uiB3RNN5hVU/nEJTEBg/CfxoXEYri4= -k8s.io/api v0.0.0-20190927115716-5d581ce610b0/go.mod h1:l2ZHS8QbgqodGx7yrYsOSwIxOR76BpGiW1OywXo9PFI= -k8s.io/apiextensions-apiserver v0.0.0-20190927042040-728319705b32 h1:ss1T2mi6o+ji42DAoFxrophF9dysSKUXyq6fTmCMvFI= -k8s.io/apiextensions-apiserver v0.0.0-20190927042040-728319705b32/go.mod h1:SMmFyjBO4fGs1v/nrTzNbhyg4PEGUH+h3ilWsi90RPk= -k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4= -k8s.io/apimachinery v0.0.0-20190923155427-ec87dd743e08/go.mod h1:grJJH0hgilA2pYoUiJcPu2EDUal95NTq1vpxxvMLSu8= -k8s.io/apimachinery v0.0.0-20190925235427-62598f38f24e/go.mod h1:grJJH0hgilA2pYoUiJcPu2EDUal95NTq1vpxxvMLSu8= -k8s.io/apimachinery v0.0.0-20190927035529-0104e33c351d h1:oYLB5Nk2IOm17BHdatnaWAgzNGzq/5dlWy7Bzo5Htdc= -k8s.io/apimachinery v0.0.0-20190927035529-0104e33c351d/go.mod h1:grJJH0hgilA2pYoUiJcPu2EDUal95NTq1vpxxvMLSu8= -k8s.io/apiserver v0.0.0-20190927000204-dd401ce564d5/go.mod h1:oXS8tPljvXCBPjzDnAM7xnx26pzwFT+oIqIUCmG8Pj8= -k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90 h1:mLmhKUm1X+pXu0zXMEzNsOF5E2kKFGe5o6BZBIIqA6A= -k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk= -k8s.io/client-go v0.0.0-20190925235746-07054768d98d/go.mod h1:KumMj5rt+3qCPy5LJipGocsmMx6RW8vdDAs8QNK6jvU= -k8s.io/client-go v0.0.0-20190926235751-95884bf844a9 h1:YpRGAa4i68p7SGIuJAaZgE7oumAMxzsTux2gTur2eMM= -k8s.io/client-go v0.0.0-20190926235751-95884bf844a9/go.mod h1:KumMj5rt+3qCPy5LJipGocsmMx6RW8vdDAs8QNK6jvU= +k8s.io/api v0.0.0-20191121015604-11707872ac1c h1:Z87my3sF4WhG0OMxzARkWY/IKBtOr+MhXZAb4ts6qFc= +k8s.io/api v0.0.0-20191121015604-11707872ac1c/go.mod h1:R/s4gKT0V/cWEnbQa9taNRJNbWUK57/Dx6cPj6MD3A0= +k8s.io/apiextensions-apiserver v0.0.0-20191121021419-88daf26ec3b8 h1:SrFLwOURsuwzuCi0zJdaBbPF31AcV9JUwpwIVosnnE4= +k8s.io/apiextensions-apiserver v0.0.0-20191121021419-88daf26ec3b8/go.mod h1:NMIy5Wa/or8CsLhYRleOp9CWAHVdcWpzT6Ufx1SNVjA= +k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a h1:9V03T5lHv/iF4fSgvMCd+iB86AgEgmzLpheMqIJy7hs= +k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/apiserver v0.0.0-20191121020624-6eed2f5a3289/go.mod h1:7P+0qMKoaggchirHLUSCVD22ohdkjN19+qQOKcAdfbI= +k8s.io/client-go v0.0.0-20191121015835-571c0ef67034 h1:+/ppGIi1rJThJAz/xJSSOuD82gb6E5jRv2305MSznxQ= +k8s.io/client-go v0.0.0-20191121015835-571c0ef67034/go.mod h1:Adhj+OyDRsEXTnL9BfL7xbLWGWMCqGLWpMqGHkZI4J8= k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/code-generator v0.0.0-20190925195306-32dfb485ddce/go.mod h1:4MfOrxyyZxxCuenwsdaJRtoSnOP5T13jE2LRYPZ6KeY= -k8s.io/code-generator v0.0.0-20190927075303-016f2b3d74d0 h1:rhwEVFHoBm42V0b7yN9SUdbWzfCVndLzRV8YGIi0uWY= -k8s.io/code-generator v0.0.0-20190927075303-016f2b3d74d0/go.mod h1:4MfOrxyyZxxCuenwsdaJRtoSnOP5T13jE2LRYPZ6KeY= -k8s.io/component-base v0.0.0-20190926082537-804254d56004/go.mod h1:+sedDd0Yj/9lFSZjan8FdX4Jednr2we+Q0ZDeicbKSc= +k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e h1:HB9Zu5ZUvJfNpLiTPhz+CebVKV8C39qTBMQkAgAZLNw= +k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= +k8s.io/component-base v0.0.0-20191121020327-771114ba3383/go.mod h1:tv9ITs6VEFWkF+kHwY4GiFvDr9vUGKJ4X/8+Z+oqVLk= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6 h1:rfepARh/ECp66dk9TTmT//1PBkHffjnxhdOrgH4m+eA= -k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= +sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=