From 15917792ae37b3b6a1e47aa3bd1891d35b375f08 Mon Sep 17 00:00:00 2001 From: Michael Burman Date: Mon, 5 Jul 2021 17:04:50 +0300 Subject: [PATCH] Update operator-sdk to 1.x from the old <0.19 structure (new kubebuilder struct) (#120) Update operator-sdk to 1.x from the old <0.19 structure (new kubebuilder struct). With the history of changes as it proceeded: * Update to operator sdk 0.18.2, newer mage and rebuilding the client interface Fix ResourceVersion conflict in CheckRackPodTemplate, remove dependency to deprecated k8sutil from operator-sdk and copy the relevant parts here Upgrade generateSdk to use 0.18.2, changes CRD to apiextensions v1 instead of v1beta1 Fix CRD patching with new apiextensions version The tests do not understand go mod tidy, so adding untied go.sum for tests * Initial work for operator 1.x * Build changes * Fix RBAC generation, disable webhooks * Fix watchNamespace deployment * Fix some group names, add kustomize template for spec.config property * Split the patch to a separate file * Fix event filtering for CassandraDatacenter * Remove Helm charts * Change Makefile to use /bin/bash instead of /bin/sh for ubuntu-latest * integ-test target runs kustomize install first * Refactor dynamicSecretWatches to work again, migrate oldReconciler to controllers, remove more mage stuff (operator, k3d, k8s, kind, docker, integ-tests), update config-builder to 1.0.4 * Refactor validating webhook handling, remove old cert checks and replace with cert-manager in integration tests * Fix RBAC rights for PersistentVolume and Nodes, add larger timeouts for scale down events * Modify settings to use Role instead of ClusterRole by default, create kustomize template for cluster_wide_install scenario * Add workaround for cluster_wide_install kustomize issue with deployment order and hopefully fix the scale down tests * Move operator/pkg and internal to pkg/ * Update to kustomize 4.1.3 instead of 3.x * Migrate crd.patch to kustomize * Replace some Watches with Owns * Set all as default integ-test target --- .github/workflows/kindIntegTest.yml | 22 +- .github/workflows/operatorBuildAndDeploy.yml | 35 +- .gitignore | 5 + Dockerfile | 29 + Makefile | 229 + PROJECT | 23 + .../v1beta1/cassandradatacenter_types.go | 19 +- .../v1beta1/cassandradatacenter_webhook.go | 40 +- api/v1beta1/groupversion_info.go | 36 + api/v1beta1/webhook_suite_test.go | 133 + .../cassandra => api}/v1beta1/webhook_test.go | 0 .../v1beta1/zz_generated.deepcopy.go | 46 +- charts/cass-operator-chart/Chart.yaml | 10 - .../templates/clusterrole.yaml | 14 - .../templates/clusterrolebinding.yaml | 12 - .../templates/customresourcedefinition.yaml | 6579 --------------- .../templates/deployment.yaml | 105 - .../templates/registry-secret.yaml | 9 - .../cass-operator-chart/templates/role.yaml | 171 - .../templates/serviceaccount.yaml | 4 - .../validatingwebhookconfiguration.yaml | 22 - .../templates/webhook-cr.yaml | 16 - .../templates/webhook-crb.yaml | 12 - .../templates/webhook-secret.yaml | 7 - .../templates/webhook-service.yaml | 12 - charts/cass-operator-chart/values.yaml | 14 - config/certmanager/certificate.yaml | 25 + config/certmanager/kustomization.yaml | 5 + config/certmanager/kustomizeconfig.yaml | 16 + ...dra.datastax.com_cassandradatacenters.yaml | 7083 +++++++++++++++++ config/crd/kustomization.yaml | 43 + config/crd/kustomizeconfig.yaml | 19 + .../cainjection_in_cassandradatacenters.yaml | 7 + config/crd/patches/config_removal.yaml | 15 + config/crd/patches/remove_xkeys.yaml | 12 + .../webhook_in_cassandradatacenters.yaml | 14 + config/default/kustomization.yaml | 74 + config/default/manager_auth_proxy_patch.yaml | 26 + config/default/manager_config_patch.yaml | 20 + config/default/manager_webhook_patch.yaml | 23 + config/default/webhookcainjection_patch.yaml | 15 + config/manager/controller_manager_config.yaml | 11 + config/manager/kustomization.yaml | 16 + config/manager/manager.yaml | 66 + .../cass-operator.clusterserviceversion.yaml | 47 + config/manifests/kustomization.yaml | 27 + config/prometheus/kustomization.yaml | 2 + config/prometheus/monitor.yaml | 20 + .../rbac/auth_proxy_client_clusterrole.yaml | 7 + config/rbac/auth_proxy_role.yaml | 13 + .../rbac/auth_proxy_role_binding.yaml | 16 +- config/rbac/auth_proxy_service.yaml | 14 + .../rbac/cassandradatacenter_editor_role.yaml | 24 + .../rbac/cassandradatacenter_viewer_role.yaml | 20 + config/rbac/kustomization.yaml | 18 + config/rbac/leader_election_role.yaml | 27 + .../rbac/leader_election_role_binding.yaml | 15 +- config/rbac/role.yaml | 110 + .../rbac/role_binding.yaml | 33 +- .../rbac}/service_account.yaml | 3 +- ...astax.com_v1beta1_cassandradatacenter.yaml | 7 + config/samples/kustomization.yaml | 4 + config/scorecard/bases/config.yaml | 7 + config/scorecard/kustomization.yaml | 16 + config/scorecard/patches/basic.config.yaml | 10 + config/scorecard/patches/olm.config.yaml | 50 + config/webhook/kustomization.yaml | 6 + config/webhook/kustomizeconfig.yaml | 25 + config/webhook/manifests.yaml | 29 + config/webhook/service.yaml | 12 + controllers/cassandradatacenter_controller.go | 247 + controllers/suite_test.go | 80 + go.mod | 82 +- go.sum | 1797 +---- hack/boilerplate.go.txt | 15 + mage/docker/lib.go | 240 - mage/ginkgo/lib.go | 69 +- mage/helm/lib.go | 65 - mage/integ-tests/lib.go | 194 - mage/integ-tests/lib_test.go | 49 - mage/k3d/lib.go | 146 - mage/k8s/lib.go | 299 - mage/kind/lib.go | 123 - mage/operator/crd.patch | 37 - mage/operator/deploy.go | 137 - mage/operator/lib.go | 597 -- mage/operator/lib_test.go | 161 - mage/sh/lib.go | 6 +- magefile.go | 6 - main.go | 146 + operator/cmd/manager/main.go | 313 - operator/deploy/README.md | 57 - operator/deploy/cluster_role.yaml | 16 - ...datastax.com_cassandradatacenters_crd.yaml | 6591 --------------- operator/deploy/namespace.yaml | 4 - operator/deploy/operator.yaml | 70 - operator/deploy/role.yaml | 73 - operator/deploy/webhook_configuration.yaml | 22 - operator/deploy/webhook_secret.yaml | 7 - operator/deploy/webhook_service.yaml | 12 - operator/pkg/admissionwebhook/webhook.go | 187 - .../pkg/apis/addtoscheme_cassandra_v1beta1.go | 13 - operator/pkg/apis/apis.go | 16 - operator/pkg/apis/cassandra/group.go | 9 - .../v1beta1/cassandradatacenter_types_test.go | 254 - operator/pkg/apis/cassandra/v1beta1/doc.go | 7 - .../pkg/apis/cassandra/v1beta1/register.go | 34 - .../cassandra/v1beta1/zz_generated.openapi.go | 312 - .../pkg/controller/add_cassandradatacenter.go | 13 - .../cassandradatacenter_controller.go | 309 - operator/pkg/controller/controller.go | 21 - operator/pkg/reconciliation/handler_test.go | 394 - {operator/pkg => pkg}/dynamicwatch/watch.go | 56 +- {operator/pkg => pkg}/events/events.go | 0 {operator/pkg => pkg}/events/events_test.go | 30 +- .../clientset/versioned/clientset.go | 4 +- .../generated/clientset/versioned/doc.go | 0 .../versioned/fake/clientset_generated.go | 6 +- .../generated/clientset/versioned/fake/doc.go | 0 .../clientset/versioned/fake/register.go | 4 +- .../clientset/versioned/scheme/doc.go | 0 .../clientset/versioned/scheme/register.go | 4 +- .../cassandra/v1beta1/cassandra_client.go | 6 +- .../cassandra/v1beta1/cassandradatacenter.go | 76 +- .../versioned/typed/cassandra/v1beta1/doc.go | 0 .../typed/cassandra/v1beta1/fake/doc.go | 0 .../v1beta1/fake/fake_cassandra_client.go | 2 +- .../v1beta1/fake/fake_cassandradatacenter.go | 24 +- .../cassandra/v1beta1/generated_expansion.go | 0 {operator/pkg => pkg}/httphelper/client.go | 0 .../pkg => pkg}/httphelper/client_test.go | 2 +- .../pkg => pkg}/httphelper/httpclient.go | 2 +- {operator/pkg => pkg}/httphelper/security.go | 2 +- .../pkg => pkg}/httphelper/security_test.go | 0 .../pkg => pkg}/httphelper/testdata/ca.crt | 0 .../pkg => pkg}/httphelper/testdata/ca.key | 0 .../httphelper/testdata/client.crt | 0 .../httphelper/testdata/client.key | 0 .../httphelper/testdata/evil_ca.crt | 0 .../httphelper/testdata/evil_ca.key | 0 .../httphelper/testdata/gencerts.sh | 0 .../httphelper/testdata/server.crt | 0 .../httphelper/testdata/server.encrypted.key | 0 .../httphelper/testdata/server.key | 0 .../httphelper/testdata/server.rsa.key | 0 {operator/pkg => pkg}/images/images.go | 2 +- {operator/pkg => pkg}/images/images_test.go | 0 .../internal/result/result_helper.go | 18 +- .../internal/result/result_helper_test.go | 0 {operator/pkg => pkg}/mocks/Client.go | 43 +- {operator/pkg => pkg}/mocks/HttpClient.go | 0 {operator/pkg => pkg}/oplabels/labels.go | 6 +- {operator/pkg => pkg}/psp/emm.go | 6 +- {operator/pkg => pkg}/psp/emm_test.go | 4 +- .../pkg => pkg}/psp/labels_annotations.go | 12 +- {operator/pkg => pkg}/psp/networkpolicies.go | 22 +- {operator/pkg => pkg}/psp/psp_status.go | 71 +- .../pkg => pkg}/reconciliation/check_nodes.go | 4 +- .../construct_podtemplatespec.go | 15 +- .../construct_podtemplatespec_test.go | 87 +- .../reconciliation/construct_service.go | 6 +- .../reconciliation/construct_service_test.go | 7 +- .../reconciliation/construct_statefulset.go | 12 +- .../construct_statefulset_test.go | 4 +- .../pkg => pkg}/reconciliation/constructor.go | 6 +- .../pkg => pkg}/reconciliation/context.go | 19 +- .../reconciliation/decommission_node.go | 8 +- .../reconciliation/decommission_node_test.go | 17 +- .../pkg => pkg}/reconciliation/defaults.go | 3 - .../pkg => pkg}/reconciliation/handler.go | 131 +- pkg/reconciliation/handler_test.go | 384 + .../reconciliation/rackinformation.go | 0 .../reconciliation/reconcile_configsecret.go | 15 +- .../reconciliation/reconcile_datacenter.go | 6 +- .../reconcile_datacenter_test.go | 2 +- .../reconciliation/reconcile_endpoints.go | 6 +- .../reconciliation/reconcile_racks.go | 33 +- .../reconciliation/reconcile_racks_helpers.go | 4 +- .../reconcile_racks_helpers_test.go | 0 .../reconciliation/reconcile_racks_test.go | 10 +- .../reconciliation/reconcile_services.go | 6 +- .../reconciliation/reconcile_services_test.go | 2 +- .../pkg => pkg}/reconciliation/secrets.go | 4 +- .../reconciliation/secrets_test.go | 2 +- .../pkg => pkg}/reconciliation/testing.go | 12 +- {operator/pkg => pkg}/reconciliation/utils.go | 6 +- .../pkg => pkg}/serverconfig/configgen.go | 0 .../serverconfig/configgen_test.go | 0 {operator/pkg => pkg}/utils/crypto.go | 2 +- {operator/pkg => pkg}/utils/crypto_test.go | 0 .../pkg => pkg}/utils/hash_annotation.go | 0 .../pkg => pkg}/utils/hash_annotation_test.go | 5 +- {operator/pkg => pkg}/utils/k8s_utils.go | 124 +- {operator/pkg => pkg}/utils/utilities.go | 8 +- {operator/pkg => pkg}/utils/utilities_test.go | 35 +- tests/add_racks/add_racks_suite_test.go | 26 +- .../additional_seeds_suite_test.go | 10 +- .../additional_service_opts_suite_test.go | 11 +- .../additional_volumes_suite_test.go | 11 +- .../bring_up_graph_suite_test.go | 23 +- .../bring_up_solr/bring_up_solr_suite_test.go | 11 +- .../bring_up_spark_suite_test.go | 11 +- tests/canary_upgrade/canary_upgrade_test.go | 28 +- .../cluster_wide_install_suite_test.go | 17 +- tests/cluster_wide_install/kustomization.yaml | 54 + .../config_change/config_change_suite_test.go | 11 +- .../config_change_condition_suite_test.go | 11 +- .../config_secret/config_secret_suite_test.go | 32 +- .../delete_node_lost_readiness_suite_test.go | 25 +- ...ete_node_terminate_container_suite_test.go | 11 +- .../helm_chart_imagepullsecrets_suite_test.go | 65 - tests/host_network/host_network_suite_test.go | 23 +- .../internode_secret_generated_test.go | 10 +- tests/kustomize/deploy.go | 52 + tests/kustomize/kustomization.yaml | 7 + .../multi_cluster_management_suite_test.go | 11 +- .../no_infinite_reconcile_suite_test.go | 23 +- tests/node_replace/node_replace_suite_test.go | 11 +- .../nodeport_service_suite_test.go | 9 +- .../oss_test_all_the_things_suite_test.go | 11 +- .../podspec_simple_suite_test.go | 11 +- tests/psp_emm/psp_emm_suite_test.go | 12 +- tests/psp_health/psp_health_suite_test.go | 41 +- .../psp_pvc_annotation_suite_test.go | 13 +- .../rolling_restart_suite_test.go | 25 +- tests/scale_down/scale_down_suite_test.go | 13 +- .../scale_down_not_enough_space_suite_test.go | 14 +- .../scale_down_unbalanced_racks_suite_test.go | 15 +- tests/scale_up/scale_up_suite_test.go | 26 +- .../scale_up_park_unpark_suite_test.go | 11 +- .../seed_selection_suite_test.go | 9 +- .../smoke_test_dse_suite_test.go | 11 +- .../smoke_test_oss_suite_test.go | 25 +- tests/stop_resume/park_unpark_suite_test.go | 13 +- .../park_unpark_scale_up_suite_test.go | 11 +- .../superuser_secret_generated_test.go | 9 +- .../superuser_secret_provided_test.go | 15 +- tests/terminate/terminate_suite_test.go | 11 +- .../test_bad_config_and_fix_suite_test.go | 11 +- .../test_mtls_mgmt_api_suite_test.go | 26 +- .../timeout_prestop_termination_suite_test.go | 11 +- .../upgrade_operator_suite_test.go | 17 +- .../webhook_validation_suite_test.go | 11 +- tools/k8s-code-generator/Dockerfile | 57 - tools/operator-sdk/Dockerfile | 6 +- update-kubernetes.sh | 20 + 246 files changed, 10879 insertions(+), 20352 deletions(-) create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 PROJECT rename {operator/pkg/apis/cassandra => api}/v1beta1/cassandradatacenter_types.go (98%) rename operator/pkg/apis/cassandra/v1beta1/webhook.go => api/v1beta1/cassandradatacenter_webhook.go (75%) create mode 100644 api/v1beta1/groupversion_info.go create mode 100644 api/v1beta1/webhook_suite_test.go rename {operator/pkg/apis/cassandra => api}/v1beta1/webhook_test.go (100%) rename {operator/pkg/apis/cassandra => api}/v1beta1/zz_generated.deepcopy.go (95%) delete mode 100644 charts/cass-operator-chart/Chart.yaml delete mode 100644 charts/cass-operator-chart/templates/clusterrole.yaml delete mode 100644 charts/cass-operator-chart/templates/clusterrolebinding.yaml delete mode 100644 charts/cass-operator-chart/templates/customresourcedefinition.yaml delete mode 100644 charts/cass-operator-chart/templates/deployment.yaml delete mode 100644 charts/cass-operator-chart/templates/registry-secret.yaml delete mode 100644 charts/cass-operator-chart/templates/role.yaml delete mode 100644 charts/cass-operator-chart/templates/serviceaccount.yaml delete mode 100644 charts/cass-operator-chart/templates/validatingwebhookconfiguration.yaml delete mode 100644 charts/cass-operator-chart/templates/webhook-cr.yaml delete mode 100644 charts/cass-operator-chart/templates/webhook-crb.yaml delete mode 100644 charts/cass-operator-chart/templates/webhook-secret.yaml delete mode 100644 charts/cass-operator-chart/templates/webhook-service.yaml delete mode 100644 charts/cass-operator-chart/values.yaml create mode 100644 config/certmanager/certificate.yaml create mode 100644 config/certmanager/kustomization.yaml create mode 100644 config/certmanager/kustomizeconfig.yaml create mode 100644 config/crd/bases/cassandra.datastax.com_cassandradatacenters.yaml create mode 100644 config/crd/kustomization.yaml create mode 100644 config/crd/kustomizeconfig.yaml create mode 100644 config/crd/patches/cainjection_in_cassandradatacenters.yaml create mode 100644 config/crd/patches/config_removal.yaml create mode 100644 config/crd/patches/remove_xkeys.yaml create mode 100644 config/crd/patches/webhook_in_cassandradatacenters.yaml create mode 100644 config/default/kustomization.yaml create mode 100644 config/default/manager_auth_proxy_patch.yaml create mode 100644 config/default/manager_config_patch.yaml create mode 100644 config/default/manager_webhook_patch.yaml create mode 100644 config/default/webhookcainjection_patch.yaml create mode 100644 config/manager/controller_manager_config.yaml create mode 100644 config/manager/kustomization.yaml create mode 100644 config/manager/manager.yaml create mode 100644 config/manifests/bases/cass-operator.clusterserviceversion.yaml create mode 100644 config/manifests/kustomization.yaml create mode 100644 config/prometheus/kustomization.yaml create mode 100644 config/prometheus/monitor.yaml create mode 100644 config/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 config/rbac/auth_proxy_role.yaml rename operator/deploy/cluster_role_binding.yaml => config/rbac/auth_proxy_role_binding.yaml (61%) create mode 100644 config/rbac/auth_proxy_service.yaml create mode 100644 config/rbac/cassandradatacenter_editor_role.yaml create mode 100644 config/rbac/cassandradatacenter_viewer_role.yaml create mode 100644 config/rbac/kustomization.yaml create mode 100644 config/rbac/leader_election_role.yaml rename operator/deploy/role_binding.yaml => config/rbac/leader_election_role_binding.yaml (63%) create mode 100644 config/rbac/role.yaml rename charts/cass-operator-chart/templates/rolebinding.yaml => config/rbac/role_binding.yaml (51%) rename {operator/deploy => config/rbac}/service_account.yaml (54%) create mode 100644 config/samples/cassandra.datastax.com_v1beta1_cassandradatacenter.yaml create mode 100644 config/samples/kustomization.yaml create mode 100644 config/scorecard/bases/config.yaml create mode 100644 config/scorecard/kustomization.yaml create mode 100644 config/scorecard/patches/basic.config.yaml create mode 100644 config/scorecard/patches/olm.config.yaml create mode 100644 config/webhook/kustomization.yaml create mode 100644 config/webhook/kustomizeconfig.yaml create mode 100644 config/webhook/manifests.yaml create mode 100644 config/webhook/service.yaml create mode 100644 controllers/cassandradatacenter_controller.go create mode 100644 controllers/suite_test.go create mode 100644 hack/boilerplate.go.txt delete mode 100644 mage/docker/lib.go delete mode 100644 mage/helm/lib.go delete mode 100644 mage/integ-tests/lib.go delete mode 100644 mage/integ-tests/lib_test.go delete mode 100644 mage/k3d/lib.go delete mode 100644 mage/k8s/lib.go delete mode 100644 mage/kind/lib.go delete mode 100644 mage/operator/crd.patch delete mode 100644 mage/operator/deploy.go delete mode 100644 mage/operator/lib.go delete mode 100644 mage/operator/lib_test.go create mode 100644 main.go delete mode 100644 operator/cmd/manager/main.go delete mode 100644 operator/deploy/README.md delete mode 100644 operator/deploy/cluster_role.yaml delete mode 100644 operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml delete mode 100644 operator/deploy/namespace.yaml delete mode 100644 operator/deploy/operator.yaml delete mode 100644 operator/deploy/role.yaml delete mode 100644 operator/deploy/webhook_configuration.yaml delete mode 100644 operator/deploy/webhook_secret.yaml delete mode 100644 operator/deploy/webhook_service.yaml delete mode 100644 operator/pkg/admissionwebhook/webhook.go delete mode 100644 operator/pkg/apis/addtoscheme_cassandra_v1beta1.go delete mode 100644 operator/pkg/apis/apis.go delete mode 100644 operator/pkg/apis/cassandra/group.go delete mode 100644 operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types_test.go delete mode 100644 operator/pkg/apis/cassandra/v1beta1/doc.go delete mode 100644 operator/pkg/apis/cassandra/v1beta1/register.go delete mode 100644 operator/pkg/apis/cassandra/v1beta1/zz_generated.openapi.go delete mode 100644 operator/pkg/controller/add_cassandradatacenter.go delete mode 100644 operator/pkg/controller/cassandradatacenter/cassandradatacenter_controller.go delete mode 100644 operator/pkg/controller/controller.go delete mode 100644 operator/pkg/reconciliation/handler_test.go rename {operator/pkg => pkg}/dynamicwatch/watch.go (91%) rename {operator/pkg => pkg}/events/events.go (100%) rename {operator/pkg => pkg}/events/events_test.go (75%) rename {operator/pkg => pkg}/generated/clientset/versioned/clientset.go (93%) rename {operator/pkg => pkg}/generated/clientset/versioned/doc.go (100%) rename {operator/pkg => pkg}/generated/clientset/versioned/fake/clientset_generated.go (87%) rename {operator/pkg => pkg}/generated/clientset/versioned/fake/doc.go (100%) rename {operator/pkg => pkg}/generated/clientset/versioned/fake/register.go (93%) rename {operator/pkg => pkg}/generated/clientset/versioned/scheme/doc.go (100%) rename {operator/pkg => pkg}/generated/clientset/versioned/scheme/register.go (93%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go (92%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go (60%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/doc.go (100%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/fake/doc.go (100%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go (90%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go (75%) rename {operator/pkg => pkg}/generated/clientset/versioned/typed/cassandra/v1beta1/generated_expansion.go (100%) rename {operator/pkg => pkg}/httphelper/client.go (100%) rename {operator/pkg => pkg}/httphelper/client_test.go (97%) rename {operator/pkg => pkg}/httphelper/httpclient.go (98%) rename {operator/pkg => pkg}/httphelper/security.go (99%) rename {operator/pkg => pkg}/httphelper/security_test.go (100%) rename {operator/pkg => pkg}/httphelper/testdata/ca.crt (100%) rename {operator/pkg => pkg}/httphelper/testdata/ca.key (100%) rename {operator/pkg => pkg}/httphelper/testdata/client.crt (100%) rename {operator/pkg => pkg}/httphelper/testdata/client.key (100%) rename {operator/pkg => pkg}/httphelper/testdata/evil_ca.crt (100%) rename {operator/pkg => pkg}/httphelper/testdata/evil_ca.key (100%) rename {operator/pkg => pkg}/httphelper/testdata/gencerts.sh (100%) rename {operator/pkg => pkg}/httphelper/testdata/server.crt (100%) rename {operator/pkg => pkg}/httphelper/testdata/server.encrypted.key (100%) rename {operator/pkg => pkg}/httphelper/testdata/server.key (100%) rename {operator/pkg => pkg}/httphelper/testdata/server.rsa.key (100%) rename {operator/pkg => pkg}/images/images.go (99%) rename {operator/pkg => pkg}/images/images_test.go (100%) rename {operator => pkg}/internal/result/result_helper.go (66%) rename {operator => pkg}/internal/result/result_helper_test.go (100%) rename {operator/pkg => pkg}/mocks/Client.go (66%) rename {operator/pkg => pkg}/mocks/HttpClient.go (100%) rename {operator/pkg => pkg}/oplabels/labels.go (73%) rename {operator/pkg => pkg}/psp/emm.go (99%) rename {operator/pkg => pkg}/psp/emm_test.go (99%) rename {operator/pkg => pkg}/psp/labels_annotations.go (86%) rename {operator/pkg => pkg}/psp/networkpolicies.go (93%) rename {operator/pkg => pkg}/psp/psp_status.go (89%) rename {operator/pkg => pkg}/reconciliation/check_nodes.go (97%) rename {operator/pkg => pkg}/reconciliation/construct_podtemplatespec.go (98%) rename {operator/pkg => pkg}/reconciliation/construct_podtemplatespec_test.go (96%) rename {operator/pkg => pkg}/reconciliation/construct_service.go (97%) rename {operator/pkg => pkg}/reconciliation/construct_service_test.go (90%) rename {operator/pkg => pkg}/reconciliation/construct_statefulset.go (93%) rename {operator/pkg => pkg}/reconciliation/construct_statefulset_test.go (98%) rename {operator/pkg => pkg}/reconciliation/constructor.go (90%) rename {operator/pkg => pkg}/reconciliation/context.go (90%) rename {operator/pkg => pkg}/reconciliation/decommission_node.go (97%) rename {operator/pkg => pkg}/reconciliation/decommission_node_test.go (85%) rename {operator/pkg => pkg}/reconciliation/defaults.go (68%) rename {operator/pkg => pkg}/reconciliation/handler.go (55%) create mode 100644 pkg/reconciliation/handler_test.go rename {operator/pkg => pkg}/reconciliation/rackinformation.go (100%) rename {operator/pkg => pkg}/reconciliation/reconcile_configsecret.go (94%) rename {operator/pkg => pkg}/reconciliation/reconcile_datacenter.go (94%) rename {operator/pkg => pkg}/reconciliation/reconcile_datacenter_test.go (97%) rename {operator/pkg => pkg}/reconciliation/reconcile_endpoints.go (94%) rename {operator/pkg => pkg}/reconciliation/reconcile_racks.go (99%) rename {operator/pkg => pkg}/reconciliation/reconcile_racks_helpers.go (94%) rename {operator/pkg => pkg}/reconciliation/reconcile_racks_helpers_test.go (100%) rename {operator/pkg => pkg}/reconciliation/reconcile_racks_test.go (99%) rename {operator/pkg => pkg}/reconciliation/reconcile_services.go (95%) rename {operator/pkg => pkg}/reconciliation/reconcile_services_test.go (98%) rename {operator/pkg => pkg}/reconciliation/secrets.go (98%) rename {operator/pkg => pkg}/reconciliation/secrets_test.go (98%) rename {operator/pkg => pkg}/reconciliation/testing.go (94%) rename {operator/pkg => pkg}/reconciliation/utils.go (83%) rename {operator/pkg => pkg}/serverconfig/configgen.go (100%) rename {operator/pkg => pkg}/serverconfig/configgen_test.go (100%) rename {operator/pkg => pkg}/utils/crypto.go (100%) rename {operator/pkg => pkg}/utils/crypto_test.go (100%) rename {operator/pkg => pkg}/utils/hash_annotation.go (100%) rename {operator/pkg => pkg}/utils/hash_annotation_test.go (99%) rename {operator/pkg => pkg}/utils/k8s_utils.go (50%) rename {operator/pkg => pkg}/utils/utilities.go (99%) rename {operator/pkg => pkg}/utils/utilities_test.go (92%) create mode 100644 tests/cluster_wide_install/kustomization.yaml delete mode 100644 tests/helm_chart_imagepullsecrets/helm_chart_imagepullsecrets_suite_test.go create mode 100644 tests/kustomize/deploy.go create mode 100644 tests/kustomize/kustomization.yaml delete mode 100644 tools/k8s-code-generator/Dockerfile create mode 100755 update-kubernetes.sh diff --git a/.github/workflows/kindIntegTest.yml b/.github/workflows/kindIntegTest.yml index 12d61024..19705e1f 100644 --- a/.github/workflows/kindIntegTest.yml +++ b/.github/workflows/kindIntegTest.yml @@ -25,7 +25,8 @@ jobs: id: docker_build uses: docker/build-push-action@v2 with: - file: operator/docker/base/Dockerfile + file: Dockerfile + context: . push: false tags: k8ssandra/cass-operator:latest platforms: linux/amd64 @@ -106,6 +107,7 @@ jobs: env: GOPATH: /home/runner/go GOROOT: /usr/local/go1.16 + CGO_ENABLED: 0 M_LOAD_TEST_IMAGES: false M_INTEG_DIR: ${{ matrix.integration_test }} M_K8S_FLAVOR: kind @@ -130,15 +132,11 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - - name: Install Helm - uses: azure/setup-helm@v1 - with: - version: v3.5.3 - name: Create Kind Cluster uses: helm/kind-action@v1.1.0 with: - version: v0.10.0 - node_image: kindest/node:v1.20.2 + version: v0.11.1 + node_image: kindest/node:v1.20.7 cluster_name: kind config: tests/testdata/kind/kind_config_6_workers.yaml - name: Set up Docker Buildx @@ -162,10 +160,12 @@ jobs: kind load docker-image --name=kind k8ssandra/cass-operator:latest kind load docker-image --name=kind k8ssandra/system-logger:latest - name: Run integration test ( ${{ matrix.integration_test }} ) - uses: magefile/mage-action@v1 - with: - version: latest - args: integ:run + run: | + make integ-test + # uses: magefile/mage-action@v1 + # with: + # version: latest + # args: integ:run - name: Archive k8s logs if: ${{ failure() }} uses: actions/upload-artifact@v2 diff --git a/.github/workflows/operatorBuildAndDeploy.yml b/.github/workflows/operatorBuildAndDeploy.yml index 176fc7dc..8607a944 100644 --- a/.github/workflows/operatorBuildAndDeploy.yml +++ b/.github/workflows/operatorBuildAndDeploy.yml @@ -12,6 +12,7 @@ jobs: env: GOPATH: /home/runner/go GOROOT: /usr/local/go1.16 + CGO_ENABLED: 0 steps: - uses: actions/checkout@v2 if: github.event_name == 'pull_request' @@ -38,21 +39,24 @@ jobs: key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- - - name: Test Sdk Generate - uses: magefile/mage-action@v1 - with: - version: latest - args: operator:testSdkGenerate - - name: Test Client Generate - uses: magefile/mage-action@v1 - with: - version: latest - args: operator:testGenerateClient + # - name: Test Sdk Generate + # uses: magefile/mage-action@v1 + # with: + # version: latest + # args: operator:testSdkGenerate + # - name: Test Client Generate + # uses: magefile/mage-action@v1 + # with: + # version: latest + # args: operator:testGenerateClient - name: Unit Tests - uses: magefile/mage-action@v1 - with: - version: latest - args: operator:testGo + run: | + export PATH=$GOROOT/bin:$GOPATH/bin:$PATH + make controller-gen test + # uses: magefile/mage-action@v1 + # with: + # version: latest + # args: operator:testGo build_operator_docker: name: Build Cass Operator Docker Image runs-on: ubuntu-latest @@ -84,7 +88,8 @@ jobs: id: docker_build uses: docker/build-push-action@v2 with: - file: operator/docker/base/Dockerfile + file: Dockerfile + context: . push: ${{ github.event_name != 'pull_request' }} tags: k8ssandra/cass-operator:${{ steps.vars.outputs.sha_short }}, k8ssandra/cass-operator:latest platforms: linux/amd64 diff --git a/.gitignore b/.gitignore index 44c92afb..ab35700e 100644 --- a/.gitignore +++ b/.gitignore @@ -248,3 +248,8 @@ tags # Packet captures *.pcap + +# make temps +bin/ +testbin/ +manager \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..45e30645 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +# Build the manager binary +FROM golang:1.15 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ +COPY pkg/ pkg/ + + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/manager . +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3630ba2d --- /dev/null +++ b/Makefile @@ -0,0 +1,229 @@ +# Makefile uses sh by default, but Github Actions (ubuntu-latest) requires dash/bash to work. +SHELL := /bin/bash + +# VERSION defines the project version for the bundle. +# Update this value when you upgrade the version of your project. +# To re-generate a bundle for another specific version without changing the standard setup, you can: +# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) +# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) +VERSION ?= 1.8.0 + +# CHANNELS define the bundle channels used in the bundle. +# Add a new line here if you would like to change its default config. (E.g CHANNELS = "preview,fast,stable") +# To re-generate a bundle for other specific channels without changing the standard setup, you can: +# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=preview,fast,stable) +# - use environment variables to overwrite this value (e.g export CHANNELS="preview,fast,stable") +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) +endif + +# DEFAULT_CHANNEL defines the default channel used in the bundle. +# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") +# To re-generate a bundle for any other default channel without changing the default setup, you can: +# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) +# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. +# This variable is used to construct full image tags for bundle and catalog images. +# +# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both +# cassandra.datastax.com/cass-oper-bundle:$VERSION and cassandra.datastax.com/cass-oper-catalog:$VERSION. +IMAGE_TAG_BASE ?= k8ssandra/cass-operator + +M_INTEG_DIR ?= all + +# BUNDLE_IMG defines the image:tag used for the bundle. +# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) +BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION) + +# Image URL to use all building/pushing image targets +IMG ?= $(IMAGE_TAG_BASE):latest +# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) +CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false" + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +all: build + +##@ General + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk commands is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. + $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + +fmt: ## Run go fmt against code. + go fmt ./... + +vet: ## Run go vet against code. + go vet ./... + +ENVTEST_ASSETS_DIR=$(shell pwd)/testbin +test: manifests generate fmt vet ## Run unit tests (including envtest based ones) + # Old unit tests first - these use mocked client / fakeclient + go test ./pkg/... -coverprofile cover-operator.out + # These are not used yet + mkdir -p ${ENVTEST_ASSETS_DIR} + test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.2/hack/setup-envtest.sh + source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./controllers/... -coverprofile cover.out + +integ-test: kustomize cert-manager ## Run integration tests from directory M_INTEG_DIR or set M_INTEG_DIR=all to run all the integration tests. +ifeq ($(M_INTEG_DIR), all) + # Run all the tests (exclude kustomize & testdata directories) + cd tests && go test -v -timeout 300m --ginkgo.progress --ginkgo.v ./... +else + cd tests/${M_INTEG_DIR} && go test -v -timeout 300m --ginkgo.progress --ginkgo.v ./... +endif + +##@ Build + +build: generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +docker-build: ## Build docker image with the manager. + docker buildx build -t ${IMG} . --load + +docker-kind: docker-build ## Build docker image and load to kind cluster + kind load docker-image ${IMG} + +docker-push: ## Build and push docker image with the manager. + docker buildx build -t ${IMG} . --push + +##@ Deployment + +install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/crd | kubectl apply -f - + +uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/crd | kubectl delete -f - + +deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | kubectl apply -f - + +undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/default | kubectl delete -f - + +deploy-test: +ifneq ($(strip $(NAMESPACE)),) + cd tests/kustomize && $(KUSTOMIZE) edit set namespace $(NAMESPACE) +endif + $(KUSTOMIZE) build tests/$(TEST_DIR) | kubectl apply -f - + +undeploy-test: +ifneq ($(strip $(NAMESPACE)),) + cd tests/kustomize && $(KUSTOMIZE) edit set namespace $(NAMESPACE) +endif + $(KUSTOMIZE) build tests/$(TEST_DIR) | kubectl delete -f - + +##@ Tools + +cert-manager: ## Install cert-manager to the cluster + kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yaml + +CONTROLLER_GEN = $(shell pwd)/bin/controller-gen +controller-gen: ## Download controller-gen locally if necessary. + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1) + +KUSTOMIZE = $(shell pwd)/bin/kustomize +kustomize: ## Download kustomize locally if necessary. + $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v4@v4.1.3) + +# go-get-tool will 'go get' any package $2 and install it to $1. +PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) +define go-get-tool +@[ -f $(1) ] || { \ +set -e ;\ +TMP_DIR=$$(mktemp -d) ;\ +cd $$TMP_DIR ;\ +go mod init tmp ;\ +echo "Downloading $(2)" ;\ +GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\ +rm -rf $$TMP_DIR ;\ +} +endef + +.PHONY: bundle +bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files. + operator-sdk generate kustomize manifests -q + cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + operator-sdk bundle validate ./bundle + +.PHONY: bundle-build +bundle-build: ## Build the bundle image. + docker buildx build -f bundle.Dockerfile -t $(BUNDLE_IMG) . --load + +.PHONY: bundle-push +bundle-push: ## Push the bundle image. + $(MAKE) docker-push IMG=$(BUNDLE_IMG) + +.PHONY: opm +OPM = ./bin/opm +opm: ## Download opm locally if necessary. +ifeq (,$(wildcard $(OPM))) +ifeq (,$(shell which opm 2>/dev/null)) + @{ \ + set -e ;\ + mkdir -p $(dir $(OPM)) ;\ + OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$${OS}-$${ARCH}-opm ;\ + chmod +x $(OPM) ;\ + } +else +OPM = $(shell which opm) +endif +endif + +# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). +# These images MUST exist in a registry and be pull-able. +BUNDLE_IMGS ?= $(BUNDLE_IMG) + +# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). +CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) + +# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. +ifneq ($(origin CATALOG_BASE_IMG), undefined) +FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) +endif + +# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. +# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: +# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator +.PHONY: catalog-build +catalog-build: opm ## Build a catalog image. + $(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) + +# Push the catalog image. +.PHONY: catalog-push +catalog-push: ## Push a catalog image. + $(MAKE) docker-push IMG=$(CATALOG_IMG) diff --git a/PROJECT b/PROJECT new file mode 100644 index 00000000..6f4a9c21 --- /dev/null +++ b/PROJECT @@ -0,0 +1,23 @@ +domain: cassandra.datastax.com +layout: +- go.kubebuilder.io/v3 +plugins: + manifests.sdk.operatorframework.io/v2: {} + scorecard.sdk.operatorframework.io/v2: {} +projectName: cass-operator +repo: github.com/k8ssandra/cass-operator +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: cassandra.datastax.com + group: cassandra.datastax.com + kind: CassandraDatacenter + path: github.com/k8ssandra/cass-operator/api/v1beta1 + version: v1beta1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +version: "3" diff --git a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go b/api/v1beta1/cassandradatacenter_types.go similarity index 98% rename from operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go rename to api/v1beta1/cassandradatacenter_types.go index 46024389..1ac52f9b 100644 --- a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go +++ b/api/v1beta1/cassandradatacenter_types.go @@ -8,7 +8,7 @@ import ( "fmt" "github.com/Jeffail/gabs" - "github.com/k8ssandra/cass-operator/operator/pkg/serverconfig" + "github.com/k8ssandra/cass-operator/pkg/serverconfig" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -62,11 +62,9 @@ type CassandraUser struct { // CassandraDatacenterSpec defines the desired state of a CassandraDatacenter // +k8s:openapi-gen=true +// +kubebuilder:pruning:PreserveUnknownFields +// +kubebuilder:validation:XPreserveUnknownFields type CassandraDatacenterSpec struct { - // Important: Run "mage operator:sdkGenerate" to regenerate code after modifying this file - // Add custom validation using kubebuilder tags: - // https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html - // Desired number of Cassandra server nodes // +kubebuilder:validation:Minimum=1 Size int32 `json:"size"` @@ -89,6 +87,7 @@ type CassandraDatacenterSpec struct { // Config for the server, in YAML format // +kubebuilder:pruning:PreserveUnknownFields + // +kubebuilder:validation:XPreserveUnknownFields Config json.RawMessage `json:"config,omitempty"` // ConfigSecret is the name of a secret that contains configuration for Cassandra. The @@ -102,7 +101,7 @@ type CassandraDatacenterSpec struct { // }, // "jmv-options": { // "max_heap_size": 1024M - // } + // } // } // // ConfigSecret is mutually exclusive with Config. ConfigSecret takes precedence and @@ -391,12 +390,10 @@ type CassandraDatacenterStatus struct { ObservedGeneration int64 `json:"observedGeneration,omitempty"` } -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - // CassandraDatacenter is the Schema for the cassandradatacenters API // +k8s:openapi-gen=true -// +kubebuilder:subresource:status +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status // +kubebuilder:resource:path=cassandradatacenters,scope=Namespaced,shortName=cassdc;cassdcs type CassandraDatacenter struct { metav1.TypeMeta `json:",inline"` @@ -433,7 +430,7 @@ type ReaperConfig struct { Resources corev1.ResourceRequirements `json:"resources,omitempty"` } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +//+kubebuilder:object:root=true // CassandraDatacenterList contains a list of CassandraDatacenter type CassandraDatacenterList struct { diff --git a/operator/pkg/apis/cassandra/v1beta1/webhook.go b/api/v1beta1/cassandradatacenter_webhook.go similarity index 75% rename from operator/pkg/apis/cassandra/v1beta1/webhook.go rename to api/v1beta1/cassandradatacenter_webhook.go index 248333bc..035a2241 100644 --- a/operator/pkg/apis/cassandra/v1beta1/webhook.go +++ b/api/v1beta1/cassandradatacenter_webhook.go @@ -1,5 +1,18 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ package v1beta1 @@ -10,14 +23,34 @@ import ( "reflect" "strings" - "github.com/k8ssandra/cass-operator/operator/pkg/images" + "github.com/k8ssandra/cass-operator/pkg/images" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" ) var log = logf.Log.WithName("api") +func (r *CassandraDatacenter) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// kubebuilder:webhook:path=/mutate-cassandra-datastax-com-v1beta1-cassandradatacenter,mutating=true,failurePolicy=fail,sideEffects=None,groups=cassandra.datastax.com,resources=cassandradatacenters,verbs=create;update,versions=v1beta1,name=mcassandradatacenter.kb.io,admissionReviewVersions={v1,v1beta1} +// +kubebuilder:webhook:path=/validate-cassandra-datastax-com-v1beta1-cassandradatacenter,mutating=false,failurePolicy=ignore,sideEffects=None,groups=cassandra.datastax.com,resources=cassandradatacenters,verbs=create;update,versions=v1beta1,name=vcassandradatacenter.kb.io,admissionReviewVersions={v1,v1beta1} + +var _ webhook.Defaulter = &CassandraDatacenter{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *CassandraDatacenter) Default() { + // No mutations at this point +} + func attemptedTo(action string, actionStrArgs ...interface{}) error { var msg string if actionStrArgs != nil { @@ -161,6 +194,7 @@ func ValidateDatacenterFieldChanges(oldDc CassandraDatacenter, newDc CassandraDa return nil } +// +kubebuilder:webhook:path=/validate-cassandra-datastax-com-v1beta1-cassandradatacenter,mutating=false,failurePolicy=ignore,sideEffects=None,groups=cassandra.datastax.com,resources=cassandradatacenters,verbs=create;update,versions=v1beta1,name=vcassandradatacenter.kb.io,admissionReviewVersions={v1,v1beta1} // +kubebuilder:webhook:path=/validate-cassandradatacenter,mutating=false,failurePolicy=ignore,groups=cassandra.datastax.com,resources=cassandradatacenters,verbs=create;update,versions=v1beta1,name=validate-cassandradatacenter-webhook var _ webhook.Validator = &CassandraDatacenter{} diff --git a/api/v1beta1/groupversion_info.go b/api/v1beta1/groupversion_info.go new file mode 100644 index 00000000..84425055 --- /dev/null +++ b/api/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains API Schema definitions for the cassandra.datastax.com v1beta1 API group +//+kubebuilder:object:generate=true +//+groupName=cassandra.datastax.com +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "cassandra.datastax.com", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1beta1/webhook_suite_test.go b/api/v1beta1/webhook_suite_test.go new file mode 100644 index 00000000..941dc3e6 --- /dev/null +++ b/api/v1beta1/webhook_suite_test.go @@ -0,0 +1,133 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "config", "webhook")}, + }, + } + + cfg, err := testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + // err = admissionv1beta1.AddToScheme(scheme) + // Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&CassandraDatacenter{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + err = mgr.Start(ctx) + if err != nil { + Expect(err).NotTo(HaveOccurred()) + } + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/operator/pkg/apis/cassandra/v1beta1/webhook_test.go b/api/v1beta1/webhook_test.go similarity index 100% rename from operator/pkg/apis/cassandra/v1beta1/webhook_test.go rename to api/v1beta1/webhook_test.go diff --git a/operator/pkg/apis/cassandra/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go similarity index 95% rename from operator/pkg/apis/cassandra/v1beta1/zz_generated.deepcopy.go rename to api/v1beta1/zz_generated.deepcopy.go index ea049b3f..8527a8f2 100644 --- a/operator/pkg/apis/cassandra/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -1,21 +1,35 @@ // +build !ignore_autogenerated -// Code generated by operator-sdk. DO NOT EDIT. +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. package v1beta1 import ( - json "encoding/json" - - v1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "encoding/json" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AdditionalVolumes) DeepCopyInto(out *AdditionalVolumes) { *out = *in in.PVCSpec.DeepCopyInto(&out.PVCSpec) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdditionalVolumes. @@ -36,7 +50,6 @@ func (in AdditionalVolumesSlice) DeepCopyInto(out *AdditionalVolumesSlice) { for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } - return } } @@ -57,7 +70,6 @@ func (in *CassandraDatacenter) DeepCopyInto(out *CassandraDatacenter) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraDatacenter. @@ -90,7 +102,6 @@ func (in *CassandraDatacenterList) DeepCopyInto(out *CassandraDatacenterList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraDatacenterList. @@ -198,7 +209,6 @@ func (in *CassandraDatacenterSpec) DeepCopyInto(out *CassandraDatacenterSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraDatacenterSpec. @@ -238,7 +248,6 @@ func (in *CassandraDatacenterStatus) DeepCopyInto(out *CassandraDatacenterStatus copy(*out, *in) } in.QuietPeriod.DeepCopyInto(&out.QuietPeriod) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraDatacenterStatus. @@ -254,7 +263,6 @@ func (in *CassandraDatacenterStatus) DeepCopy() *CassandraDatacenterStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CassandraNodeStatus) DeepCopyInto(out *CassandraNodeStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraNodeStatus. @@ -275,7 +283,6 @@ func (in CassandraStatusMap) DeepCopyInto(out *CassandraStatusMap) { for key, val := range *in { (*out)[key] = val } - return } } @@ -292,7 +299,6 @@ func (in CassandraStatusMap) DeepCopy() CassandraStatusMap { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CassandraUser) DeepCopyInto(out *CassandraUser) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CassandraUser. @@ -309,7 +315,6 @@ func (in *CassandraUser) DeepCopy() *CassandraUser { func (in *DatacenterCondition) DeepCopyInto(out *DatacenterCondition) { *out = *in in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatacenterCondition. @@ -325,7 +330,6 @@ func (in *DatacenterCondition) DeepCopy() *DatacenterCondition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DseWorkloads) DeepCopyInto(out *DseWorkloads) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DseWorkloads. @@ -351,7 +355,6 @@ func (in *ManagementApiAuthConfig) DeepCopyInto(out *ManagementApiAuthConfig) { *out = new(ManagementApiAuthManualConfig) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagementApiAuthConfig. @@ -367,7 +370,6 @@ func (in *ManagementApiAuthConfig) DeepCopy() *ManagementApiAuthConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ManagementApiAuthInsecureConfig) DeepCopyInto(out *ManagementApiAuthInsecureConfig) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagementApiAuthInsecureConfig. @@ -383,7 +385,6 @@ func (in *ManagementApiAuthInsecureConfig) DeepCopy() *ManagementApiAuthInsecure // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ManagementApiAuthManualConfig) DeepCopyInto(out *ManagementApiAuthManualConfig) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagementApiAuthManualConfig. @@ -404,7 +405,6 @@ func (in *NetworkingConfig) DeepCopyInto(out *NetworkingConfig) { *out = new(NodePortConfig) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkingConfig. @@ -420,7 +420,6 @@ func (in *NetworkingConfig) DeepCopy() *NetworkingConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodePortConfig) DeepCopyInto(out *NodePortConfig) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePortConfig. @@ -443,7 +442,6 @@ func (in *Rack) DeepCopyInto(out *Rack) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rack. @@ -460,7 +458,6 @@ func (in *Rack) DeepCopy() *Rack { func (in *ReaperConfig) DeepCopyInto(out *ReaperConfig) { *out = *in in.Resources.DeepCopyInto(&out.Resources) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReaperConfig. @@ -481,7 +478,6 @@ func (in *ServiceConfig) DeepCopyInto(out *ServiceConfig) { in.AllPodsService.DeepCopyInto(&out.AllPodsService) in.AdditionalSeedService.DeepCopyInto(&out.AdditionalSeedService) in.NodePortService.DeepCopyInto(&out.NodePortService) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfig. @@ -511,7 +507,6 @@ func (in *ServiceConfigAdditions) DeepCopyInto(out *ServiceConfigAdditions) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfigAdditions. @@ -539,7 +534,6 @@ func (in *StorageConfig) DeepCopyInto(out *StorageConfig) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageConfig. diff --git a/charts/cass-operator-chart/Chart.yaml b/charts/cass-operator-chart/Chart.yaml deleted file mode 100644 index a7e8d7de..00000000 --- a/charts/cass-operator-chart/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v2 -name: cass-operator -version: 1.7.1 -description: Helm chart for Cass Operator. -appVersion: 1.7.1 -home: https://github.com/k8ssandra/cass-operator -maintainers: - - name: Cassandra Operator Team - email: cass-operator@datastax.coom - url: https://www.datastax.com/ diff --git a/charts/cass-operator-chart/templates/clusterrole.yaml b/charts/cass-operator-chart/templates/clusterrole.yaml deleted file mode 100644 index 8ebf2773..00000000 --- a/charts/cass-operator-chart/templates/clusterrole.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Values.clusterRoleName }} -rules: -- apiGroups: - - "" - resources: - - nodes - - persistentvolumes - verbs: - - get - - list - - watch diff --git a/charts/cass-operator-chart/templates/clusterrolebinding.yaml b/charts/cass-operator-chart/templates/clusterrolebinding.yaml deleted file mode 100644 index c4e385f5..00000000 --- a/charts/cass-operator-chart/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.clusterRoleBindingName }} -subjects: -- kind: ServiceAccount - name: {{ .Values.serviceAccountName }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.clusterRoleName }} - apiGroup: rbac.authorization.k8s.io diff --git a/charts/cass-operator-chart/templates/customresourcedefinition.yaml b/charts/cass-operator-chart/templates/customresourcedefinition.yaml deleted file mode 100644 index fff8c481..00000000 --- a/charts/cass-operator-chart/templates/customresourcedefinition.yaml +++ /dev/null @@ -1,6579 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: cassandradatacenters.cassandra.datastax.com -spec: - group: cassandra.datastax.com - names: - kind: CassandraDatacenter - listKind: CassandraDatacenterList - plural: cassandradatacenters - shortNames: - - cassdc - - cassdcs - singular: cassandradatacenter - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: CassandraDatacenter is the Schema for the cassandradatacenters - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: CassandraDatacenterSpec defines the desired state of a CassandraDatacenter - properties: - additionalSeeds: - items: - type: string - type: array - additionalServiceConfig: - description: AdditionalServiceConfig allows to define additional parameters - that are included in the created Services. Note, user can override - values set by cass-operator and doing so could break cass-operator - functionality. Avoid label "cass-operator" and anything that starts - with "cassandra.datastax.com/" - properties: - additionalSeedService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - allpodsService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - dcService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - nodePortService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - seedService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - type: object - allowMultipleNodesPerWorker: - description: Turning this option on allows multiple server pods to be - created on a k8s worker node. By default the operator creates just - one server pod per k8s worker node using k8s podAntiAffinity and requiredDuringSchedulingIgnoredDuringExecution. - type: boolean - canaryUpgrade: - description: Indicates that configuration and container image changes - should only be pushed to the first rack of the datacenter - type: boolean - canaryUpgradeCount: - description: The number of nodes that will be updated when CanaryUpgrade - is true. Note that the value is either 0 or greater than the rack - size, then all nodes in the rack will get updated. - format: int32 - type: integer - clusterName: - description: The name by which CQL clients and instances will know the - cluster. If the same cluster name is shared by multiple Datacenters - in the same Kubernetes namespace, they will join together in a multi-datacenter - cluster. - minLength: 2 - type: string - configBuilderImage: - description: Container image for the config builder init container. - type: string - configBuilderResources: - description: Kubernetes resource requests and limits per server config - initialization container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - configSecret: - description: "ConfigSecret is the name of a secret that contains configuration - for Cassandra. The secret is expected to have a property named config - whose value should be a JSON formatted string that should look like - this: \n config: |- { \"cassandra-yaml\": { \"read_request_timeout_in_ms\": - 10000 }, \"jmv-options\": { \"max_heap_size\": - 1024M } } \n ConfigSecret is mutually exclusive with Config. - ConfigSecret takes precedence and will be used exclusively if both - properties are set. The operator sets a watch such that an update - to the secret will trigger an update of the StatefulSets." - type: string - disableSystemLoggerSidecar: - description: Configuration for disabling the simple log tailing sidecar - container. Our default is to have it enabled. - type: boolean - dockerImageRunsAsCassandra: - description: Does the Server Docker image run as the Cassandra user? - type: boolean - dseWorkloads: - properties: - analyticsEnabled: - type: boolean - graphEnabled: - type: boolean - searchEnabled: - type: boolean - type: object - forceUpgradeRacks: - description: Rack names in this list are set to the latest StatefulSet - configuration even if Cassandra nodes are down. Use this to recover - from an upgrade that couldn't roll out. - items: - type: string - type: array - managementApiAuth: - description: Config for the Management API certificates - properties: - insecure: - type: object - manual: - properties: - clientSecretName: - type: string - serverSecretName: - type: string - skipSecretValidation: - type: boolean - required: - - clientSecretName - - serverSecretName - type: object - type: object - networking: - properties: - hostNetwork: - type: boolean - nodePort: - properties: - internode: - type: integer - internodeSSL: - type: integer - native: - type: integer - nativeSSL: - type: integer - type: object - type: object - nodeAffinityLabels: - additionalProperties: - type: string - description: NodeAffinityLabels to pin the Datacenter, using node affinity - type: object - nodeSelector: - additionalProperties: - type: string - description: 'A map of label keys and values to restrict Cassandra node - scheduling to k8s workers with matchiing labels. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector' - type: object - podTemplateSpec: - description: PodTemplate provides customisation options (labels, annotations, - affinity rules, resource requests, and so on) for the cassandra pods - properties: - metadata: - description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' - type: object - spec: - description: 'Specification of the desired behavior of the pod. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' - properties: - activeDeadlineSeconds: - description: Optional duration in seconds the pod may be active - on the node relative to StartTime before the system will actively - try to mark it failed and kill associated containers. Value - must be a positive integer. - format: int64 - type: integer - affinity: - description: If specified, the pod's scheduling constraints - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for - the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a - no-op). A null preferred scheduling term matches - no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range - 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an - update), the system may or may not try to eventually - evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) with the - highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, etc. - as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the greatest - sum of weights, i.e. for each node that meets all - of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if the - node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - description: AutomountServiceAccountToken indicates whether - a service account token should be automatically mounted. - type: boolean - containers: - description: List of containers belonging to the pod. Containers - cannot currently be added or removed. There must be at least - one container in a Pod. Cannot be updated. - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config - management to default or override container images in - workload controllers like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should - take in response to container lifecycle events. Cannot - be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but - is primarily informational. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port - which is listening on the default "0.0.0.0" address - inside a container will be accessible from the network. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if - the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: 'Security options the pod should run with. - More info: https://kubernetes.io/docs/concepts/policy/security-context/ - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has - successfully initialized. If specified, no other probes - are executed until this completes successfully. If this - probe fails, the Pod will be restarted, just as if the - livenessProbe failed. This can be used to provide different - probe parameters at the beginning of a Pod''s lifecycle, - when it might take a long time to load data or warm - a cache, than during steady-state operation. This cannot - be updated. This is an alpha feature enabled by the - StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - dnsConfig: - description: Specifies the DNS parameters of a pod. Parameters - specified here will be merged to the generated DNS configuration - based on DNSPolicy. - properties: - nameservers: - description: A list of DNS name server IP addresses. This - will be appended to the base nameservers generated from - DNSPolicy. Duplicated nameservers will be removed. - items: - type: string - type: array - options: - description: A list of DNS resolver options. This will be - merged with the base options generated from DNSPolicy. - Duplicated entries will be removed. Resolution options - given in Options will override those that appear in the - base DNSPolicy. - items: - description: PodDNSConfigOption defines DNS resolver options - of a pod. - properties: - name: - description: Required. - type: string - value: - type: string - type: object - type: array - searches: - description: A list of DNS search domains for host-name - lookup. This will be appended to the base search paths - generated from DNSPolicy. Duplicated search paths will - be removed. - items: - type: string - type: array - type: object - dnsPolicy: - description: Set DNS policy for the pod. Defaults to "ClusterFirst". - Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', - 'Default' or 'None'. DNS parameters given in DNSConfig will - be merged with the policy selected with DNSPolicy. To have - DNS options set along with hostNetwork, you have to specify - DNS policy explicitly to 'ClusterFirstWithHostNet'. - type: string - enableServiceLinks: - description: 'EnableServiceLinks indicates whether information - about services should be injected into pod''s environment - variables, matching the syntax of Docker links. Optional: - Defaults to true.' - type: boolean - ephemeralContainers: - description: List of ephemeral containers run in this pod. Ephemeral - containers may be run in an existing pod to perform user-initiated - actions such as debugging. This list cannot be specified when - creating a pod, and it cannot be modified by updating the - pod spec. In order to add an ephemeral container to an existing - pod, use the pod's ephemeralcontainers subresource. This field - is alpha-level and is only honored by servers that enable - the EphemeralContainers feature. - items: - description: An EphemeralContainer is a container that may - be added temporarily to an existing pod for user-initiated - activities such as debugging. Ephemeral containers have - no resource or scheduling guarantees, and they will not - be restarted when they exit or when a pod is removed or - restarted. If an ephemeral container causes a pod to exceed - its resource allocation, the pod may be evicted. Ephemeral - containers may not be added by directly updating the pod - spec. They must be added via the pod's ephemeralcontainers - subresource, and they will appear in the pod spec once added. - This is an alpha feature enabled by the EphemeralContainers - feature flag. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Lifecycle is not allowed for ephemeral containers. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the ephemeral container specified - as a DNS_LABEL. This name must be unique among all containers, - init containers and ephemeral containers. - type: string - ports: - description: Ports are not allowed for ephemeral containers. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - readinessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: Resources are not allowed for ephemeral containers. - Ephemeral containers use spare resources already allocated - to the pod. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: SecurityContext is not allowed for ephemeral - containers. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - targetContainerName: - description: If set, the name of the container from PodSpec - that this ephemeral container targets. The ephemeral - container will be run in the namespaces (IPC, PID, etc) - of this container. If not set then the ephemeral container - is run in whatever namespaces are shared for the pod. - Note that the container runtime must support this feature. - type: string - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - hostAliases: - description: HostAliases is an optional list of hosts and IPs - that will be injected into the pod's hosts file if specified. - This is only valid for non-hostNetwork pods. - items: - description: HostAlias holds the mapping between IP and hostnames - that will be injected as an entry in the pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - ip: - description: IP address of the host file entry. - type: string - type: object - type: array - hostIPC: - description: 'Use the host''s ipc namespace. Optional: Default - to false.' - type: boolean - hostNetwork: - description: Host networking requested for this pod. Use the - host's network namespace. If this option is set, the ports - that will be used must be specified. Default to false. - type: boolean - hostPID: - description: 'Use the host''s pid namespace. Optional: Default - to false.' - type: boolean - hostname: - description: Specifies the hostname of the Pod If not specified, - the pod's hostname will be set to a system-defined value. - type: string - imagePullSecrets: - description: 'ImagePullSecrets is an optional list of references - to secrets in the same namespace to use for pulling any of - the images used by this PodSpec. If specified, these secrets - will be passed to individual puller implementations for them - to use. For example, in the case of docker, only DockerConfig - type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' - items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same - namespace. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - type: array - initContainers: - description: 'List of initialization containers belonging to - the pod. Init containers are executed in order prior to containers - being started. If any init container fails, the pod is considered - to have failed and is handled according to its restartPolicy. - The name for an init container or normal container must be - unique among all containers. Init containers may not have - Lifecycle actions, Readiness probes, Liveness probes, or Startup - probes. The resourceRequirements of an init container are - taken into account during scheduling by finding the highest - request/limit for each resource type, and then using the max - of of that value or the sum of the normal containers. Limits - are applied to init containers in a similar fashion. Init - containers cannot currently be added or removed. Cannot be - updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config - management to default or override container images in - workload controllers like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should - take in response to container lifecycle events. Cannot - be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but - is primarily informational. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port - which is listening on the default "0.0.0.0" address - inside a container will be accessible from the network. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if - the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: 'Security options the pod should run with. - More info: https://kubernetes.io/docs/concepts/policy/security-context/ - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has - successfully initialized. If specified, no other probes - are executed until this completes successfully. If this - probe fails, the Pod will be restarted, just as if the - livenessProbe failed. This can be used to provide different - probe parameters at the beginning of a Pod''s lifecycle, - when it might take a long time to load data or warm - a cache, than during steady-state operation. This cannot - be updated. This is an alpha feature enabled by the - StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - nodeName: - description: NodeName is a request to schedule this pod onto - a specific node. If it is non-empty, the scheduler simply - schedules this pod onto that node, assuming that it fits resource - requirements. - type: string - nodeSelector: - additionalProperties: - type: string - description: 'NodeSelector is a selector which must be true - for the pod to fit on a node. Selector which must match a - node''s labels for the pod to be scheduled on that node. More - info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Overhead represents the resource overhead associated - with running a pod for a given RuntimeClass. This field will - be autopopulated at admission time by the RuntimeClass admission - controller. If the RuntimeClass admission controller is enabled, - overhead must not be set in Pod create requests. The RuntimeClass - admission controller will reject Pod create requests which - have the overhead already set. If RuntimeClass is configured - and selected in the PodSpec, Overhead will be set to the value - defined in the corresponding RuntimeClass, otherwise it will - remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md - This field is alpha-level as of Kubernetes v1.16, and is only - honored by servers that enable the PodOverhead feature.' - type: object - preemptionPolicy: - description: PreemptionPolicy is the Policy for preempting pods - with lower priority. One of Never, PreemptLowerPriority. Defaults - to PreemptLowerPriority if unset. This field is alpha-level - and is only honored by servers that enable the NonPreemptingPriority - feature. - type: string - priority: - description: The priority value. Various system components use - this field to find the priority of the pod. When Priority - Admission Controller is enabled, it prevents users from setting - this field. The admission controller populates this field - from PriorityClassName. The higher the value, the higher the - priority. - format: int32 - type: integer - priorityClassName: - description: If specified, indicates the pod's priority. "system-node-critical" - and "system-cluster-critical" are two special keywords which - indicate the highest priorities with the former being the - highest priority. Any other name must be defined by creating - a PriorityClass object with that name. If not specified, the - pod priority will be default or zero if there is no default. - type: string - readinessGates: - description: 'If specified, all readiness gates will be evaluated - for pod readiness. A pod is ready when all its containers - are ready AND all conditions specified in the readiness gates - have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md' - items: - description: PodReadinessGate contains the reference to a - pod condition - properties: - conditionType: - description: ConditionType refers to a condition in the - pod's condition list with matching type. - type: string - required: - - conditionType - type: object - type: array - restartPolicy: - description: 'Restart policy for all containers within the pod. - One of Always, OnFailure, Never. Default to Always. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' - type: string - runtimeClassName: - description: 'RuntimeClassName refers to a RuntimeClass object - in the node.k8s.io group, which should be used to run this - pod. If no RuntimeClass resource matches the named class, - the pod will not be run. If unset or empty, the "legacy" RuntimeClass - will be used, which is an implicit class with an empty definition - that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md - This is a beta feature as of Kubernetes v1.14.' - type: string - schedulerName: - description: If specified, the pod will be dispatched by specified - scheduler. If not specified, the pod will be dispatched by - default scheduler. - type: string - securityContext: - description: 'SecurityContext holds pod-level security attributes - and common container settings. Optional: Defaults to empty. See - type description for default values of each field.' - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow the - Kubelet to change the ownership of that volume to be owned - by the pod: \n 1. The owning GID will be the FSGroup 2. - The setgid bit is set (new files created in the volume - will be owned by FSGroup) 3. The permission bits are OR'd - with rw-rw---- \n If unset, the Kubelet will not modify - the ownership and permissions of any volume." - format: int64 - type: integer - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a - non-root user. If true, the Kubelet will validate the - image at runtime to ensure that it does not run as UID - 0 (root) and fail to start the container if it does. If - unset or false, no such validation will be performed. - May also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence for - that container. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a - random SELinux context for each container. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID. If unspecified, no groups will be added - to any container. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. This field is - alpha-level and is only honored by servers that enable - the WindowsGMSA feature flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. This field is alpha-level - and is only honored by servers that enable the WindowsGMSA - feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - serviceAccount: - description: 'DeprecatedServiceAccount is a depreciated alias - for ServiceAccountName. Deprecated: Use serviceAccountName - instead.' - type: string - serviceAccountName: - description: 'ServiceAccountName is the name of the ServiceAccount - to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' - type: string - shareProcessNamespace: - description: 'Share a single process namespace between all of - the containers in a pod. When this is set containers will - be able to view and signal processes from other containers - in the same pod, and the first process in each container will - not be assigned PID 1. HostPID and ShareProcessNamespace cannot - both be set. Optional: Default to false.' - type: boolean - subdomain: - description: If specified, the fully qualified Pod hostname - will be "...svc.". If not specified, the pod will not have a domainname - at all. - type: string - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs to terminate - gracefully. May be decreased in delete request. Value must - be non-negative integer. The value zero indicates delete immediately. - If this value is nil, the default grace period will be used - instead. The grace period is the duration in seconds after - the processes running in the pod are sent a termination signal - and the time when the processes are forcibly halted with a - kill signal. Set this value longer than the expected cleanup - time for your process. Defaults to 30 seconds. - format: int64 - type: integer - tolerations: - description: If specified, the pod's tolerations. - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - topologySpreadConstraints: - description: TopologySpreadConstraints describes how a group - of pods ought to spread across topology domains. Scheduler - will schedule pods in a way which abides by the constraints. - This field is alpha-level and is only honored by clusters - that enables the EvenPodsSpread feature. All topologySpreadConstraints - are ANDed. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine - the number of pods in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - maxSkew: - description: 'MaxSkew describes the degree to which pods - may be unevenly distributed. It''s the maximum permitted - difference between the number of matching pods in any - two topology domains of a given topology type. For example, - in a 3-zone cluster, MaxSkew is set to 1, and pods with - the same labelSelector spread as 1/1/0: | zone1 | zone2 - | zone3 | | P | P | | - if MaxSkew is - 1, incoming pod can only be scheduled to zone3 to become - 1/1/1; scheduling it onto zone1(zone2) would make the - ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto - any zone. It''s a required field. Default value is 1 - and 0 is not allowed.' - format: int32 - type: integer - topologyKey: - description: TopologyKey is the key of node labels. Nodes - that have a label with this key and identical values - are considered to be in the same topology. We consider - each as a "bucket", and try to put balanced - number of pods into each bucket. It's a required field. - type: string - whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how to deal - with a pod if it doesn''t satisfy the spread constraint. - - DoNotSchedule (default) tells the scheduler not to - schedule it - ScheduleAnyway tells the scheduler to - still schedule it It''s considered as "Unsatisfiable" - if and only if placing incoming pod on any topology - violates "MaxSkew". For example, in a 3-zone cluster, - MaxSkew is set to 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming - pod can only be scheduled to zone2(zone3) to become - 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be - imbalanced, but scheduler won''t make it *more* imbalanced. - It''s a required field.' - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - volumes: - description: 'List of volumes that can be mounted by containers - belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - partition: - description: 'The partition in the volume that you - want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, - you specify the partition as "1". Similarly, the - volume partition for /dev/sda is "0" (or you can - leave the property empty).' - format: int32 - type: integer - readOnly: - description: 'Specify "true" to force and set the - ReadOnly property in VolumeMounts to "true". If - omitted, the default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: AzureDisk represents an Azure Data Disk mount - on the host and bind mount to the pod. - properties: - cachingMode: - description: 'Host Caching mode: None, Read Only, - Read Write.' - type: string - diskName: - description: The Name of the data disk in the blob - storage - type: string - diskURI: - description: The URI the data disk in the blob storage - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed - data disk (only in managed availability set). defaults - to shared' - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: AzureFile represents an Azure File Service - mount on the host and bind mount to the pod. - properties: - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: the name of secret that contains Azure - Storage Account Name and Key - type: string - shareName: - description: Share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: CephFS represents a Ceph FS mount on the - host that shares a pod's lifetime - properties: - monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'Optional: Used as the mounted root, - rather than the full Ceph tree, default is /' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'Optional: SecretFile is the path to - key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'Optional: SecretRef is reference to - the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'Cinder represents a cinder volume attached - and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'Filesystem type to mount. Must be a - filesystem type supported by the host operating - system. Examples: "ext4", "xfs", "ntfs". Implicitly - inferred to be "ext4" if unspecified. More info: - https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'Optional: points to a secret object - containing parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: ConfigMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will - be projected into the volume as a file whose name - is the key and content is the value. If specified, - the listed keys will be projected into the specified - paths, and unlisted keys will not be present. If - a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked - optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - keys must be defined - type: boolean - type: object - csi: - description: CSI (Container Storage Interface) represents - storage that is handled by an external CSI driver (Alpha - feature). - properties: - driver: - description: Driver is the name of the CSI driver - that handles this volume. Consult with your admin - for the correct name as registered in the cluster. - type: string - fsType: - description: Filesystem type to mount. Ex. "ext4", - "xfs", "ntfs". If not provided, the empty value - is passed to the associated CSI driver which will - determine the default filesystem to apply. - type: string - nodePublishSecretRef: - description: NodePublishSecretRef is a reference to - the secret object containing sensitive information - to pass to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the - secret object contains more than one secret, all - secret references are passed. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: VolumeAttributes stores driver-specific - properties that are passed to the CSI driver. Consult - your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: DownwardAPI represents downward API about - the pod that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' path. - Must be utf-8 encoded. The first item of the - relative path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'EmptyDir represents a temporary directory - that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to - use the node''s default medium. Must be an empty - string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also - applicable for memory medium. The maximum usage - on memory medium EmptyDir would be the minimum value - between the SizeLimit specified here and the sum - of memory limits of all containers in a pod. The - default is nil which means that the limit is undefined. - More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - fc: - description: FC represents a Fibre Channel resource that - is attached to a kubelet's host machine and then exposed - to the pod. - properties: - fsType: - description: 'Filesystem type to mount. Must be a - filesystem type supported by the host operating - system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred - to be "ext4" if unspecified. TODO: how do we prevent - errors in the filesystem from compromising the machine' - type: string - lun: - description: 'Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts.' - type: boolean - targetWWNs: - description: 'Optional: FC target worldwide names - (WWNs)' - items: - type: string - type: array - wwids: - description: 'Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs - and lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: FlexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: Driver is the name of the driver to use - for this volume. - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". The default filesystem depends - on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'Optional: Extra command options if any.' - type: object - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts.' - type: boolean - secretRef: - description: 'Optional: SecretRef is reference to - the secret object containing sensitive information - to pass to the plugin scripts. This may be empty - if no secret object is specified. If the secret - object contains more than one secret, all secrets - are passed to the plugin scripts.' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - required: - - driver - type: object - flocker: - description: Flocker represents a Flocker volume attached - to a kubelet's host machine. This depends on the Flocker - control service being running - properties: - datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated - type: string - datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - partition: - description: 'The partition in the volume that you - want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, - you specify the partition as "1". Similarly, the - volume partition for /dev/sda is "0" (or you can - leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More - info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'GitRepo represents a git repository at a - particular revision. DEPRECATED: GitRepo is deprecated. - To provision a container with a git repo, mount an EmptyDir - into an InitContainer that clones the repo using git, - then mount the EmptyDir into the Pod''s container.' - properties: - directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: Repository URL - type: string - revision: - description: Commit hash for the specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'Glusterfs represents a Glusterfs mount on - the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'Path is the Glusterfs volume path. More - info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'ReadOnly here will force the Glusterfs - volume to be mounted with read-only permissions. - Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'HostPath represents a pre-existing file - or directory on the host machine that is directly exposed - to the container. This is generally used for system - agents or other privileged things that are allowed to - see the host machine. Most containers will NOT need - this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host - directory mounts and who can/can not mount host directories - as read/write.' - properties: - path: - description: 'Path of the directory on the host. If - the path is a symlink, it will follow the link to - the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'Type for HostPath Volume Defaults to - "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'ISCSI represents an ISCSI Disk resource - that is attached to a kubelet''s host machine and then - exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP - authentication - type: boolean - chapAuthSession: - description: whether support iSCSI Session CHAP authentication - type: boolean - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, - new iSCSI interface : - will be created for the connection. - type: string - iqn: - description: Target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). - type: string - lun: - description: iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: iSCSI Target Portal List. The portal - is either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than - default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'Volume''s name. Must be a DNS_LABEL and - unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'NFS represents an NFS mount on the host - that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults - to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address - of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents - a reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host - machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - pdID: - description: ID that identifies Photon Controller - persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: PortworxVolume represents a portworx volume - attached and mounted on kubelets host machine - properties: - fsType: - description: FSType represents the filesystem type - to mount Must be a filesystem type supported by - the host operating system. Ex. "ext4", "xfs". Implicitly - inferred to be "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: VolumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: Items for all in one resources secrets, configmaps, - and downward API - properties: - defaultMode: - description: Mode bits to use on created files by - default. Must be a value between 0 and 0777. Directories - within the path are not affected by this setting. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set. - format: int32 - type: integer - sources: - description: list of volume projections - items: - description: Projection that may be projected along - with other supported volume types - properties: - configMap: - description: information about the configMap - data to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - ConfigMap will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed - keys will be projected into the specified - paths, and unlisted keys will not be present. - If a key is specified which is not present - in the ConfigMap, the volume setup will - error unless it is marked optional. Paths - must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of - the file to map the key to. May - not be an absolute path. May not - contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - downwardAPI: - description: information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a - field of the pod: only annotations, - labels, name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema - the FieldPath is written in - terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field - to select in the specified API - version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file to - be created. Must not be absolute - or contain the ''..'' path. Must - be utf-8 encoded. The first item - of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of - the container: only resources limits - and requests (limits.cpu, limits.memory, - requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: - required for volumes, optional - for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output - format of the exposed resources, - defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - secret: - description: information about the secret data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - Secret will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed - keys will be projected into the specified - paths, and unlisted keys will not be present. - If a key is specified which is not present - in the Secret, the volume setup will error - unless it is marked optional. Paths must - be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of - the file to map the key to. May - not be an absolute path. May not - contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - type: object - serviceAccountToken: - description: information about the serviceAccountToken - data to project - properties: - audience: - description: Audience is the intended audience - of the token. A recipient of a token must - identify itself with an identifier specified - in the audience of the token, and otherwise - should reject the token. The audience - defaults to the identifier of the apiserver. - type: string - expirationSeconds: - description: ExpirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, - the kubelet volume plugin will proactively - rotate the service account token. The - kubelet will start trying to rotate the - token if the token is older than 80 percent - of its time to live or if the token is - older than 24 hours.Defaults to 1 hour - and must be at least 10 minutes. - format: int64 - type: integer - path: - description: Path is the path relative to - the mount point of the file to project - the token into. - type: string - required: - - path - type: object - type: object - type: array - required: - - sources - type: object - quobyte: - description: Quobyte represents a Quobyte mount on the - host that shares a pod's lifetime - properties: - group: - description: Group to map volume access to Default - is no group - type: string - readOnly: - description: ReadOnly here will force the Quobyte - volume to be mounted with read-only permissions. - Defaults to false. - type: boolean - registry: - description: Registry represents a single or multiple - Quobyte Registry services specified as a string - as host:port pair (multiple entries are separated - with commas) which acts as the central registry - for volumes - type: string - tenant: - description: Tenant owning the given Quobyte volume - in the Backend Used with dynamically provisioned - Quobyte volumes, value is set by the plugin - type: string - user: - description: User to map volume access to Defaults - to serivceaccount user - type: string - volume: - description: Volume is a string that references an - already created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'RBD represents a Rados Block Device mount - on the host that shares a pod''s lifetime. More info: - https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'Keyring is the path to key ring for - RBDUser. Default is /etc/ceph/keyring. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'A collection of Ceph monitors. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'The rados pool name. Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'SecretRef is name of the authentication - secret for RBDUser. If provided overrides keyring. - Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: ScaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: The host address of the ScaleIO API Gateway. - type: string - protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef references to the secret for - ScaleIO user and other sensitive information. If - this is not provided, Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - sslEnabled: - description: Flag to enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. - type: string - storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. - type: string - system: - description: The name of the storage system as configured - in ScaleIO. - type: string - volumeName: - description: The name of a volume already created - in the ScaleIO system that is associated with this - volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'Secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be - projected into the volume as a file whose name is - the key and content is the value. If specified, - the listed keys will be projected into the specified - paths, and unlisted keys will not be present. If - a key is specified which is not present in the Secret, - the volume setup will error unless it is marked - optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: Specify whether the Secret or its keys - must be defined - type: boolean - secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: StorageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef specifies the secret to use - for obtaining the StorageOS API credentials. If - not specified, default values will be attempted. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeName: - description: VolumeName is the human-readable name - of the StorageOS volume. Volume names are only - unique within a namespace. - type: string - volumeNamespace: - description: VolumeNamespace specifies the scope of - the volume within StorageOS. If no namespace is - specified then the Pod's namespace will be used. This - allows the Kubernetes name scoping to be mirrored - within StorageOS for tighter integration. Set VolumeName - to any name to override the default behaviour. Set - to "default" if you are not using namespaces within - StorageOS. Namespaces that do not pre-exist within - StorageOS will be created. - type: string - type: object - vsphereVolume: - description: VsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. - type: string - volumePath: - description: Path that identifies vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - required: - - containers - type: object - type: object - racks: - description: A list of the named racks in the datacenter, representing - independent failure domains. The number of racks should match the - replication factor in the keyspaces you plan to create, and the number - of racks cannot easily be changed once a datacenter is deployed. - items: - description: Rack ... - properties: - name: - description: The rack name - minLength: 2 - type: string - nodeAffinityLabels: - additionalProperties: - type: string - description: NodeAffinityLabels to pin the rack, using node affinity - type: object - zone: - description: Deprecated. Use nodeAffinityLabels instead. Zone - name to pin the rack, using node affinity - type: string - required: - - name - type: object - type: array - reaper: - description: 'Deprecated: Reaper''s sidecar mode has too many problems - in Kubernetes for it to usable. In order for it to work reliably, - changes in Reaper would be needed. See https://github.com/thelastpickle/cassandra-reaper/issues/956 - for details. Because those changes were not implemented in Reaper - and because Reaper support was instead added through k8ssandra, this - field will be removed in the 1.8.0 release.' - properties: - enabled: - type: boolean - image: - type: string - imagePullPolicy: - description: PullPolicy describes a policy for if/when to pull a - container image - type: string - resources: - description: Kubernetes resource requests and limits per reaper - container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - type: object - replaceNodes: - description: A list of pod names that need to be replaced. - items: - type: string - type: array - resources: - description: Kubernetes resource requests and limits, per pod - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - rollingRestartRequested: - description: Whether to do a rolling restart at the next opportunity. - The operator will set this back to false once the restart is in progress. - type: boolean - serverImage: - description: 'Cassandra server image name. More info: https://kubernetes.io/docs/concepts/containers/images' - type: string - serverType: - description: 'Server type: "cassandra" or "dse"' - enum: - - cassandra - - dse - type: string - serverVersion: - description: Version string for config builder, used to generate Cassandra - server configuration - pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.0\.\d+) - type: string - serviceAccount: - description: The k8s service account to use for the server pods - type: string - size: - description: Desired number of Cassandra server nodes - format: int32 - minimum: 1 - type: integer - stopped: - description: A stopped CassandraDatacenter will have no running server - pods, like using "stop" with traditional System V init scripts. Other - Kubernetes resources will be left intact, and volumes will re-attach - when the CassandraDatacenter workload is resumed. - type: boolean - storageConfig: - description: Describes the persistent storage request of each server - node - properties: - additionalVolumes: - items: - description: StorageConfig defines additional storage configurations - properties: - mountPath: - description: Mount path into cassandra container - type: string - name: - description: Name of the pvc - pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' - type: string - pvcSpec: - description: Persistent volume claim spec - properties: - accessModes: - description: 'AccessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: This field requires the VolumeSnapshotDataSource - alpha feature gate to be enabled and currently VolumeSnapshot - is the only supported data source. If the provisioner - can support VolumeSnapshot data source, it will create - a new volume and data will be restored to the volume - at the same time. If the provisioner does not support - VolumeSnapshot data source, volume will not be created - and the failure will be reported as an event. In the - future, we plan to support more data source types and - the behavior of the provisioner may change. - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum resources - the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - selector: - description: A label query over volumes to consider for - binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required by the - claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. This is a beta feature. - type: string - volumeName: - description: VolumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - required: - - mountPath - - name - - pvcSpec - type: object - type: array - cassandraDataVolumeClaimSpec: - description: PersistentVolumeClaimSpec describes the common attributes - of storage devices and allows a Source for provider-specific attributes - properties: - accessModes: - description: 'AccessModes contains the desired access modes - the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: This field requires the VolumeSnapshotDataSource - alpha feature gate to be enabled and currently VolumeSnapshot - is the only supported data source. If the provisioner can - support VolumeSnapshot data source, it will create a new volume - and data will be restored to the volume at the same time. - If the provisioner does not support VolumeSnapshot data source, - volume will not be created and the failure will be reported - as an event. In the future, we plan to support more data source - types and the behavior of the provisioner may change. - properties: - apiGroup: - description: APIGroup is the group for the resource being - referenced. If APIGroup is not specified, the specified - Kind must be in the core API group. For any other third-party - types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum resources the - volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. More info: - https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - selector: - description: A label query over volumes to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume is required - by the claim. Value of Filesystem is implied when not included - in claim spec. This is a beta feature. - type: string - volumeName: - description: VolumeName is the binding reference to the PersistentVolume - backing this claim. - type: string - type: object - type: object - superuserSecretName: - description: This secret defines the username and password for the Cassandra - server superuser. If it is omitted, we will generate a secret instead. - type: string - systemLoggerImage: - description: Container image for the log tailing sidecar container. - type: string - systemLoggerResources: - description: Kubernetes resource requests and limits per system logger - container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - tolerations: - description: Tolerations applied to the Cassandra pod. Note that these - cannot be overridden with PodTemplateSpec. - items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . - properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, operator - must be Exists; this combination means to match all values and - all keys. - type: string - operator: - description: Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. Exists - is equivalent to wildcard for value, so that a pod can tolerate - all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time the - toleration (which must be of effect NoExecute, otherwise this - field is ignored) tolerates the taint. By default, it is not - set, which means tolerate the taint forever (do not evict). - Zero and negative values will be treated as 0 (evict immediately) - by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise - just a regular string. - type: string - type: object - type: array - users: - description: Cassandra users to bootstrap - items: - properties: - secretName: - type: string - superuser: - type: boolean - required: - - secretName - - superuser - type: object - type: array - required: - - clusterName - - serverType - - serverVersion - - size - - storageConfig - type: object - status: - description: CassandraDatacenterStatus defines the observed state of CassandraDatacenter - properties: - cassandraOperatorProgress: - description: Last known progress state of the Cassandra Operator - type: string - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - message - - reason - - status - - type - type: object - type: array - lastRollingRestart: - format: date-time - type: string - lastServerNodeStarted: - description: The timestamp when the operator last started a Server node - with the management API - format: date-time - type: string - nodeReplacements: - items: - type: string - type: array - nodeStatuses: - additionalProperties: - properties: - hostID: - type: string - type: object - type: object - observedGeneration: - format: int64 - type: integer - quietPeriod: - format: date-time - type: string - superUserUpserted: - description: Deprecated. Use usersUpserted instead. The timestamp at - which CQL superuser credentials were last upserted to the management - API - format: date-time - type: string - usersUpserted: - description: The timestamp at which managed cassandra users' credentials - were last upserted to the management API - format: date-time - type: string - type: object - type: object - x-kubernetes-preserve-unknown-fields: true - version: v1beta1 - versions: - - name: v1beta1 - served: true - storage: true diff --git a/charts/cass-operator-chart/templates/deployment.yaml b/charts/cass-operator-chart/templates/deployment.yaml deleted file mode 100644 index a950e2a0..00000000 --- a/charts/cass-operator-chart/templates/deployment.yaml +++ /dev/null @@ -1,105 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Values.deploymentName }} -spec: - replicas: {{ .Values.deploymentReplicas }} - selector: - matchLabels: - name: cass-operator - template: - metadata: - labels: - name: cass-operator - spec: - serviceAccountName: {{ .Values.serviceAccountName }} - {{- $imagePullSecrets := list -}} - {{- if .Values.imagePullSecret }} - {{- $imagePullSecrets = append $imagePullSecrets .Values.imagePullSecret }} - {{- end }} - {{- if .Values.registryUsername }} - {{- $imagePullSecrets = append $imagePullSecrets "cass-operator-registry-override-regcred" }} - {{- end }} - {{- if empty $imagePullSecrets | not }} - imagePullSecrets: - {{- range $imagePullSecrets }} - - name: {{ . | quote }} - {{- end }} - {{- end }} - volumes: - - name: tmpconfig-volume - emptyDir: - medium: "Memory" - - name: cass-operator-certs-volume - secret: - secretName: cass-operator-webhook-config - containers: - - name: cass-operator - {{- if .Values.image }} - image: {{ .Values.image }} - {{- else if .Values.registryName }} - image: {{ printf "%s/%s" .Values.registryName .Values.defaultImage }} - {{- else }} - image: {{ .Values.defaultImage }} - {{- end }} - imagePullPolicy: {{ .Values.imagePullPolicy }} - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cass-operator-certs-volume - readOnly: false - - mountPath: /tmp/ - name: tmpconfig-volume - readOnly: false - securityContext: - runAsUser: 65534 - runAsGroup: 65534 - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - livenessProbe: - exec: - command: - - pgrep - - ".*operator" - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - failureThreshold: 3 - readinessProbe: - exec: - command: - - stat - - "/tmp/operator-sdk-ready" - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - failureThreshold: 1 - env: - {{- if .Values.vmwarePSPEnabled }} - - name: ENABLE_VMWARE_PSP - value: "true" - {{- end }} - {{- if .Values.registryName }} - - name: DEFAULT_CONTAINER_REGISTRY_OVERRIDE - value: {{ .Values.registryName }} - {{- end }} - {{- if .Values.registryUsername }} - - name: DEFAULT_CONTAINER_REGISTRY_OVERRIDE_PULL_SECRETS - value: cass-operator-registry-override-regcred - {{- end }} - {{- if .Values.clusterWideInstall }} - - name: WATCH_NAMESPACE - value: "" - {{- else }} - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "cass-operator" - - name: SKIP_VALIDATING_WEBHOOK - value: "FALSE" diff --git a/charts/cass-operator-chart/templates/registry-secret.yaml b/charts/cass-operator-chart/templates/registry-secret.yaml deleted file mode 100644 index ca440dd2..00000000 --- a/charts/cass-operator-chart/templates/registry-secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{ if .Values.registryUsername }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/dockerconfigjson -metadata: - name: cass-operator-registry-override-regcred -data: - .dockerconfigjson: {{ printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.registryName (printf "%s:%s" .Values.registryUsername .Values.registryPassword | b64enc) | b64enc }} -{{- end }} diff --git a/charts/cass-operator-chart/templates/role.yaml b/charts/cass-operator-chart/templates/role.yaml deleted file mode 100644 index afe12c91..00000000 --- a/charts/cass-operator-chart/templates/role.yaml +++ /dev/null @@ -1,171 +0,0 @@ -{{- if .Values.clusterWideInstall }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Values.roleName }} -rules: -- apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - verbs: - - '*' -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get -- apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - '*' -- apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create -- apiGroups: - - apps - resourceNames: - - cass-operator - resources: - - deployments/finalizers - verbs: - - update -- apiGroups: - - datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - '*' -- apiGroups: - - cassandra.datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - batch - resources: - - '*' - verbs: - - '*' -{{- if .Values.vmwarePSPEnabled }} -- apiGroups: - - "networking.k8s.io" - resources: - - networkpolicies - verbs: - - get - - create - - update - - patch - - delete - - list -{{- end }} -{{- else }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: {{ .Values.roleName }} -rules: -- apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - verbs: - - '*' -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get -- apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - '*' -- apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create -- apiGroups: - - apps - resourceNames: - - cass-operator - resources: - - deployments/finalizers - verbs: - - update -- apiGroups: - - datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - '*' -- apiGroups: - - cassandra.datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - batch - resources: - - '*' - verbs: - - '*' -{{- if .Values.vmwarePSPEnabled }} -- apiGroups: - - "networking.k8s.io" - resources: - - networkpolicies - verbs: - - get - - create - - update - - patch - - delete - - list -{{- end }} -{{- end }} diff --git a/charts/cass-operator-chart/templates/serviceaccount.yaml b/charts/cass-operator-chart/templates/serviceaccount.yaml deleted file mode 100644 index aa7977de..00000000 --- a/charts/cass-operator-chart/templates/serviceaccount.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.serviceAccountName }} diff --git a/charts/cass-operator-chart/templates/validatingwebhookconfiguration.yaml b/charts/cass-operator-chart/templates/validatingwebhookconfiguration.yaml deleted file mode 100644 index 5b43c5e8..00000000 --- a/charts/cass-operator-chart/templates/validatingwebhookconfiguration.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -metadata: - name: "cassandradatacenter-webhook-registration" -webhooks: -- name: "cassandradatacenter-webhook.cassandra.datastax.com" - rules: - - apiGroups: ["cassandra.datastax.com"] - apiVersions: ["v1beta1"] - operations: ["CREATE", "UPDATE"] - resources: ["cassandradatacenters"] - scope: "*" - clientConfig: - service: - name: "cassandradatacenter-webhook-service" - namespace: {{ .Release.Namespace }} - path: /validate-cassandra-datastax-com-v1beta1-cassandradatacenter - admissionReviewVersions: ["v1beta1"] - timeoutSeconds: 10 - failurePolicy: "Ignore" - matchPolicy: "Equivalent" - sideEffects: None diff --git a/charts/cass-operator-chart/templates/webhook-cr.yaml b/charts/cass-operator-chart/templates/webhook-cr.yaml deleted file mode 100644 index 18ec3a37..00000000 --- a/charts/cass-operator-chart/templates/webhook-cr.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: {{ .Values.webhookClusterRoleName }} -rules: -- apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - verbs: - - create - - get - - update - resourceNames: - - "cassandradatacenter-webhook-registration" diff --git a/charts/cass-operator-chart/templates/webhook-crb.yaml b/charts/cass-operator-chart/templates/webhook-crb.yaml deleted file mode 100644 index fa8f6b9e..00000000 --- a/charts/cass-operator-chart/templates/webhook-crb.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.webhookClusterRoleBindingName }} -subjects: -- kind: ServiceAccount - name: {{ .Values.serviceAccountName }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.webhookClusterRoleName }} - apiGroup: rbac.authorization.k8s.io diff --git a/charts/cass-operator-chart/templates/webhook-secret.yaml b/charts/cass-operator-chart/templates/webhook-secret.yaml deleted file mode 100644 index 3e01528e..00000000 --- a/charts/cass-operator-chart/templates/webhook-secret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: cass-operator-webhook-config -data: - tls.crt: "" - tls.key: "" diff --git a/charts/cass-operator-chart/templates/webhook-service.yaml b/charts/cass-operator-chart/templates/webhook-service.yaml deleted file mode 100644 index 49b1e61a..00000000 --- a/charts/cass-operator-chart/templates/webhook-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: cassandradatacenter-webhook-service - labels: - name: cass-operator-webhook -spec: - ports: - - port: 443 - targetPort: 8443 - selector: - name: cass-operator diff --git a/charts/cass-operator-chart/values.yaml b/charts/cass-operator-chart/values.yaml deleted file mode 100644 index 455c07a2..00000000 --- a/charts/cass-operator-chart/values.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Default values -clusterWideInstall: false -serviceAccountName: cass-operator -clusterRoleName: cass-operator-cr -clusterRoleBindingName: cass-operator-crb -roleName: cass-operator -roleBindingName: cass-operator -webhookClusterRoleName: cass-operator-webhook -webhookClusterRoleBindingName: cass-operator-webhook -deploymentName: cass-operator -deploymentReplicas: 1 -defaultImage: "k8ssandra/cass-operator:v1.7.1" -imagePullPolicy: IfNotPresent -imagePullSecret: "" diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 00000000..52d86618 --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 00000000..bebea5a5 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000..90d7c313 --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/config/crd/bases/cassandra.datastax.com_cassandradatacenters.yaml b/config/crd/bases/cassandra.datastax.com_cassandradatacenters.yaml new file mode 100644 index 00000000..7aca10b4 --- /dev/null +++ b/config/crd/bases/cassandra.datastax.com_cassandradatacenters.yaml @@ -0,0 +1,7083 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: cassandradatacenters.cassandra.datastax.com +spec: + group: cassandra.datastax.com + names: + kind: CassandraDatacenter + listKind: CassandraDatacenterList + plural: cassandradatacenters + shortNames: + - cassdc + - cassdcs + singular: cassandradatacenter + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: CassandraDatacenter is the Schema for the cassandradatacenters + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CassandraDatacenterSpec defines the desired state of a CassandraDatacenter + properties: + additionalSeeds: + items: + type: string + type: array + additionalServiceConfig: + description: AdditionalServiceConfig allows to define additional parameters + that are included in the created Services. Note, user can override + values set by cass-operator and doing so could break cass-operator + functionality. Avoid label "cass-operator" and anything that starts + with "cassandra.datastax.com/" + properties: + additionalSeedService: + description: ServiceConfigAdditions exposes additional options + for each service + properties: + additionalAnnotations: + additionalProperties: + type: string + type: object + additionalLabels: + additionalProperties: + type: string + type: object + type: object + allpodsService: + description: ServiceConfigAdditions exposes additional options + for each service + properties: + additionalAnnotations: + additionalProperties: + type: string + type: object + additionalLabels: + additionalProperties: + type: string + type: object + type: object + dcService: + description: ServiceConfigAdditions exposes additional options + for each service + properties: + additionalAnnotations: + additionalProperties: + type: string + type: object + additionalLabels: + additionalProperties: + type: string + type: object + type: object + nodePortService: + description: ServiceConfigAdditions exposes additional options + for each service + properties: + additionalAnnotations: + additionalProperties: + type: string + type: object + additionalLabels: + additionalProperties: + type: string + type: object + type: object + seedService: + description: ServiceConfigAdditions exposes additional options + for each service + properties: + additionalAnnotations: + additionalProperties: + type: string + type: object + additionalLabels: + additionalProperties: + type: string + type: object + type: object + type: object + allowMultipleNodesPerWorker: + description: Turning this option on allows multiple server pods to + be created on a k8s worker node. By default the operator creates + just one server pod per k8s worker node using k8s podAntiAffinity + and requiredDuringSchedulingIgnoredDuringExecution. + type: boolean + canaryUpgrade: + description: Indicates that configuration and container image changes + should only be pushed to the first rack of the datacenter + type: boolean + canaryUpgradeCount: + description: The number of nodes that will be updated when CanaryUpgrade + is true. Note that the value is either 0 or greater than the rack + size, then all nodes in the rack will get updated. + format: int32 + type: integer + clusterName: + description: The name by which CQL clients and instances will know + the cluster. If the same cluster name is shared by multiple Datacenters + in the same Kubernetes namespace, they will join together in a multi-datacenter + cluster. + minLength: 2 + type: string + config: + description: Config for the server, in YAML format + format: byte + type: string + x-kubernetes-preserve-unknown-fields: true + configBuilderImage: + description: Container image for the config builder init container. + type: string + configBuilderResources: + description: Kubernetes resource requests and limits per server config + initialization container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + configSecret: + description: "ConfigSecret is the name of a secret that contains configuration + for Cassandra. The secret is expected to have a property named config + whose value should be a JSON formatted string that should look like + this: \n config: |- { \"cassandra-yaml\": { \"read_request_timeout_in_ms\": + 10000 }, \"jmv-options\": { \"max_heap_size\": + 1024M } } \n ConfigSecret is mutually exclusive with + Config. ConfigSecret takes precedence and will be used exclusively + if both properties are set. The operator sets a watch such that + an update to the secret will trigger an update of the StatefulSets." + type: string + disableSystemLoggerSidecar: + description: Configuration for disabling the simple log tailing sidecar + container. Our default is to have it enabled. + type: boolean + dockerImageRunsAsCassandra: + description: Does the Server Docker image run as the Cassandra user? + type: boolean + dseWorkloads: + properties: + analyticsEnabled: + type: boolean + graphEnabled: + type: boolean + searchEnabled: + type: boolean + type: object + forceUpgradeRacks: + description: Rack names in this list are set to the latest StatefulSet + configuration even if Cassandra nodes are down. Use this to recover + from an upgrade that couldn't roll out. + items: + type: string + type: array + managementApiAuth: + description: Config for the Management API certificates + properties: + insecure: + type: object + manual: + properties: + clientSecretName: + type: string + serverSecretName: + type: string + skipSecretValidation: + type: boolean + required: + - clientSecretName + - serverSecretName + type: object + type: object + networking: + properties: + hostNetwork: + type: boolean + nodePort: + properties: + internode: + type: integer + internodeSSL: + type: integer + native: + type: integer + nativeSSL: + type: integer + type: object + type: object + nodeAffinityLabels: + additionalProperties: + type: string + description: NodeAffinityLabels to pin the Datacenter, using node + affinity + type: object + nodeSelector: + additionalProperties: + type: string + description: 'A map of label keys and values to restrict Cassandra + node scheduling to k8s workers with matchiing labels. More info: + https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector' + type: object + podTemplateSpec: + description: PodTemplate provides customisation options (labels, annotations, + affinity rules, resource requests, and so on) for the cassandra + pods + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + activeDeadlineSeconds: + description: Optional duration in seconds the pod may be active + on the node relative to StartTime before the system will + actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: List of containers belonging to the pod. Containers + cannot currently be added or removed. There must be at least + one container in a Pod. Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the + reference in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a double $$, + ie: $$(VAR_NAME). Escaped references will never be + expanded, regardless of whether the variable exists + or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used if + this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If + a variable cannot be resolved, the reference in the + input string will be unchanged. The $(VAR_NAME) syntax + can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in + the container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is + starting. When a key exists in multiple sources, the + value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will + take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, + IfNotPresent. Defaults to Always if :latest tag is + specified, or IfNotPresent otherwise. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should + take in response to container lifecycle events. Cannot + be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, + the container is terminated and restarted according + to its restart policy. Other management of the + container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before + a container is terminated due to an API request + or management event such as liveness/startup probe + failure, preemption, resource contention, etc. + The handler is not called if the container crashes + or exits. The reason for termination is passed + to the handler. The Pod''s termination grace period + countdown begins before the PreStop hooked is + executed. Regardless of the outcome of the handler, + the container will eventually terminate within + the Pod''s termination grace period. Other management + of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but + is primarily informational. Not specifying a port + here DOES NOT prevent that port from being exposed. + Any port which is listening on the default "0.0.0.0" + address inside a container will be accessible from + the network. Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, + 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, + this must match ContainerPort. Most containers + do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in + a pod must have a unique name. Name for the + port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if + the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is + omitted for a container, it defaults to Limits + if that is explicitly specified, otherwise to + an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + securityContext: + description: 'Security options the pod should run with. + More info: https://kubernetes.io/docs/concepts/policy/security-context/ + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges than + its parent process. This bool directly controls + if the no_new_privs flag will be set on the container + process. AllowPrivilegeEscalation is true always + when the container is: 1) run as Privileged 2) + has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default is + DefaultProcMount which uses the container runtime + defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to + be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the + container process. Uses runtime default if unset. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will + validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no + such validation will be performed. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified + in image metadata if unspecified. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + the container. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided at + both the pod & container level, the container + options override the pod options. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative + to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: + \n Localhost - a profile defined in a file + on the node should be used. RuntimeDefault + - the container runtime default profile should + be used. Unconfined - no profile should be + applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the + GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run + the entrypoint of the container process. Defaults + to the user specified in image metadata if + unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has + successfully initialized. If specified, no other probes + are executed until this completes successfully. If + this probe fails, the Pod will be restarted, just + as if the livenessProbe failed. This can be used to + provide different probe parameters at the beginning + of a Pod''s lifecycle, when it might take a long time + to load data or warm a cache, than during steady-state + operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will + always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce + is set to true, stdin is opened on container start, + is empty until the first client attaches to stdin, + and then remains open and accepts data until the client + disconnects, at which time stdin is closed and remains + closed until the container is restarted. If this flag + is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written + is mounted into the container''s filesystem. Message + written is intended to be brief final status, such + as an assertion failure message. Will be truncated + by the node if greater than 4096 bytes. The total + message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot + be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last + chunk of container log output if the termination message + file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, + whichever is smaller. Defaults to File. Cannot be + updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: Path within the container at which + the volume should be mounted. Must not contain + ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and + the other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to + false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. Defaults + to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment + variable references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which + might be configured in the container image. Cannot + be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Specifies the DNS parameters of a pod. Parameters + specified here will be merged to the generated DNS configuration + based on DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. This + will be appended to the base nameservers generated from + DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This will + be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options + given in Options will override those that appear in + the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name + lookup. This will be appended to the base search paths + generated from DNSPolicy. Duplicated search paths will + be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: Set DNS policy for the pod. Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', + 'Default' or 'None'. DNS parameters given in DNSConfig will + be merged with the policy selected with DNSPolicy. To have + DNS options set along with hostNetwork, you have to specify + DNS policy explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: 'EnableServiceLinks indicates whether information + about services should be injected into pod''s environment + variables, matching the syntax of Docker links. Optional: + Defaults to true.' + type: boolean + ephemeralContainers: + description: List of ephemeral containers run in this pod. + Ephemeral containers may be run in an existing pod to perform + user-initiated actions such as debugging. This list cannot + be specified when creating a pod, and it cannot be modified + by updating the pod spec. In order to add an ephemeral container + to an existing pod, use the pod's ephemeralcontainers subresource. + This field is alpha-level and is only honored by servers + that enable the EphemeralContainers feature. + items: + description: An EphemeralContainer is a container that may + be added temporarily to an existing pod for user-initiated + activities such as debugging. Ephemeral containers have + no resource or scheduling guarantees, and they will not + be restarted when they exit or when a pod is removed or + restarted. If an ephemeral container causes a pod to exceed + its resource allocation, the pod may be evicted. Ephemeral + containers may not be added by directly updating the pod + spec. They must be added via the pod's ephemeralcontainers + subresource, and they will appear in the pod spec once + added. This is an alpha feature enabled by the EphemeralContainers + feature flag. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the + reference in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a double $$, + ie: $$(VAR_NAME). Escaped references will never be + expanded, regardless of whether the variable exists + or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used if + this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If + a variable cannot be resolved, the reference in the + input string will be unchanged. The $(VAR_NAME) syntax + can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in + the container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is + starting. When a key exists in multiple sources, the + value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will + take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, + IfNotPresent. Defaults to Always if :latest tag is + specified, or IfNotPresent otherwise. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, + the container is terminated and restarted according + to its restart policy. Other management of the + container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before + a container is terminated due to an API request + or management event such as liveness/startup probe + failure, preemption, resource contention, etc. + The handler is not called if the container crashes + or exits. The reason for termination is passed + to the handler. The Pod''s termination grace period + countdown begins before the PreStop hooked is + executed. Regardless of the outcome of the handler, + the container will eventually terminate within + the Pod''s termination grace period. Other management + of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified + as a DNS_LABEL. This name must be unique among all + containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, + 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, + this must match ContainerPort. Most containers + do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in + a pod must have a unique name. Name for the + port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral + containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is + omitted for a container, it defaults to Limits + if that is explicitly specified, otherwise to + an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + securityContext: + description: SecurityContext is not allowed for ephemeral + containers. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges than + its parent process. This bool directly controls + if the no_new_privs flag will be set on the container + process. AllowPrivilegeEscalation is true always + when the container is: 1) run as Privileged 2) + has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default is + DefaultProcMount which uses the container runtime + defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to + be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the + container process. Uses runtime default if unset. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will + validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no + such validation will be performed. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified + in image metadata if unspecified. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + the container. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided at + both the pod & container level, the container + options override the pod options. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative + to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: + \n Localhost - a profile defined in a file + on the node should be used. RuntimeDefault + - the container runtime default profile should + be used. Unconfined - no profile should be + applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the + GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run + the entrypoint of the container process. Defaults + to the user specified in image metadata if + unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will + always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce + is set to true, stdin is opened on container start, + is empty until the first client attaches to stdin, + and then remains open and accepts data until the client + disconnects, at which time stdin is closed and remains + closed until the container is restarted. If this flag + is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: If set, the name of the container from + PodSpec that this ephemeral container targets. The + ephemeral container will be run in the namespaces + (IPC, PID, etc) of this container. If not set then + the ephemeral container is run in whatever namespaces + are shared for the pod. Note that the container runtime + must support this feature. + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written + is mounted into the container''s filesystem. Message + written is intended to be brief final status, such + as an assertion failure message. Will be truncated + by the node if greater than 4096 bytes. The total + message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot + be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last + chunk of container log output if the termination message + file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, + whichever is smaller. Defaults to File. Cannot be + updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: Path within the container at which + the volume should be mounted. Must not contain + ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and + the other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to + false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. Defaults + to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment + variable references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which + might be configured in the container image. Cannot + be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: HostAliases is an optional list of hosts and + IPs that will be injected into the pod's hosts file if specified. + This is only valid for non-hostNetwork pods. + items: + description: HostAlias holds the mapping between IP and + hostnames that will be injected as an entry in the pod's + hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: 'Use the host''s ipc namespace. Optional: Default + to false.' + type: boolean + hostNetwork: + description: Host networking requested for this pod. Use the + host's network namespace. If this option is set, the ports + that will be used must be specified. Default to false. + type: boolean + hostPID: + description: 'Use the host''s pid namespace. Optional: Default + to false.' + type: boolean + hostname: + description: Specifies the hostname of the Pod If not specified, + the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: 'ImagePullSecrets is an optional list of references + to secrets in the same namespace to use for pulling any + of the images used by this PodSpec. If specified, these + secrets will be passed to individual puller implementations + for them to use. For example, in the case of docker, only + DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same + namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + initContainers: + description: 'List of initialization containers belonging + to the pod. Init containers are executed in order prior + to containers being started. If any init container fails, + the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or + normal container must be unique among all containers. Init + containers may not have Lifecycle actions, Readiness probes, + Liveness probes, or Startup probes. The resourceRequirements + of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, + and then using the max of of that value or the sum of the + normal containers. Limits are applied to init containers + in a similar fashion. Init containers cannot currently be + added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the + reference in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a double $$, + ie: $$(VAR_NAME). Escaped references will never be + expanded, regardless of whether the variable exists + or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used if + this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If + a variable cannot be resolved, the reference in the + input string will be unchanged. The $(VAR_NAME) syntax + can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in + the container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. + The $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is + starting. When a key exists in multiple sources, the + value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will + take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, + IfNotPresent. Defaults to Always if :latest tag is + specified, or IfNotPresent otherwise. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should + take in response to container lifecycle events. Cannot + be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, + the container is terminated and restarted according + to its restart policy. Other management of the + container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before + a container is terminated due to an API request + or management event such as liveness/startup probe + failure, preemption, resource contention, etc. + The handler is not called if the container crashes + or exits. The reason for termination is passed + to the handler. The Pod''s termination grace period + countdown begins before the PreStop hooked is + executed. Regardless of the outcome of the handler, + the container will eventually terminate within + the Pod''s termination grace period. Other management + of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but + is primarily informational. Not specifying a port + here DOES NOT prevent that port from being exposed. + Any port which is listening on the default "0.0.0.0" + address inside a container will be accessible from + the network. Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, + 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, + this must match ContainerPort. Most containers + do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in + a pod must have a unique name. Name for the + port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if + the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is + omitted for a container, it defaults to Limits + if that is explicitly specified, otherwise to + an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + securityContext: + description: 'Security options the pod should run with. + More info: https://kubernetes.io/docs/concepts/policy/security-context/ + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges than + its parent process. This bool directly controls + if the no_new_privs flag will be set on the container + process. AllowPrivilegeEscalation is true always + when the container is: 1) run as Privileged 2) + has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default is + DefaultProcMount which uses the container runtime + defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to + be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the + container process. Uses runtime default if unset. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will + validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no + such validation will be performed. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified + in image metadata if unspecified. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in + SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + the container. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided at + both the pod & container level, the container + options override the pod options. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative + to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: + \n Localhost - a profile defined in a file + on the node should be used. RuntimeDefault + - the container runtime default profile should + be used. Unconfined - no profile should be + applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the + GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run + the entrypoint of the container process. Defaults + to the user specified in image metadata if + unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has + successfully initialized. If specified, no other probes + are executed until this completes successfully. If + this probe fails, the Pod will be restarted, just + as if the livenessProbe failed. This can be used to + provide different probe parameters at the beginning + of a Pod''s lifecycle, when it might take a long time + to load data or warm a cache, than during steady-state + operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: One and only one of the following should + be specified. Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the + probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the + probe. Default to 10 seconds. Minimum value is + 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the + probe to be considered successful after having + failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action involving + a TCP port. TCP hooks not yet supported TODO: + implement a realistic TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + description: 'Number of seconds after which the + probe times out. Defaults to 1 second. Minimum + value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will + always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce + is set to true, stdin is opened on container start, + is empty until the first client attaches to stdin, + and then remains open and accepts data until the client + disconnects, at which time stdin is closed and remains + closed until the container is restarted. If this flag + is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written + is mounted into the container''s filesystem. Message + written is intended to be brief final status, such + as an assertion failure message. Will be truncated + by the node if greater than 4096 bytes. The total + message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot + be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last + chunk of container log output if the termination message + file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, + whichever is smaller. Defaults to File. Cannot be + updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: Path within the container at which + the volume should be mounted. Must not contain + ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and + the other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to + false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. Defaults + to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment + variable references $(VAR_NAME) are expanded + using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which + might be configured in the container image. Cannot + be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: NodeName is a request to schedule this pod onto + a specific node. If it is non-empty, the scheduler simply + schedules this pod onto that node, assuming that it fits + resource requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be true + for the pod to fit on a node. Selector which must match + a node''s labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Overhead represents the resource overhead associated + with running a pod for a given RuntimeClass. This field + will be autopopulated at admission time by the RuntimeClass + admission controller. If the RuntimeClass admission controller + is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create + requests which have the overhead already set. If RuntimeClass + is configured and selected in the PodSpec, Overhead will + be set to the value defined in the corresponding RuntimeClass, + otherwise it will remain unset and treated as zero. More + info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md + This field is alpha-level as of Kubernetes v1.16, and is + only honored by servers that enable the PodOverhead feature.' + type: object + preemptionPolicy: + description: PreemptionPolicy is the Policy for preempting + pods with lower priority. One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. This field is + beta-level, gated by the NonPreemptingPriority feature-gate. + type: string + priority: + description: The priority value. Various system components + use this field to find the priority of the pod. When Priority + Admission Controller is enabled, it prevents users from + setting this field. The admission controller populates this + field from PriorityClassName. The higher the value, the + higher the priority. + format: int32 + type: integer + priorityClassName: + description: If specified, indicates the pod's priority. "system-node-critical" + and "system-cluster-critical" are two special keywords which + indicate the highest priorities with the former being the + highest priority. Any other name must be defined by creating + a PriorityClass object with that name. If not specified, + the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: 'If specified, all readiness gates will be evaluated + for pod readiness. A pod is ready when all its containers + are ready AND all conditions specified in the readiness + gates have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md' + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + description: 'Restart policy for all containers within the + pod. One of Always, OnFailure, Never. Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' + type: string + runtimeClassName: + description: 'RuntimeClassName refers to a RuntimeClass object + in the node.k8s.io group, which should be used to run this + pod. If no RuntimeClass resource matches the named class, + the pod will not be run. If unset or empty, the "legacy" + RuntimeClass will be used, which is an implicit class with + an empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md + This is a beta feature as of Kubernetes v1.14.' + type: string + schedulerName: + description: If specified, the pod will be dispatched by specified + scheduler. If not specified, the pod will be dispatched + by default scheduler. + type: string + securityContext: + description: 'SecurityContext holds pod-level security attributes + and common container settings. Optional: Defaults to empty. See + type description for default values of each field.' + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume to + be owned by the pod: \n 1. The owning GID will be the + FSGroup 2. The setgid bit is set (new files created + in the volume will be owned by FSGroup) 3. The permission + bits are OR'd with rw-rw---- \n If unset, the Kubelet + will not modify the ownership and permissions of any + volume." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of + changing ownership and permission of the volume before + being exposed inside Pod. This field will only apply + to volume types which support fsGroup based ownership(and + permissions). It will have no effect on ephemeral volume + types such as: secret, configmaps and emptydir. Valid + values are "OnRootMismatch" and "Always". If not specified, + "Always" is used.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if it + does. If unset or false, no such validation will be + performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all + containers. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers + in this pod. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. The + profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's + configured seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n Localhost + - a profile defined in a file on the node should + be used. RuntimeDefault - the container runtime + default profile should be used. Unconfined - no + profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process + run in each container, in addition to the container's + primary GID. If unspecified, no groups will be added + to any container. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls (by + the container runtime) might fail to launch. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options within a + container's SecurityContext will be used. If set in + both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + serviceAccount: + description: 'DeprecatedServiceAccount is a depreciated alias + for ServiceAccountName. Deprecated: Use serviceAccountName + instead.' + type: string + serviceAccountName: + description: 'ServiceAccountName is the name of the ServiceAccount + to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' + type: string + setHostnameAsFQDN: + description: If true the pod's hostname will be configured + as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the + hostname field of the kernel (the nodename field of struct + utsname). In Windows containers, this means setting the + registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters + to FQDN. If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: 'Share a single process namespace between all + of the containers in a pod. When this is set containers + will be able to view and signal processes from other containers + in the same pod, and the first process in each container + will not be assigned PID 1. HostPID and ShareProcessNamespace + cannot both be set. Optional: Default to false.' + type: boolean + subdomain: + description: If specified, the fully qualified Pod hostname + will be "...svc.". If not specified, the pod will not have a domainname + at all. + type: string + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates + delete immediately. If this value is nil, the default grace + period will be used instead. The grace period is the duration + in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are + forcibly halted with a kill signal. Set this value longer + than the expected cleanup time for your process. Defaults + to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: TopologySpreadConstraints describes how a group + of pods ought to spread across topology domains. Scheduler + will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching + pods. Pods that match this label selector are counted + to determine the number of pods in their corresponding + topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + maxSkew: + description: 'MaxSkew describes the degree to which + pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the + number of matching pods in the target topology and + the global minimum. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 1/1/0: | zone1 | zone2 | zone3 | | P | P | | + - if MaxSkew is 1, incoming pod can only be scheduled + to zone3 to become 1/1/1; scheduling it onto zone1(zone2) + would make the ActualSkew(2-0) on zone1(zone2) violate + MaxSkew(1). - if MaxSkew is 2, incoming pod can be + scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies + that satisfy it. It''s a required field. Default value + is 1 and 0 is not allowed.' + format: int32 + type: integer + topologyKey: + description: TopologyKey is the key of node labels. + Nodes that have a label with this key and identical + values are considered to be in the same topology. + We consider each as a "bucket", and try + to put balanced number of pods into each bucket. It's + a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal + with a pod if it doesn''t satisfy the spread constraint. + - DoNotSchedule (default) tells the scheduler not + to schedule it. - ScheduleAnyway tells the scheduler + to schedule the pod in any location, but giving + higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" + for an incoming pod if and only if every possible + node assigment for that pod would violate "MaxSkew" + on some topology. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P + | P | P | If WhenUnsatisfiable is set to DoNotSchedule, + incoming pod can only be scheduled to zone2(zone3) + to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) + satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make + it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: 'List of volumes that can be mounted by containers + belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'The partition in the volume that you + want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the + volume partition for /dev/sda is "0" (or you can + leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set the + ReadOnly property in VolumeMounts to "true". If + omitted, the default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk resource + in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read Only, + Read Write.' + type: string + diskName: + description: The Name of the data disk in the blob + storage + type: string + diskURI: + description: The URI the data disk in the blob storage + type: string + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'Expected values Shared: multiple blob + disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed + data disk (only in managed availability set). + defaults to shared' + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains Azure + Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path to + key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference to + the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must be + a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object + containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for + mode bits. Defaults to 0644. Directories within + the path are not affected by this setting. This + might be in conflict with other options that affect + the file mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair + in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to + set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file + to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: Driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", + "xfs", "ntfs". If not provided, the empty value + is passed to the associated CSI driver which will + determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should + back this directory. The default is "" which means + to use the node''s default medium. Must be an + empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage required + for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage + on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and + the sum of memory limits of all containers in + a pod. The default is nil which means that the + limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "Ephemeral represents a volume that is + handled by a cluster storage driver (Alpha feature). + The volume's lifecycle is tied to the pod that defines + it - it will be created before the pod starts, and + deleted when the pod is removed. \n Use this if: a) + the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or + capacity tracking are needed, c) the storage driver + is specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + readOnly: + description: Specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'AccessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + * An existing custom resource that implements + data population (Alpha) In order to use + custom resource types that implement data + population, the AnyVolumeDataSource feature + gate must be enabled. If the provisioner + or an external controller can support + the specified data source, it will create + a new volume based on the contents of + the specified data source.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum + resources the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + selector: + description: A label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: VolumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: FC represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must be + a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide names + (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: Driver is the name of the driver to + use for this volume. + type: string + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default + filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options if + any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference to + the secret object containing sensitive information + to pass to the plugin scripts. This may be empty + if no secret object is specified. If the secret + object contains more than one secret, all secrets + are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique + identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'The partition in the volume that you + want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the + volume partition for /dev/sda is "0" (or you can + leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: Target directory name. Must not contain + or start with '..'. If '.' is supplied, the volume + directory will be the git repository. Otherwise, + if specified, the volume will contain the git + repository in the subdirectory with the given + name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint name + that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'Path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery CHAP + authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP + authentication + type: boolean + fsType: + description: 'Filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If initiatorName + is specified with iscsiInterface simultaneously, + new iSCSI interface : + will be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses an iSCSI + transport. Defaults to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal + is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and + 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and initiator + authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal is + either an IP or ip_addr:port if the port is other + than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: Mode bits used to set permissions on + created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. Directories within the path are not affected + by this setting. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + configMap: + description: information about the configMap + data to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the + volume as a file whose name is the key + and content is the value. If specified, + the listed keys will be projected into + the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the ConfigMap, + the volume setup will error unless it + is marked optional. Paths must be relative + and may not contain the '..' path or + start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits + used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of + the file to map the key to. May + not be an absolute path. May not + contain the path element '..'. + May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret + data to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and + content is the value. If specified, + the listed keys will be projected into + the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the Secret, + the volume setup will error unless it + is marked optional. Paths must be relative + and may not contain the '..' path or + start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits + used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of + the file to map the key to. May + not be an absolute path. May not + contain the path element '..'. + May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: Quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: Group to map volume access to Default + is no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: Registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: Tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: User to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: Volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'The rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is + "xfs". + type: string + gateway: + description: The host address of the ScaleIO API + Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection + Domain for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for a + volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: The name of the storage system as configured + in ScaleIO. + type: string + volumeName: + description: The name of a volume already created + in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for + mode bits. Defaults to 0644. Directories within + the path are not affected by this setting. This + might be in conflict with other options that affect + the file mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair + in the Data field of the referenced Secret will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to + set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file + to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its keys + must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s namespace + to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must be a + filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management (SPBM) + profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management (SPBM) + profile name. + type: string + volumePath: + description: Path that identifies vSphere volume + vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + racks: + description: A list of the named racks in the datacenter, representing + independent failure domains. The number of racks should match the + replication factor in the keyspaces you plan to create, and the + number of racks cannot easily be changed once a datacenter is deployed. + items: + description: Rack ... + properties: + name: + description: The rack name + minLength: 2 + type: string + nodeAffinityLabels: + additionalProperties: + type: string + description: NodeAffinityLabels to pin the rack, using node + affinity + type: object + zone: + description: Deprecated. Use nodeAffinityLabels instead. Zone + name to pin the rack, using node affinity + type: string + required: + - name + type: object + type: array + reaper: + description: 'Deprecated: Reaper''s sidecar mode has too many problems + in Kubernetes for it to usable. In order for it to work reliably, + changes in Reaper would be needed. See https://github.com/thelastpickle/cassandra-reaper/issues/956 + for details. Because those changes were not implemented in Reaper + and because Reaper support was instead added through k8ssandra, + this field will be removed in the 1.8.0 release.' + properties: + enabled: + type: boolean + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + resources: + description: Kubernetes resource requests and limits per reaper + container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + type: object + replaceNodes: + description: A list of pod names that need to be replaced. + items: + type: string + type: array + resources: + description: Kubernetes resource requests and limits, per pod + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + rollingRestartRequested: + description: Whether to do a rolling restart at the next opportunity. + The operator will set this back to false once the restart is in + progress. + type: boolean + serverImage: + description: 'Cassandra server image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + serverType: + description: 'Server type: "cassandra" or "dse"' + enum: + - cassandra + - dse + type: string + serverVersion: + description: Version string for config builder, used to generate Cassandra + server configuration + pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.0\.\d+) + type: string + serviceAccount: + description: The k8s service account to use for the server pods + type: string + size: + description: Desired number of Cassandra server nodes + format: int32 + minimum: 1 + type: integer + stopped: + description: A stopped CassandraDatacenter will have no running server + pods, like using "stop" with traditional System V init scripts. + Other Kubernetes resources will be left intact, and volumes will + re-attach when the CassandraDatacenter workload is resumed. + type: boolean + storageConfig: + description: Describes the persistent storage request of each server + node + properties: + additionalVolumes: + items: + description: StorageConfig defines additional storage configurations + properties: + mountPath: + description: Mount path into cassandra container + type: string + name: + description: Name of the pvc + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' + type: string + pvcSpec: + description: Persistent volume claim spec + properties: + accessModes: + description: 'AccessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) * An existing + custom resource that implements data population (Alpha) + In order to use custom resource types that implement + data population, the AnyVolumeDataSource feature gate + must be enabled. If the provisioner or an external + controller can support the specified data source, + it will create a new volume based on the contents + of the specified data source.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum resources + the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is + omitted for a container, it defaults to Limits + if that is explicitly specified, otherwise to + an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + selector: + description: A label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required by the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: VolumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + required: + - mountPath + - name + - pvcSpec + type: object + type: array + cassandraDataVolumeClaimSpec: + description: PersistentVolumeClaimSpec describes the common attributes + of storage devices and allows a Source for provider-specific + attributes + properties: + accessModes: + description: 'AccessModes contains the desired access modes + the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify either: * + An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) * An existing + custom resource that implements data population (Alpha) + In order to use custom resource types that implement data + population, the AnyVolumeDataSource feature gate must be + enabled. If the provisioner or an external controller can + support the specified data source, it will create a new + volume based on the contents of the specified data source.' + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum resources the + volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + selector: + description: A label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required + by the claim. Value of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: VolumeName is the binding reference to the PersistentVolume + backing this claim. + type: string + type: object + type: object + superuserSecretName: + description: This secret defines the username and password for the + Cassandra server superuser. If it is omitted, we will generate a + secret instead. + type: string + systemLoggerImage: + description: Container image for the log tailing sidecar container. + type: string + systemLoggerResources: + description: Kubernetes resource requests and limits per system logger + container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations applied to the Cassandra pod. Note that these + cannot be overridden with PodTemplateSpec. + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + users: + description: Cassandra users to bootstrap + items: + properties: + secretName: + type: string + superuser: + type: boolean + required: + - secretName + - superuser + type: object + type: array + required: + - clusterName + - serverType + - serverVersion + - size + - storageConfig + type: object + x-kubernetes-preserve-unknown-fields: true + status: + description: CassandraDatacenterStatus defines the observed state of CassandraDatacenter + properties: + cassandraOperatorProgress: + description: Last known progress state of the Cassandra Operator + type: string + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + lastRollingRestart: + format: date-time + type: string + lastServerNodeStarted: + description: The timestamp when the operator last started a Server + node with the management API + format: date-time + type: string + nodeReplacements: + items: + type: string + type: array + nodeStatuses: + additionalProperties: + properties: + hostID: + type: string + type: object + type: object + observedGeneration: + format: int64 + type: integer + quietPeriod: + format: date-time + type: string + superUserUpserted: + description: Deprecated. Use usersUpserted instead. The timestamp + at which CQL superuser credentials were last upserted to the management + API + format: date-time + type: string + usersUpserted: + description: The timestamp at which managed cassandra users' credentials + were last upserted to the management API + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml new file mode 100644 index 00000000..ebd528f2 --- /dev/null +++ b/config/crd/kustomization.yaml @@ -0,0 +1,43 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/cassandra.datastax.com_cassandradatacenters.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patchesJson6902: +- target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: cassandradatacenters.cassandra.datastax.com + path: patches/config_removal.yaml +- target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: cassandradatacenters.cassandra.datastax.com + path: patches/remove_xkeys.yaml +# name: controller-manager +# namespace: system +# patch: |- +# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/containers/1/volumeMounts/0 + + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_cassandradatacenters.yaml +#+kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +- patches/cainjection_in_cassandradatacenters.yaml +#+kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000..ec5c150a --- /dev/null +++ b/config/crd/kustomizeconfig.yaml @@ -0,0 +1,19 @@ +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/config/crd/patches/cainjection_in_cassandradatacenters.yaml b/config/crd/patches/cainjection_in_cassandradatacenters.yaml new file mode 100644 index 00000000..afaedb9b --- /dev/null +++ b/config/crd/patches/cainjection_in_cassandradatacenters.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: cassandradatacenters.cassandra.datastax.com diff --git a/config/crd/patches/config_removal.yaml b/config/crd/patches/config_removal.yaml new file mode 100644 index 00000000..c091b09c --- /dev/null +++ b/config/crd/patches/config_removal.yaml @@ -0,0 +1,15 @@ +# Remove the "config" section from the CRD, and enable +# x-kubernetes-preserve-unknown-fields. +# +# This is necessary because the config field has a dynamic +# schema which depends on the DSE version selected, and +# dynamic schema aren't possible to fully specify and +# validate via openAPI V3. +# +# Instead, we remove the config field from the schema +# entirely and instruct openAPI/k8s to preserve fields even +# if they aren't specified in the CRD. The field itself is defined +# as a json.RawMessage, see dsedatacenter_types.go in the +# api's subdirectory for details. +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/config diff --git a/config/crd/patches/remove_xkeys.yaml b/config/crd/patches/remove_xkeys.yaml new file mode 100644 index 00000000..c4cbdfb4 --- /dev/null +++ b/config/crd/patches/remove_xkeys.yaml @@ -0,0 +1,12 @@ +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/containers/items/properties/ports/x-kubernetes-list-map-keys +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/containers/items/properties/ports/x-kubernetes-list-type +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/initContainers/items/properties/ports/x-kubernetes-list-map-keys +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/initContainers/items/properties/ports/x-kubernetes-list-type +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/topologySpreadConstraints/x-kubernetes-list-map-keys +- op: remove + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/podTemplateSpec/properties/spec/properties/topologySpreadConstraints/x-kubernetes-list-type diff --git a/config/crd/patches/webhook_in_cassandradatacenters.yaml b/config/crd/patches/webhook_in_cassandradatacenters.yaml new file mode 100644 index 00000000..07d7aba0 --- /dev/null +++ b/config/crd/patches/webhook_in_cassandradatacenters.yaml @@ -0,0 +1,14 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: cassandradatacenters.cassandra.datastax.com +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml new file mode 100644 index 00000000..cc3495d7 --- /dev/null +++ b/config/default/kustomization.yaml @@ -0,0 +1,74 @@ +# Adds namespace to all resources. +namespace: cass-operator + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: cass-operator- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: +# Protect the /metrics endpoint by putting it behind auth. +# If you want your controller-manager to expose the /metrics +# endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_patch.yaml + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +- manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. +# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. +# 'CERTMANAGER' needs to be enabled to use ca injection +- webhookcainjection_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000..a224be19 --- /dev/null +++ b/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,26 @@ +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https + - name: manager + args: + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" + - "--leader-elect" diff --git a/config/default/manager_config_patch.yaml b/config/default/manager_config_patch.yaml new file mode 100644 index 00000000..6c400155 --- /dev/null +++ b/config/default/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000..738de350 --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000..a350db40 --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +# apiVersion: admissionregistration.k8s.io/v1 +# kind: MutatingWebhookConfiguration +# metadata: +# name: mutating-webhook-configuration +# annotations: +# cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manager/controller_manager_config.yaml b/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000..668fdf9f --- /dev/null +++ b/config/manager/controller_manager_config.yaml @@ -0,0 +1,11 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: b569adb7.cassandra.datastax.com diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml new file mode 100644 index 00000000..3804659a --- /dev/null +++ b/config/manager/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- files: + - controller_manager_config.yaml + name: manager-config +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: k8ssandra/cass-operator + newTag: latest diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml new file mode 100644 index 00000000..039e0fa0 --- /dev/null +++ b/config/manager/manager.yaml @@ -0,0 +1,66 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + name: cass-operator + control-plane: controller-manager + replicas: 1 + template: + metadata: + labels: + name: cass-operator + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/cass-operator.clusterserviceversion.yaml b/config/manifests/bases/cass-operator.clusterserviceversion.yaml new file mode 100644 index 00000000..033bb2db --- /dev/null +++ b/config/manifests/bases/cass-operator.clusterserviceversion.yaml @@ -0,0 +1,47 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: '[]' + capabilities: Basic Install + name: cass-operator.v0.0.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: CassandraDatacenter is the Schema for the cassandradatacenters API + displayName: Cassandra Datacenter + kind: CassandraDatacenter + name: cassandradatacenters.cassandra.datastax.com + version: v1beta1 + description: '-' + displayName: DataStax Apache Cassandra Operator + icon: + - base64data: "" + mediatype: "" + install: + spec: + deployments: null + strategy: "" + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - k8ssandra + - cass-operator + - cassandra + links: + - name: Cass Operator + url: https://k8ssandra.io + maturity: alpha + provider: + name: DataStax + url: k8ssandra.io + version: 0.0.0 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml new file mode 100644 index 00000000..190d75d9 --- /dev/null +++ b/config/manifests/kustomization.yaml @@ -0,0 +1,27 @@ +# These resources constitute the fully configured set of manifests +# used to generate the 'manifests/' directory in a bundle. +resources: +- bases/cass-operator.clusterserviceversion.yaml +- ../default +- ../samples +- ../scorecard + +# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. +# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. +# These patches remove the unnecessary "cert" volume and its manager container volumeMount. +patchesJson6902: +# - target: +# group: apps +# version: v1 +# kind: Deployment +# name: controller-manager +# namespace: system +# patch: |- +# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/containers/1/volumeMounts/0 +# # Remove the "cert" volume, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing volumes in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/volumes/0 diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml new file mode 100644 index 00000000..ed137168 --- /dev/null +++ b/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml new file mode 100644 index 00000000..d19136ae --- /dev/null +++ b/config/prometheus/monitor.yaml @@ -0,0 +1,20 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000..bd4af137 --- /dev/null +++ b/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,7 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: ["/metrics"] + verbs: ["get"] diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000..618f5e41 --- /dev/null +++ b/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] diff --git a/operator/deploy/cluster_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml similarity index 61% rename from operator/deploy/cluster_role_binding.yaml rename to config/rbac/auth_proxy_role_binding.yaml index 374cacd5..ec7acc0a 100644 --- a/operator/deploy/cluster_role_binding.yaml +++ b/config/rbac/auth_proxy_role_binding.yaml @@ -1,12 +1,12 @@ -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: - name: cass-operator -subjects: -- kind: ServiceAccount - name: cass-operator - namespace: "cass-operator" + name: proxy-rolebinding roleRef: - kind: ClusterRole - name: cass-operator-cluster-role apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000..6cf656be --- /dev/null +++ b/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager diff --git a/config/rbac/cassandradatacenter_editor_role.yaml b/config/rbac/cassandradatacenter_editor_role.yaml new file mode 100644 index 00000000..8d2cc906 --- /dev/null +++ b/config/rbac/cassandradatacenter_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit cassandradatacenters. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cassandradatacenter-editor-role +rules: +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters/status + verbs: + - get diff --git a/config/rbac/cassandradatacenter_viewer_role.yaml b/config/rbac/cassandradatacenter_viewer_role.yaml new file mode 100644 index 00000000..043205f0 --- /dev/null +++ b/config/rbac/cassandradatacenter_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view cassandradatacenters. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cassandradatacenter-viewer-role +rules: +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters + verbs: + - get + - list + - watch +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters/status + verbs: + - get diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml new file mode 100644 index 00000000..fb5a2b88 --- /dev/null +++ b/config/rbac/kustomization.yaml @@ -0,0 +1,18 @@ +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# Comment the following 4 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +# - auth_proxy_service.yaml +# - auth_proxy_role.yaml +# - auth_proxy_role_binding.yaml +# - auth_proxy_client_clusterrole.yaml diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000..6334cc51 --- /dev/null +++ b/config/rbac/leader_election_role.yaml @@ -0,0 +1,27 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role +rules: +- apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/operator/deploy/role_binding.yaml b/config/rbac/leader_election_role_binding.yaml similarity index 63% rename from operator/deploy/role_binding.yaml rename to config/rbac/leader_election_role_binding.yaml index 5b5f4ede..df9defbf 100644 --- a/operator/deploy/role_binding.yaml +++ b/config/rbac/leader_election_role_binding.yaml @@ -1,12 +1,11 @@ -kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: - name: cass-operator - namespace: "" -subjects: -- kind: ServiceAccount - name: cass-operator + name: leader-election-rolebinding roleRef: - kind: Role - name: cass-operator apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml new file mode 100644 index 00000000..94245c18 --- /dev/null +++ b/config/rbac/role.yaml @@ -0,0 +1,110 @@ + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - "" + resources: + - nodes + - persistentvolumes + verbs: + - get + - list + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + creationTimestamp: null + name: manager-role + namespace: cass-operator +rules: +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters/finalizers + verbs: + - delete + - update +- apiGroups: + - cassandra.datastax.com + resources: + - cassandradatacenters/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - configmaps + - endpoints + - events + - persistentvolumeclaims + - pods + - secrets + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/charts/cass-operator-chart/templates/rolebinding.yaml b/config/rbac/role_binding.yaml similarity index 51% rename from charts/cass-operator-chart/templates/rolebinding.yaml rename to config/rbac/role_binding.yaml index 5e12870d..d9833c8c 100644 --- a/charts/cass-operator-chart/templates/rolebinding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,26 +1,23 @@ -{{- if .Values.clusterWideInstall }} -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: - name: {{ .Values.roleBindingName }} -subjects: -- kind: ServiceAccount - name: {{ .Values.serviceAccountName }} - namespace: {{ .Release.Namespace }} + name: manager-rolebinding roleRef: - kind: ClusterRole - name: {{ .Values.roleName }} apiGroup: rbac.authorization.k8s.io -{{- else }} -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.roleBindingName }} + kind: Role + name: manager-role subjects: - kind: ServiceAccount - name: {{ .Values.serviceAccountName }} + name: controller-manager +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: manager-res-rolebinding roleRef: - kind: Role - name: {{ .Values.roleName }} apiGroup: rbac.authorization.k8s.io -{{- end }} + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: controller-manager diff --git a/operator/deploy/service_account.yaml b/config/rbac/service_account.yaml similarity index 54% rename from operator/deploy/service_account.yaml rename to config/rbac/service_account.yaml index f8babb1f..69ece2e4 100644 --- a/operator/deploy/service_account.yaml +++ b/config/rbac/service_account.yaml @@ -1,5 +1,4 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: cass-operator - namespace: "" + name: controller-manager diff --git a/config/samples/cassandra.datastax.com_v1beta1_cassandradatacenter.yaml b/config/samples/cassandra.datastax.com_v1beta1_cassandradatacenter.yaml new file mode 100644 index 00000000..b608ef70 --- /dev/null +++ b/config/samples/cassandra.datastax.com_v1beta1_cassandradatacenter.yaml @@ -0,0 +1,7 @@ +apiVersion: cassandra.datastax.com/v1beta1 +kind: CassandraDatacenter +metadata: + name: cassandradatacenter-sample +spec: + # Add fields here + foo: bar diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml new file mode 100644 index 00000000..66e16158 --- /dev/null +++ b/config/samples/kustomization.yaml @@ -0,0 +1,4 @@ +## Append samples you want in your CSV to this file as resources ## +resources: +- cassandra.datastax.com_v1beta1_cassandradatacenter.yaml +#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml new file mode 100644 index 00000000..c7704784 --- /dev/null +++ b/config/scorecard/bases/config.yaml @@ -0,0 +1,7 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: [] diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml new file mode 100644 index 00000000..50cd2d08 --- /dev/null +++ b/config/scorecard/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- bases/config.yaml +patchesJson6902: +- path: patches/basic.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +- path: patches/olm.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +#+kubebuilder:scaffold:patchesJson6902 diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml new file mode 100644 index 00000000..ec3f34a7 --- /dev/null +++ b/config/scorecard/patches/basic.config.yaml @@ -0,0 +1,10 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: basic + test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml new file mode 100644 index 00000000..9e095537 --- /dev/null +++ b/config/scorecard/patches/olm.config.yaml @@ -0,0 +1,50 @@ +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: olm + test: olm-bundle-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: olm + test: olm-crds-have-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: olm + test: olm-crds-have-resources-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: olm + test: olm-spec-descriptors-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.6.1 + labels: + suite: olm + test: olm-status-descriptors-test diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 00000000..9cf26134 --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000..25e21e3c --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 00000000..f8375cc4 --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,29 @@ + +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-cassandra-datastax-com-v1beta1-cassandradatacenter + failurePolicy: Ignore + name: vcassandradatacenter.kb.io + rules: + - apiGroups: + - cassandra.datastax.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - cassandradatacenters + sideEffects: None diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 00000000..31e0f829 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/controllers/cassandradatacenter_controller.go b/controllers/cassandradatacenter_controller.go new file mode 100644 index 00000000..0a496f8a --- /dev/null +++ b/controllers/cassandradatacenter_controller.go @@ -0,0 +1,247 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "time" + + "github.com/go-logr/logr" + "github.com/google/uuid" + "github.com/k8ssandra/cass-operator/pkg/dynamicwatch" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/reconciliation" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" +) + +// datastax.com groups +//+kubebuilder:rbac:groups=cassandra.datastax.com,namespace=cass-operator,resources=cassandradatacenters,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=cassandra.datastax.com,namespace=cass-operator,resources=cassandradatacenters/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=cassandra.datastax.com,namespace=cass-operator,resources=cassandradatacenters/finalizers,verbs=update;delete + +// Kubernetes core +// +kubebuilder:rbac:groups=apps,namespace=cass-operator,resources=statefulsets;replicasets;deployments;daemonsets,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=apps,namespace=cass-operator,resources=deployments/finalizers,verbs=update +// +kubebuilder:rbac:groups=core,namespace=cass-operator,resources=pods;endpoints;services;configmaps;secrets;persistentvolumeclaims;events,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,namespace=cass-operator,resources=namespaces,verbs=get +// +kubebuilder:rbac:groups=core,resources=persistentvolumes;nodes,verbs=get;list;watch +// +kubebuilder:rbac:groups=policy,namespace=cass-operator,resources=poddisruptionbudgets,verbs=get;list;watch;create;update;patch;delete + +// CassandraDatacenterReconciler reconciles a cassandraDatacenter object +type CassandraDatacenterReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + Recorder record.EventRecorder + + // SecretWatches is used in the controller when setting up the watches and + // during reconciliation where we update the mappings for the watches. + // Putting it here allows us to get it to both places. + SecretWatches dynamicwatch.DynamicWatches +} + +// Reconcile reads that state of the cluster for a Datacenter object +// and makes changes based on the state read +// and what is in the cassandraDatacenter.Spec +// Note: +// The Controller will requeue the Request to be processed again +// if the returned error is non-nil or Result.Requeue is true, +// otherwise upon completion it will remove the work from the queue. +// See: https://godoc.org/sigs.k8s.io/controller-runtime/pkg/reconcile#Result +func (r *CassandraDatacenterReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { + startReconcile := time.Now() + + logger := r.Log. + WithValues("cassandradatacenter", request.NamespacedName). + WithValues("requestNamespace", request.Namespace). + WithValues("requestName", request.Name). + // loopID is used to tie all events together that are spawned by the same reconciliation loop + WithValues("loopID", uuid.New().String()) + + defer func() { + reconcileDuration := time.Since(startReconcile).Seconds() + logger.Info("Reconcile loop completed", + "duration", reconcileDuration) + }() + + logger.Info("======== handler::Reconcile has been called") + + rc, err := reconciliation.CreateReconciliationContext(&request, r.Client, r.Scheme, r.Recorder, r.SecretWatches, logger) + + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. + // Return and don't requeue + logger.Info("CassandraDatacenter resource not found. Ignoring since object must be deleted.") + return ctrl.Result{}, nil + } + + // Error reading the object + logger.Error(err, "Failed to get CassandraDatacenter.") + return ctrl.Result{RequeueAfter: 10 * time.Second}, err + } + + if err := rc.IsValid(rc.Datacenter); err != nil { + logger.Error(err, "CassandraDatacenter resource is invalid") + rc.Recorder.Eventf(rc.Datacenter, "Warning", "ValidationFailed", err.Error()) + return ctrl.Result{}, err + } + + // TODO fold this into the quiet period + twentySecs := time.Second * 20 + lastNodeStart := rc.Datacenter.Status.LastServerNodeStarted + cooldownTime := time.Until(lastNodeStart.Add(twentySecs)) + + if cooldownTime > 0 { + logger.Info("Ending reconciliation early because a server node was recently started") + secs := time.Duration(1 + int(cooldownTime.Seconds())) + return ctrl.Result{RequeueAfter: secs * time.Second}, nil + } + + if rc.Datacenter.Status.QuietPeriod.After(time.Now()) { + logger.Info("Ending reconciliation early because the datacenter is in a quiet period") + cooldownTime = rc.Datacenter.Status.QuietPeriod.Sub(time.Now()) + secs := time.Duration(1 + int(cooldownTime.Seconds())) + return ctrl.Result{RequeueAfter: secs * time.Second}, nil + } + + res, err := rc.CalculateReconciliationActions() + if err != nil { + logger.Error(err, "calculateReconciliationActions returned an error") + rc.Recorder.Eventf(rc.Datacenter, "Warning", "ReconcileFailed", err.Error()) + } + return res, err +} + +// SetupWithManager sets up the controller with the Manager. +func (r *CassandraDatacenterReconciler) SetupWithManager(mgr ctrl.Manager) error { + log := r.Log. + WithName("cassandradatacenter_controller") + + managedByCassandraOperatorPredicate := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return oplabels.HasManagedByCassandraOperatorLabel(e.Object.GetLabels()) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + return oplabels.HasManagedByCassandraOperatorLabel(e.Object.GetLabels()) + }, + UpdateFunc: func(e event.UpdateEvent) bool { + return oplabels.HasManagedByCassandraOperatorLabel(e.ObjectOld.GetLabels()) || + oplabels.HasManagedByCassandraOperatorLabel(e.ObjectNew.GetLabels()) + }, + GenericFunc: func(e event.GenericEvent) bool { + return oplabels.HasManagedByCassandraOperatorLabel(e.Object.GetLabels()) + }, + } + + // Create a new managed controller builder + c := ctrl.NewControllerManagedBy(mgr). + Named("cassandradatacenter-controller"). + WithLogger(log). + For(&api.CassandraDatacenter{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). + Owns(&appsv1.StatefulSet{}, builder.WithPredicates(managedByCassandraOperatorPredicate)). + Owns(&policyv1beta1.PodDisruptionBudget{}, builder.WithPredicates(managedByCassandraOperatorPredicate)). + Owns(&corev1.Service{}, builder.WithPredicates(managedByCassandraOperatorPredicate)) + + configSecretMapFn := func(mapObj client.Object) []reconcile.Request { + log.Info("config secret watch called", "Secret", mapObj.GetName()) + + requests := make([]reconcile.Request, 0) + secret := mapObj.(*corev1.Secret) + if v, ok := secret.Annotations[api.DatacenterAnnotation]; ok { + log.Info("adding reconciliation request for config secret", "Secret", secret.Name) + requests = append(requests, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: secret.Namespace, + Name: v, + }, + }) + } + + return requests + } + + isConfigSecret := func(annotations map[string]string) bool { + _, ok := annotations[api.DatacenterAnnotation] + return ok + } + + configSecretPredicate := predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + return isConfigSecret(e.Object.GetAnnotations()) + }, + + UpdateFunc: func(e event.UpdateEvent) bool { + return isConfigSecret(e.ObjectOld.GetAnnotations()) || isConfigSecret(e.ObjectNew.GetAnnotations()) + }, + + DeleteFunc: func(e event.DeleteEvent) bool { + return isConfigSecret(e.Object.GetAnnotations()) + }, + + GenericFunc: func(e event.GenericEvent) bool { + return isConfigSecret(e.Object.GetAnnotations()) + }, + } + + c = c.Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(configSecretMapFn), builder.WithPredicates(configSecretPredicate)) + + // TODO Add PSP stuff here if necessary + + // Setup watches for Secrets. These secrets are often not owned by or created by + // the operator, so we must create a mapping back to the appropriate datacenters. + + r.SecretWatches = dynamicwatch.NewDynamicSecretWatches(r.Client) + dynamicSecretWatches := r.SecretWatches + + toRequests := func(a client.Object) []reconcile.Request { + watchers := dynamicSecretWatches.FindWatchers(a) + requests := []reconcile.Request{} + for _, watcher := range watchers { + requests = append(requests, reconcile.Request{NamespacedName: watcher}) + } + return requests + } + + c = c.Watches( + &source.Kind{Type: &corev1.Secret{}}, + handler.EnqueueRequestsFromMapFunc(toRequests), + ) + + return c.Complete(r) +} + +// blank assignment to verify that CassandraDatacenterReconciler implements reconciliation.Reconciler +var _ reconcile.Reconciler = &CassandraDatacenterReconciler{} diff --git a/controllers/suite_test.go b/controllers/suite_test.go new file mode 100644 index 00000000..401d38d6 --- /dev/null +++ b/controllers/suite_test.go @@ -0,0 +1,80 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + cassandradatastaxcomv1beta1 "github.com/k8ssandra/cass-operator/api/v1beta1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + } + + cfg, err := testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = cassandradatastaxcomv1beta1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/go.mod b/go.mod index fb5bfb04..60f3bee6 100644 --- a/go.mod +++ b/go.mod @@ -4,51 +4,51 @@ go 1.16 require ( github.com/Jeffail/gabs v1.4.0 - github.com/go-logr/logr v0.1.0 - github.com/go-openapi/spec v0.19.4 - github.com/google/uuid v1.1.1 - github.com/magefile/mage v1.9.0 - github.com/onsi/ginkgo v1.11.0 - github.com/onsi/gomega v1.8.1 - github.com/operator-framework/operator-sdk v0.17.0 + github.com/go-logr/logr v0.4.0 + github.com/google/uuid v1.1.2 + github.com/magefile/mage v1.11.0 + github.com/onsi/ginkgo v1.14.1 + github.com/onsi/gomega v1.10.2 github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible github.com/pkg/errors v0.9.1 - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.4.0 - golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 - gopkg.in/yaml.v2 v2.2.8 - k8s.io/api v0.17.4 - k8s.io/apimachinery v0.17.4 + github.com/stretchr/testify v1.6.1 + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 + gopkg.in/yaml.v2 v2.4.0 + k8s.io/api v0.20.2 + k8s.io/apimachinery v0.20.2 k8s.io/client-go v12.0.0+incompatible - k8s.io/code-generator v0.17.4 - k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f - k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a - k8s.io/kubernetes v1.17.4 - sigs.k8s.io/controller-runtime v0.5.2 - sigs.k8s.io/controller-tools v0.2.8 + k8s.io/code-generator v0.20.2 + k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 + k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 + k8s.io/kubernetes v1.21.1 + sigs.k8s.io/controller-runtime v0.8.3 + sigs.k8s.io/controller-tools v0.5.0 ) replace ( - github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.3.2+incompatible // Required by OLM - k8s.io/api => k8s.io/api v0.17.4 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.17.4 - k8s.io/apimachinery => k8s.io/apimachinery v0.17.4 - k8s.io/apiserver => k8s.io/apiserver v0.17.4 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.17.4 - k8s.io/client-go => k8s.io/client-go v0.17.4 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.17.4 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.17.4 - k8s.io/code-generator => k8s.io/code-generator v0.17.4 - k8s.io/component-base => k8s.io/component-base v0.17.4 - k8s.io/cri-api => k8s.io/cri-api v0.17.4 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.17.4 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.17.4 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.17.4 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.17.4 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.17.4 - k8s.io/kubectl => k8s.io/kubectl v0.17.4 - k8s.io/kubelet => k8s.io/kubelet v0.17.4 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.17.4 - k8s.io/metrics => k8s.io/metrics v0.17.4 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.17.4 + // github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.3.2+incompatible // Required by OLM + k8s.io/api => k8s.io/api v0.20.2 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.20.2 + k8s.io/apimachinery => k8s.io/apimachinery v0.20.2 + k8s.io/apiserver => k8s.io/apiserver v0.20.2 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.20.2 + k8s.io/client-go => k8s.io/client-go v0.20.2 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.20.2 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.20.2 + k8s.io/code-generator => k8s.io/code-generator v0.20.2 + k8s.io/component-base => k8s.io/component-base v0.20.2 + k8s.io/component-helpers => k8s.io/component-helpers v0.20.2 + k8s.io/controller-manager => k8s.io/controller-manager v0.20.2 + k8s.io/cri-api => k8s.io/cri-api v0.20.2 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.20.2 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.20.2 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.20.2 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.20.2 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.20.2 + k8s.io/kubectl => k8s.io/kubectl v0.20.2 + k8s.io/kubelet => k8s.io/kubelet v0.20.2 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.20.2 + k8s.io/metrics => k8s.io/metrics v0.20.2 + k8s.io/mount-utils => k8s.io/mount-utils v0.20.2 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.20.2 ) diff --git a/go.sum b/go.sum index 3069f78b..135cb88b 100644 --- a/go.sum +++ b/go.sum @@ -1,1511 +1,606 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q= -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690 h1:N9r8OBSXAgEUfho3SQtZLY8zo6E1OdOMvelvP22aVFc= bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= -bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.49.0 h1:CH+lkubJzcPYB1Ggupcq0+k8Ni2ILdG2lYjDIgavDBQ= -cloud.google.com/go v0.49.0/go.mod h1:hGvAdzcWNbyuxS3nWhD7H2cIJxjRRTRLQVB0bdputVY= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.3.0 h1:2Ze/3nQD5F+HfL0xOPM2EeawDWs+NPRtzgcre+17iZU= -cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA= -contrib.go.opencensus.io/exporter/ocagent v0.6.0 h1:Z1n6UAyr0QwM284yUuh5Zd8JlvxUGAhFZcgMJkMPrGM= -contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v23.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v36.1.0+incompatible h1:smHlbChr/JDmsyUqELZXLs0YIgpXecIGdUibuc2983s= -github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v13.3.2+incompatible h1:VxzPyuhtnlBOzc4IWCZHqpyH2d+QMLQEuy3wREyY4oc= -github.com/Azure/go-autorest v13.3.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503 h1:uUhdsDMg2GbFLF5GfQPtLMWd5vdDZSfqvqQp3waafxQ= -github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 h1:Hxqlh1uAA8aGpa1dFhDNhll7U/rkWtG8ZItFvRMr7l0= -github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.12 h1:gI8ytXbxMfI+IVbI9mP2JGCTXIuhHLgRlvQ9X4PsnHE= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= -github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503 h1:2McfZNaDqGPjv2pddK547PENIk4HV+NT7gvqRq4L0us= -github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= -github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503 h1:RBrGlrkPWapMcLp1M6ywCqyYKOAT5ERI6lYFvGKOThE= -github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= -github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534 h1:N7lSsF+R7wSulUADi36SInSQA3RvfO/XclHQfedr0qk= -github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= -github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= -github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3sm36u14= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.0.2 h1:wz22D0CiSctrliXiI9ZO3HoNApweeRGftyDN+BQa3B8= -github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= -github.com/Masterminds/vcs v1.13.1 h1:NL3G1X7/7xduQtA2sJLpVpfHTNBALVNSjob6KEjPXNQ= -github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= -github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= -github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= -github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Rican7/retry v0.1.0 h1:FqK94z34ly8Baa6K+G8Mmza9rYWTKOJk+yckIBB5qVk= -github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ= -github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible h1:EaK5256H3ELiyaq5O/Zwd6fnghD6DqmZDQmmzzJklUU= -github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 h1:uZuxRZCz65cG1o6K/xUqImNcYKtmk9ylqaH0itMSvzA= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU= -github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 h1:irR1cO6eek3n5uquIVaRAsQmZnlsfPuHNz31cXo4eyk= github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= -github.com/bazelbuild/bazel-gazelle v0.18.2/go.mod h1:D0ehMSbS+vesFsLGiD6JXu3mVEzOlfUl8wNnq+x/9p0= -github.com/bazelbuild/bazel-gazelle v0.19.1-0.20191105222053-70208cbdc798 h1:1pcd3bq1rC5X4nz56fdK0oQrz9CZup6DGZl8isCPthk= -github.com/bazelbuild/bazel-gazelle v0.19.1-0.20191105222053-70208cbdc798/go.mod h1:rPwzNHUqEzngx1iVBfO/2X2npKaT3tqPqqHW6rVsn/A= -github.com/bazelbuild/buildtools v0.0.0-20190731111112-f720930ceb60/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= -github.com/bazelbuild/buildtools v0.0.0-20190917191645-69366ca98f89 h1:3B/ZE1a6eEJ/4Jf/M6RM2KBouN8yKCUcMmXzSyWqa3g= -github.com/bazelbuild/buildtools v0.0.0-20190917191645-69366ca98f89/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= -github.com/bazelbuild/rules_go v0.0.0-20190719190356-6dae44dc5cab h1:wzbawlkLtl2ze9w/312NHZ84c7kpUCtlkD8HgFY27sw= -github.com/bazelbuild/rules_go v0.0.0-20190719190356-6dae44dc5cab/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= -github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115 h1:fUjoj2bT6dG8LoEe+uNsKk8J+sLkDbQkJnB6Z1F02Bc= github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= -github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/brancz/gojsontoyaml v0.0.0-20190425155809-e8bd32d46b3d h1:DMb8SuAL9+demT8equqMMzD8C/uxqWmj4cgV7ufrpQo= -github.com/brancz/gojsontoyaml v0.0.0-20190425155809-e8bd32d46b3d/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/caddyserver/caddy v1.0.3 h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w= github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E= -github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= -github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= -github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c h1:p8i+qCbr/dNhS2FoQhRpSS7X5+IlxTa94nRNYXu4fyo= -github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= -github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM= -github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho= -github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 h1:a1zrFsLFac2xoM6zG1u72DWJwZG3ayttYLfmLbxVETk= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313 h1:eIHD9GNM3Hp7kcRW5mvcz7WTR3ETeoYYKwpgA04kaXE= github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0= -github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY= -github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= -github.com/container-storage-interface/spec v1.2.0 h1:bD9KIVgaVKKkQ/UbVUY9kCaH/CJbhNxe0eeB4JeJV2s= -github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= -github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg= +github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.0.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M= -github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de h1:dlfGmNcE3jDAecLqwKPMNX6nk2qh1c1Vg1/YTzpOOF4= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 h1:14r0i3IeJj6zkNLigAJiv/TWSR8EY+pxIjv5tFiT+n8= -github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE= -github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/coredns/corefile-migration v1.0.4 h1:GpAwsgzgLA9HOnt3+Z69xsMVLl0doNnyVfBX79d/P5A= -github.com/coredns/corefile-migration v1.0.4/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/coredns/corefile-migration v1.0.11/go.mod h1:RMy/mXdeDlYwzt0vdMEJvT2hGJ2I86/eO0UdXmH9XNI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/prometheus-operator v0.38.0 h1:gF2xYIfO09XLFdyEecND46uihQ2KTaDwTozRZpXLtN4= -github.com/coreos/prometheus-operator v0.38.0/go.mod h1:xZC7/TgeC0/mBaJk+1H9dbHaiEvLYHgX6Mi1h40UPh8= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07 h1:UHFGPvSxX4C4YBApSPvmUfL8tTvWLj2ryqvT9K4Jcuk= -github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= -github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f h1:7uSNgsgcarNk4oiN/nNkO0J7KAjlsF5Yv5Gf/tFdHas= -github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= -github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4 h1:CVAqftqbj+exlab+8KJQrE+kNIVlQfJt58j4GxCMF1s= -github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= -github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00 h1:FHpbUtp2K8X53/b4aFNj4my5n+i3x+CQCZWNuHWH/+E= -github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= -github.com/cznic/lldb v1.1.0 h1:AIA+ham6TSJ+XkMe8imQ/g8KPzMUVWAwqUQQdtuMsHs= -github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= -github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369 h1:XNT/Zf5l++1Pyg08/HV04ppB0gKxAqtZQBRYiYrUuYk= -github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/ql v1.2.0 h1:lcKp95ZtdF0XkWhGnVIXGF8dVD2X+ClS08tglKtf+ak= -github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= -github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65 h1:hxuZop6tSoOi0sxFzoGGYdRqNrPubyaIf9KoBG9tPiE= -github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= -github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186 h1:0rkFMAbn5KBKNpJyHQ6Prb95vIKanmAe62KxsrN+sqA= -github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= -github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc h1:YKKpTb2BrXN2GYyGaygIdis1vXbE7SSAG9axGWIMClg= -github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd h1:uVsMphB1eRx7xB1njzL3fuMdWRN8HtVzoUOItHMwv5c= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/deislabs/oras v0.8.1 h1:If674KraJVpujYR00rzdi0QAmW4BxzMJPVAZJKuhQ0c= -github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA= -github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b h1:Yqiad0+sloMPdd/0Fg22actpFx0dekpzt1xJmVNVkU0= -github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dhui/dktest v0.3.0 h1:kwX5a7EkLcjo7VpsPQSYJcKGbXBXdjI9FGjuUj1jn6I= -github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= -github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= -github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= -github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce h1:KXS1Jg+ddGcWA8e1N7cupxaHHZhit5rB9tfDU+mfjyY= -github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 h1:yWHOI+vFjEsAakUTSrtqc/SAHrhSkmn48pqjidZX3QA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libnetwork v0.8.0-dev.2.0.20190624125649-f0e46a78ea34 h1:8GFZB1KesbMy2X2zTiJyAuwCow+U1GT0ueD42p59y4k= -github.com/docker/libnetwork v0.8.0-dev.2.0.20190624125649-f0e46a78ea34/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/docker/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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyzzjiW90t8cY= -github.com/elastic/go-sysinfo v1.1.1 h1:ZVlaLDyhVkDfjwPGU55CQRCRolNpc7P0BbyhhQZQmMI= -github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= -github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= -github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= -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/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= -github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= -github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/structtag v1.1.0 h1:6j4mUV/ES2duvnAzKMFkN6/A5mCaNYPD3xfbAkLLOF8= -github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/fake-gcs-server v1.7.0 h1:Un0BXUXrRWYSmYyC1Rqm2e2WJfTPyDy/HGMz31emTi8= -github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= 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/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= -github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= -github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego v2.5.0+incompatible h1:5fNN9yRQfv8ymH3DSsxla+4aYeQt2IgfZqHKVnK8f0s= github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M= github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= -github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= -github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= -github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540 h1:djv/qAomOVj8voCHt0M0OYwR/4vfDq1zNKSPKjJCexs= -github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= -github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI= -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.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/zapr v0.2.0 h1:v6Ji8yBW77pva6NkJKQdHLAJKrIJKRHz0RXwPqCHSR4= +github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= 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.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/loads v0.19.4 h1:5I4CCSqoWzT+82bBkNIvmLc0UOsoKKQ4Fz+3VxOB7SY= -github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.18.0/go.mod h1:uI6pHuxWYTy94zZxgcwJkUWa9wbIlhteGfloI10GD4U= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI= -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.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA= -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.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= +github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= 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.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0= -github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= -github.com/go-ozzo/ozzo-validation v3.5.0+incompatible h1:sUy/in/P6askYr16XJgTKq/0SZhiWsdg4WZGaLsGQkM= github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= -github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/flect v0.2.0 h1:EWCvMGGxOjsgwlWaP+f4+Hh6yrrte7JeFL2S6b+0hdM= -github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/logger v1.0.0 h1:xw9Ko9EcC5iAFprrjJ6oZco9UpzS5MQ4jAwghsLHdy4= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1 h1:TFOeY2VoGamPjQLiNDT3mn//ytzk236VMO2j7iHxJR4= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4 h1:vF83LI8tAakwEwvWZtrIEx7pOySacl2TOxx6eXk4ePo= -github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= -github.com/godbus/dbus v0.0.0-20181101234600-2ff6f7ffd60f/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= -github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gobuffalo/flect v0.2.2 h1:PAVD7sp0KOdfswjAw9BpLCU9hXo7wFSzgpQ+zNeks/A= +github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= -github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c h1:/7detzz5stiXWPzkTlPTzkBEIIE4WGpppBJYjKqBiPI= -github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98 h1:0OkFarm1Zy2CjCiDKfK9XHgmc2wbDlRMD2hD8anAJHU= -github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.18.0 h1:XmQgfcLofSG/6AsQuQqmLizB+3GggD+o6ObBG9L+VMM= -github.com/golangci/golangci-lint v1.18.0/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg= -github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547 h1:fUdgm/BdKvwOHxg5AhNbkNRp2mSy8sxTXyBVs/laQHo= -github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217 h1:En/tZdwhAn0JNwLuXzP3k2RVtMqMmOEK7Yu/g3tmtJE= -github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= -github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cadvisor v0.35.0 h1:qivoEm+iGqTrd0CKSmQidxfOxUxkNZovvYs/8G6B6ao= -github.com/google/cadvisor v0.35.0/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48= +github.com/google/cadvisor v0.39.0/go.mod h1:rjQFmK4jPCpxeUdLq9bYhNFFsjgGOtpnDmDeap0+nsw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70 h1:XTnP8fJpa4Kvpw2qARB4KS9izqxPS0Sd92cDlY3uk+w= -github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww= -github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v0.6.0 h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU= -github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU= -github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3 h1:iwp+5/UAyzQSFgQ4uR2sni99sJ8Eo9DEacKWM5pekIg= -github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= -github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.4/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= -github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db h1:UxmGBzaBcWDQuQh9E1iT1dWKQFbizZ+SpTd1EL4MSqs= -github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.3.0 h1:HXNYlRkkM/t+Y/Yhxtwcy02dlYwIaoxzvxPnS+cqy78= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.3.0 h1:UOxjlb4xVNF93jak1mzzoBatyFju9nrkxpVwIp/QqxQ= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= -github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8= -github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= -github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.5 h1:AYBsgJOW9gab/toO5tEB8lWetVgDKZycqkebJ8xxpqM= -github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.8.5 h1:ZynDUIQiA8usmRgPdGPHFdPnb1wgGI9tK3mO9hcAJjc= -github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= -github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible h1:ysqc8k973k1lLJ4BOOHAkx14K2nt4cLjsIm+hwWDZDE= -github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= -github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6 h1:oJ/NLadJn5HoxvonA6VxG31lg0d6XOURNA09BTtM4fY= +github.com/heketi/heketi v10.2.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= -github.com/helm/helm-2to3 v0.5.1 h1:IGbGQXfEMK95db4Zd2x8CCgXTApYCK0pJA7fH0syQf0= -github.com/helm/helm-2to3 v0.5.1/go.mod h1:AXFpQX2cSQpss+47ROPEeu7Sm4+CRJ1jKWCEQdHP3/c= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww= -github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/imdario/mergo v0.3.10 h1:6q5mVkdH/vYmqngx7kZQTjJ5HRsx+ImorDIEQ+beJgc= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.7.7 h1:UvNzAPfBrKMENVbQ4mr4ccA9sW+W1Ihl0Yh1s0BiVAg= -github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.2.0+incompatible h1:0Vihzu20St42/UDsvZGdNE6jak7oi/UOeMzwMPHkgFY= -github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1 h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a h1:BcF8coBl0QFVhe8vAMMlD+CV8EISiu9MGKLoj6ZEyJA= +github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8= github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/joefitzgerald/rainbow-reporter v0.1.0 h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jsonnet-bundler/jsonnet-bundler v0.2.0 h1:qL1v+2mjdEOmvNJp+ab+wQH81TQY71w1A666CRUg+1U= -github.com/jsonnet-bundler/jsonnet-bundler v0.2.0/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= -github.com/karrick/godirwalk v1.10.12 h1:BqUm+LuJcXjGv1d2mj3gBiQyrQ57a0rYoAmhvJQ7RDU= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kshvakov/clickhouse v1.3.5 h1:PDTYk9VYgbjPAWry3AoDREeMgOVUFij6bh6IjlloHL0= -github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= -github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/leanovate/gopter v0.2.4 h1:U4YLBggDFhJdqQsG4Na2zX7joVTky9vHaj/AGEwSuXU= -github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= -github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/libopenstorage/openstorage v1.0.0 h1:GLPam7/0mpdP8ZZtKjbfcXJBTIA/T1O6CBErVEFEyIM= github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743 h1:143Bb8f8DuGWck/xpNUOckBVYfFbBTnLevfRZ1aVVqo= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.0 h1:fAazJekOWnfBeQYwk9jEgIWWKmBxq4ev3WfsAnezgc4= -github.com/lightstep/lightstep-tracer-go v0.18.0/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lovoo/gcloud-opentracing v0.3.0 h1:nAeKG70rIsog0TelcEtt6KU0Y1s5qXtsDLnHp0urPLU= -github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= -github.com/lpabon/godbc v0.1.1 h1:ilqjArN1UOENJJdM34I2YHKmF/B0gGq4VLoSGy9iAao= github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= -github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f h1:sSeNEkJrs+0F9TUau0CgWTTNEwF23HST3Eq0A+QIx+A= github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04= -github.com/lucas-clemente/quic-clients v0.1.0 h1:/P9n0nICT/GnQJkZovtBqridjxU0ao34m7DpMts79qY= github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk= -github.com/lucas-clemente/quic-go v0.10.2 h1:iQtTSZVbd44k94Lu0U16lLBIG3lrnjDvQongjPd4B/s= github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao= -github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced h1:zqEC1GJZFbGZA0tRyNZqRjep92K5fujFtFsu5ZW7Aug= github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= -github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE= -github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/maorfr/helm-plugin-utils v0.0.0-20200216074820-36d2fcf6ae86 h1:vid6FPDLVrjL2MJa51eFFO/N85bqKPocGbeIxEhCW/U= -github.com/maorfr/helm-plugin-utils v0.0.0-20200216074820-36d2fcf6ae86/go.mod h1:p3gwmRSFqbWw6plBpR0sKl3n3vpu8kX70gvCJKMvvCA= -github.com/markbates/inflect v1.0.4 h1:5fh1gzTFhfae06u3hzHYO9xe3l3v3nW5Pwt3naLTP5g= -github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= -github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= -github.com/martinlindhe/base36 v1.0.0 h1:eYsumTah144C0A8P1T/AVSUk5ZoLnhfYFM3OGQxB52A= -github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe h1:YioO2TiJyAHWHyCRQCP8jk5IzTqmsbGc5qQPIhHo6xs= -github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk= -github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/mesos/mesos-go v0.0.9 h1:w8V5sOEnxzHZ2kAOy273v/HgbolyI6XI+qe5jx5u+Y0= -github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= -github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2 h1:xKE9kZ5C8gelJC3+BNM6LJs1x21rivK7yxfTZMAuY2s= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc= -github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/mikefarah/yaml/v2 v2.4.0 h1:eYqfooY0BnvKTJxr7+ABJs13n3dg9n347GScDaU2Lww= -github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU= -github.com/mikefarah/yq/v2 v2.4.1 h1:tajDonaFK6WqitSZExB6fKlWQy/yCkptqxh2AXEe3N4= -github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0= -github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= -github.com/minio/minio-go/v6 v6.0.49 h1:bU4kIa/qChTLC1jrWZ8F+8gOiw1MClubddAJVR4gW3w= -github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8= -github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= -github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo= -github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= -github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb h1:e+l77LJOEqXTIQihQJVkA6ZxPOUmfPM5e4H7rcpgtSk= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40 h1:Q0XH6Ql1+Z6YbUKyWyI0sD8/9yH0U8x86yA8LuWMJwY= -github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mozillazg/go-cos v0.13.0 h1:RylOpEESdWMLb13bl0ADhko12uMN3JmHqqwFu4OYGBY= -github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3DnAZsJsoaE= -github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= -github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= -github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM= -github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww= github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8 h1:P48LjvUQpTReR3TQRbxSeSBsMXzfK0uol7eRcr7VBYQ= -github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= -github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8= github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663 h1:Ri1EhipkbhWsffPJ3IPlrb4SkTOPa2PfRXp3jchBczw= -github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/ncw/swift v1.0.47 h1:4DQRPj35Y41WogBxyhOXlrI37nzGlyEcsforeudyYPQ= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v0.0.0-20170117200651-66bb6560562f/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= -github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.0 h1:O6L965K88AilqnxeYPks/75HLpp4IG+FjeSCI3cVdRg= -github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39 h1:H7DMc6FAjgwZZi8BRqjrAAHWoqEr5e5L6pS4V0ezet4= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk= -github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= -github.com/openshift/api v0.0.0-20200205133042-34f0ec8dab87 h1:L/fZlWB7DdYCd09r9LvBa44xRH42Dx80ybxfN1h5C8Y= -github.com/openshift/api v0.0.0-20200205133042-34f0ec8dab87/go.mod h1:fT6U/JfG8uZzemTRwZA2kBDJP5nWz7v05UHnty/D+pk= -github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b h1:E++qQ7W1/EdvuMo+YGVbMPn4HihEp7YT5Rghh0VmA9A= -github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= -github.com/openshift/origin v0.0.0-20160503220234-8f127d736703 h1:KLVRXtjLhZHVtrcdnuefaI2Bf182EEiTfEVDHokoyng= -github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= -github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1 h1:GW8OxGwBbI2kCqjb5PQfVXRAuCJbYyX1RYs9R3ISjck= -github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= -github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9 h1:QsgXACQhd9QJhEmRumbsMQQvBtmdS0mafoVEBplWXEg= -github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= -github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin/zipkin-go v0.1.6 h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtLXHPBo= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/operator-framework/api v0.1.1 h1:DbfxRJUPMQlQW6nbfoNzWLxv1rIv13Gt8GbsF2aglFk= -github.com/operator-framework/api v0.1.1/go.mod h1:yzNYR7qyJqRGOOp+bT6Z/iYSbSPNxeh3Si93Gx/3OBY= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20200321030439-57b580e57e88 h1:ByKBik0i2aTEr7iKdSCmUGULydHwr6hA0h4INv9LkSA= -github.com/operator-framework/operator-lifecycle-manager v0.0.0-20200321030439-57b580e57e88/go.mod h1:7Ut8p9jJ8C6RZyyhZfZypmlibCIJwK5Wcc+WZDgLkOA= -github.com/operator-framework/operator-registry v1.5.3/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= -github.com/operator-framework/operator-registry v1.6.1/go.mod h1:sx4wWMiZtYhlUiaKscg3QQUPPM/c1bkrAs4n4KipDb4= -github.com/operator-framework/operator-registry v1.6.2-0.20200330184612-11867930adb5 h1:o7Ugm+uXWF2B1oyJU9q/wd2R4w4d57K5ByZoxXJaPcI= -github.com/operator-framework/operator-registry v1.6.2-0.20200330184612-11867930adb5/go.mod h1:SHff373z8asEkPo6aWpN0qId4Y/feQTjZxRF8PRhti8= -github.com/operator-framework/operator-sdk v0.17.0 h1:+TTrGjXa+lm7g7Cm0UtFcgOjnw1x9/lBorydpsIIhOY= -github.com/operator-framework/operator-sdk v0.17.0/go.mod h1:wmYi08aoUmtgfoUamURmssI4dkdFGNtSI1Egj+ZfBnk= -github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= -github.com/otiai10/copy v1.0.2 h1:DDNipYy6RkIkjMwy+AWzgKiNTyj2RUI9yEMeETEpVyc= -github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 h1:o59bHXu8Ejas8Kq6pjoVJQ9/neN66SM8AKh6wI42BBs= -github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= -github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= -github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= -github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible h1:Jd6xfriVlJ6hWPvYOE0Ni0QWcNTLRehfGPFxr3eSL80= github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible/go.mod h1:xlUlxe/2ItGlQyMTstqeDv9r3U4obH7xYd26TbDQutY= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= -github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 h1:0XM1XL/OFFJjXsYXlG30spTkV/E9+gmd5GD1w2HE8xM= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20 h1:7sBb9iOkeq+O7AXlVoH/8zpIcRXX523zMkKKspHjjx8= -github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= -github.com/prometheus/alertmanager v0.18.0/go.mod h1:WcxHBl40VSPuOaqWae6l6HpnEOVRIycEJ7i9iYkadEE= -github.com/prometheus/alertmanager v0.20.0 h1:PBMNY7oyIvYMBBIag35/C0hO7xn8+35p4V5rNAph5N8= -github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= -github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.2.0/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI= -github.com/prometheus/prometheus v2.3.2+incompatible h1:EekL1S9WPoPtJL2NZvL+xo38iMpraOnyEHOiyZygMDY= -github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/quobyte/api v0.1.2 h1:lPHLsuvtjFyk8WhC4uHoHRkScijIHcffTWBBP+YpzYo= -github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446 h1:/NRJ5vAYoqz+7sG51ubIDHXeWO8DlTSrToPu6q11ziA= +github.com/quobyte/api v0.1.8/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY= github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw= -github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rubenv/sql-migrate v0.0.0-20191025130928-9355dd04f4b3 h1:lwDYefgiwhjuAuVnMVUYknoF+Yg9CBUykYGvYoPCNnQ= -github.com/rubenv/sql-migrate v0.0.0-20191025130928-9355dd04f4b3/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= -github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c h1:ht7N4d/B7Ezf58nvMNVF3OlvDlz9pp+WHVcRNS0nink= -github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= +github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= -github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= -github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7 h1:80VN+vGkqM773Br/uNNTSheo3KatTgV8IpjIKjvVLng= -github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/vfsgen v0.0.0-20180825020608-02ddb050ef6b/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= -github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc h1:n+WYaU0kQ6WIiuEyWSgbXqkBx16irO69kYCtwVYoO5s= -github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/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/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8= -github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/thanos-io/thanos v0.11.0 h1:UkWLa93sihcxCofelRH/NBGQxFyFU73eXIr2a+dwOFM= -github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc= -github.com/thecodeteam/goscaleio v0.1.0 h1:SB5tO98lawC+UK8ds/U2jyfOCH7GTcFztcF5x9gbut4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM= -github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec h1:AmoEvWAO3nDx1MEcMzPh+GzOOIA5Znpv6++c7bePPY0= -github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU= -github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= -github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.2.0 h1:dzZJf2IuMiclVjdw0kkT+f9u4YdrapbNyGAN47E/qnk= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= -github.com/valyala/quicktemplate v1.1.1 h1:C58y/wN0FMTi2PR0n3onltemfFabany53j7M6SDDB8k= -github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vektah/gqlparser v1.1.2 h1:ZsyLGn7/7jDNI+y4SEhI4yAxRChlv15pUHMjijT+e68= -github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= -github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 h1:J9gO8RJCAFlln1jsvRba/CWVUnMHwObklfxxjErl1uk= -github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/xanzy/go-gitlab v0.15.0 h1:rWtwKTgEnXyNUGrOArN7yyc3THRkpYcKXIXia9abywQ= -github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= -github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 h1:j2hhcujLRHAg872RWAV5yaUrEjHEObwDv3aImCaNLek= -github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 h1:YdYsPAZ2pC6Tow/nPZOPQ96O3hm/ToAkGsPLzedXERk= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs= -gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= -go.elastic.co/apm v1.5.0 h1:arba7i+CVc36Jptww3R1ttW+O10ydvnBtidyd85DLpg= -go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk= -go.elastic.co/apm/module/apmhttp v1.5.0 h1:sxntP97oENyWWi+6GAwXUo05oEpkwbiarZLqrzLRA4o= -go.elastic.co/apm/module/apmhttp v1.5.0/go.mod h1:1FbmNuyD3ddauwzgVwFB0fqY6KbZt3JkV187tGCYYhY= -go.elastic.co/apm/module/apmot v1.5.0 h1:rPyHRI6Ooqjwny67au6e2eIxLZshqd7bJfAUpdgOw/4= -go.elastic.co/apm/module/apmot v1.5.0/go.mod h1:d2KYwhJParTpyw2WnTNy8geNlHKKFX+4oK3YLlsesWE= -go.elastic.co/fastjson v1.0.0 h1:ooXV/ABvf+tBul26jcVViPT3sBir0PvXgibYB1IQQzg= -go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA= -go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/automaxprocs v1.2.0 h1:+RUihKM+nmYUoB9w0D0Ov5TJ2PpFO2FgenTxMJiZBZA= -go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= -go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go4.org v0.0.0-20180809161055-417644f6feb5 h1:+hE86LblG4AyDgwMCLTE6FOlM9+qjHSYS+rKqxUVdsM= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= -golang.org/x/build v0.0.0-20190927031335-2835ba2e683f h1:hXVePvSFG7tPGX4Pwk1d10ePFfoTCc0QmISfpKOHsS8= -golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM= -golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= -golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1513,26 +608,27 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1540,48 +636,45 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852 h1:xYq6+9AtI+xP3M4r0N1hCkHrInHDBohhquRgx9Kk6gI= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1589,359 +682,303 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190122071731-054c452bb702/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190122202912-9c309ee22fab/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190813034749-528a2984e271/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190918214516-5a1a30219888/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191030203535-5e247c9ad0a0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200115044656-831fdb1e1868/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200327195553-82bb89366a1e h1:qCZ8SbsZMjT0OuDPCEBxgLZic4NMj8Gj4vNXiTVRAaA= -golang.org/x/tools v0.0.0-20200327195553-82bb89366a1e/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= -gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -gomodules.xyz/jsonpatch/v3 v3.0.1 h1:Te7hKxV52TKCbNYq3t84tzKav3xhThdvSsSp/W89IyI= -gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto= -gomodules.xyz/orderedmap v0.1.0 h1:fM/+TGh/O1KkqGR5xjTKg6bU8OKBkg7p0Y+x/J9m8Os= -gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k= +gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= +gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= 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.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 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 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= -gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= -gopkg.in/gcfg.v1 v1.2.0 h1:0HIbH907iBTAntm+88IJV2qmJALDAh8sPekI9Vc1fm0= gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw= -gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= -gopkg.in/imdario/mergo.v0 v0.3.7 h1:QDotlIZtaO/p+Um0ok18HRTpq5i5/SAk/qprsor+9c8= -gopkg.in/imdario/mergo.v0 v0.3.7/go.mod h1:9qPP6AGrlC1G2PTNXko614FwGZvorN7MiBU0Eppok+U= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mcuadros/go-syslog.v2 v2.2.1 h1:60g8zx1BijSVSgLTzLCW9UC4/+i1Ih9jJ1DR5Tgp9vE= gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE= -gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA= 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/warnings.v0 v0.1.1 h1:XM28wIgFzaBmeZ5dNHIpWLQpt/9DGKxk+rCg/22nnYE= gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.1.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966 h1:B0J02caTR6tpSJozBJyiAzT6CtBzjclw4pgm9gg8Ys0= -gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/gotestsum v0.3.5 h1:VePOWRsuWFYpfp/G8mbmOZKxO5T3501SEGQRUdvq7h0= -gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919 h1:tmXTu+dfa+d9Evp8NpJdgOy6+rt8/x4yG7qPBrtNfLY= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -helm.sh/helm/v3 v3.1.0/go.mod h1:WYsFJuMASa/4XUqLyv54s0U/f3mlAaRErGmyy4z921g= -helm.sh/helm/v3 v3.1.2 h1:VpNzaNv2DX4aRnOCcV7v5Of+XT2SZrJ8iOQ25AGKOos= -helm.sh/helm/v3 v3.1.2/go.mod h1:WYsFJuMASa/4XUqLyv54s0U/f3mlAaRErGmyy4z921g= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -k8s.io/api v0.17.4 h1:HbwOhDapkguO8lTAE8OX3hdF2qp8GtpC9CW/MQATXXo= -k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA= -k8s.io/apiextensions-apiserver v0.17.4 h1:ZKFnw3cJrGZ/9s6y+DerTF4FL+dmK0a04A++7JkmMho= -k8s.io/apiextensions-apiserver v0.17.4/go.mod h1:rCbbbaFS/s3Qau3/1HbPlHblrWpFivoaLYccCffvQGI= -k8s.io/apimachinery v0.17.4 h1:UzM+38cPUJnzqSQ+E1PY4YxMHIzQyCg29LOoGfo79Zw= -k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g= -k8s.io/apiserver v0.17.4 h1:bYc9LvDPEF9xAL3fhbDzqNOQOAnNF2ZYCrMW8v52/mE= -k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I= -k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e h1:VZ7xYyNfl07Yh3DK10Dck9r0/8cQ3vPSxlrSQt7tohk= -k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA= -k8s.io/cli-runtime v0.17.4 h1:ZIJdxpBEszZqUhydrCoiI5rLXS2J/1AF5xFok2QJ9bc= -k8s.io/cli-runtime v0.17.4/go.mod h1:IVW4zrKKx/8gBgNNkhiUIc7nZbVVNhc1+HcQh+PiNHc= -k8s.io/client-go v0.17.4 h1:VVdVbpTY70jiNHS1eiFkUt7ZIJX3txd29nDxxXH4en8= -k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc= -k8s.io/cloud-provider v0.17.4 h1:ELMIQwweSNu8gfVEnLDypxd9034S1sZJg6QcdWJOvMI= -k8s.io/cloud-provider v0.17.4/go.mod h1:XEjKDzfD+b9MTLXQFlDGkk6Ho8SGMpaU8Uugx/KNK9U= -k8s.io/cluster-bootstrap v0.17.4 h1:K2BySILB1pA+9RPK3+Z7aj9p3PzLBZ1CdnHuuXp40qI= -k8s.io/cluster-bootstrap v0.17.4/go.mod h1:DMePcUKMsBpBTaTvfIIKna3Q2fVbGutwh5cnMu3hMYU= -k8s.io/code-generator v0.17.4 h1:C3uu/IvQclEIO4ouUOXuoKWfc4765mYe0uebStg9CaY= -k8s.io/code-generator v0.17.4/go.mod h1:l8BLVwASXQZTo2xamW5mQNFCe1XPiAesVq7Y1t7PiQQ= -k8s.io/component-base v0.17.4 h1:H9cdWZyiGVJfWmWIcHd66IsNBWTk1iEgU7D4kJksEnw= -k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I9lE= -k8s.io/cri-api v0.17.4 h1:0L8aJVzYi/h2aZ5dLGB+xPCrr9RZY8qxqbxMdyBZcZU= -k8s.io/cri-api v0.17.4/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= -k8s.io/csi-translation-lib v0.17.4 h1:bP9yGfCJDknP7tklCwizZtwgJNRePMVcEaFIfeA11ho= -k8s.io/csi-translation-lib v0.17.4/go.mod h1:CsxmjwxEI0tTNMzffIAcgR9lX4wOh6AKHdxQrT7L0oo= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f h1:eW/6wVuHNZgQJmFesyAxu0cvj0WAHHUuGaLbPcmNY3Q= -k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/heapster v1.2.0-beta.1 h1:lUsE/AHOMHpi3MLlBEkaU8Esxm5QhdyCrv1o7ot0s84= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.20.2 h1:y/HR22XDZY3pniu9hIFDLpUCPq2w5eQ6aV/VFQ7uJMw= +k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= +k8s.io/apiextensions-apiserver v0.20.2 h1:rfrMWQ87lhd8EzQWRnbQ4gXrniL/yTRBgYH1x1+BLlo= +k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs= +k8s.io/apimachinery v0.20.2 h1:hFx6Sbt1oG0n6DZ+g4bFt5f6BoMkOjKWsQFu077M3Vg= +k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA= +k8s.io/cli-runtime v0.20.2/go.mod h1:FjH6uIZZZP3XmwrXWeeYCbgxcrD6YXxoAykBaWH0VdM= +k8s.io/client-go v0.20.2 h1:uuf+iIAbfnCSw8IGAv/Rg0giM+2bOzHLOsbbrwrdhNQ= +k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= +k8s.io/cloud-provider v0.20.2/go.mod h1:TiVc+qwBh37DNkirzDltXkbR6bdfOjfo243Tv/DyjGQ= +k8s.io/cluster-bootstrap v0.20.2/go.mod h1:2vQbXkXcZN1N6SnBlWBctKjARH9vj+Uzo4DPgzUJdqw= +k8s.io/code-generator v0.20.2 h1:SQaysped4EtUDk3u1zphnUJiOAwFdhHx9xS3WKAE0x8= +k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= +k8s.io/component-base v0.20.2 h1:LMmu5I0pLtwjpp5009KLuMGFqSc2S2isGw8t1hpYKLE= +k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= +k8s.io/component-helpers v0.20.2/go.mod h1:qeM6iAWGqIr+WE8n2QW2OK9XkpZkPNTxAoEv9jl40/I= +k8s.io/controller-manager v0.20.2/go.mod h1:5FKx8oDeIiQTanQnQNsLxu/8uUEX1TxDXjiSwRxhM+8= +k8s.io/cri-api v0.20.2/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/csi-translation-lib v0.20.2/go.mod h1:HJOHkHTe6b0ywtkR53MbLss5Y19X3pBqkYBxuN2f/B0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw= +k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= -k8s.io/helm v2.16.3+incompatible h1:MGUcXcG1uAXWZmxu4vzzgRjZOnfFUsSJbHgqM+kyqzM= -k8s.io/helm v2.16.3+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-aggregator v0.17.4 h1:eAOfeLRkYCJTSTIJsT3rwmgCnT3wW8vk/t97iBXZUF8= -k8s.io/kube-aggregator v0.17.4/go.mod h1:SGdBtKUKFTag+k3GmG7o14OfsSmoDGwSHAdKtfA9sYc= -k8s.io/kube-controller-manager v0.17.4 h1:vhDzpf6rrrm5BHS7AV/BxsYcWVk4PpYLhoJAvKZSmkk= -k8s.io/kube-controller-manager v0.17.4/go.mod h1:2HK/Z3L8XGnd/CGVpCVCKESMHh3xLZGuGtz9Y4Fdnto= -k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-proxy v0.17.4 h1:Q/v9HDhvlDWoDSNrLcWyxFj7xeAjEibSV560OpRGKX0= -k8s.io/kube-proxy v0.17.4/go.mod h1:edMfHKYk2LR4p2vMqsi9rI3ne0bTD53MSoDU/Q1SHbE= -k8s.io/kube-scheduler v0.17.4 h1:SClxOWbORVYP0wPRJK3E6wND9DJDEYQt0WkemrVaf40= -k8s.io/kube-scheduler v0.17.4/go.mod h1:Xu6+MQbo4pxk80I+9Lhq1Y5bftJqcjjLBWBTFMuEvSY= -k8s.io/kube-state-metrics v1.7.2 h1:6vdtgXrrRRMSgnyDmgua+qvgCYv954JNfxXAtDkeLVQ= -k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= -k8s.io/kubectl v0.17.4 h1:Ts0CvqvIVceS4RTVXgWMH+YqtieLAzyS2T9eoz8uDQ0= -k8s.io/kubectl v0.17.4/go.mod h1:im5QWmh6fvtmJkkNm4HToLe8z9aM3jihYK5X/wOybcY= -k8s.io/kubelet v0.17.4 h1:AwnTICJriwOTOLmVEX8AeSWMCkEfIJySstGUsdh2tA0= -k8s.io/kubelet v0.17.4/go.mod h1:LpY8egnY6pPFNyazV+nMncgsemaCEDwp6M7b5rv8TWU= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/kubernetes v1.17.4 h1:hnz5goC7sf4LyG9kjJv6eBBJ/8DeD6TL3UAdCoHpaJE= -k8s.io/kubernetes v1.17.4/go.mod h1:T2iWC2zSz7Nq5mQvvFPQB8mc2sEBIAdjMJPxavtZkcg= -k8s.io/legacy-cloud-providers v0.17.4 h1:VvFqJGiYAr2gIdoNuqbeZLEdxIFeN4Yt6OLJS9l2oIE= -k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js= -k8s.io/metrics v0.17.4 h1:nJ1K4wLLqt3V8p3xJwyYoiPDH74H+YNXr+wo/9pgUo0= -k8s.io/metrics v0.17.4/go.mod h1:6rylW2iD3M9VppnEAAtJASY1XS8Pt9tcYh+tHxBeV3I= -k8s.io/repo-infra v0.0.1-alpha.1 h1:2us1n30u3cOcoPsacNfCvCssS9B9Yldr1ZGOdK0728U= -k8s.io/repo-infra v0.0.1-alpha.1/go.mod h1:wO1t9WaB99V80ljbeENTnayuEEwNZt7gECYh/CEyOJ8= -k8s.io/sample-apiserver v0.17.4 h1:msMT5bYKx3IZKU7VcKs3MmLb1261jGZR1d0aILK5yH4= -k8s.io/sample-apiserver v0.17.4/go.mod h1:7eYWlWHpj30k51ClqD5rx3O0wchzA9Gw+/w64oYDvkA= -k8s.io/system-validators v1.0.4 h1:sW57tJ/ciqOVbbTLN+ZNy64MJMNqUuiwrirQv8IR2Kw= -k8s.io/system-validators v1.0.4/go.mod h1:HgSgTg4NAGNoYYjKsUyk52gdNi2PVDswQ9Iyn66R7NI= -k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6 h1:p0Ai3qVtkbCG/Af26dBmU0E1W58NID3hSSh7cMyylpM= -k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/kube-aggregator v0.20.2/go.mod h1:j7ks4pWm6cjXzlVZB9tewvUdg2njjbiFuHp575ZKnqc= +k8s.io/kube-controller-manager v0.20.2/go.mod h1:tEuBoNyKDqoHClDyLePZCs38XuVv5jCZGUm01MWJjII= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/kube-proxy v0.20.2/go.mod h1:l75PYLoA+hI6WAfT/2cFPUcWy8XWMFGvsyw8UXCNuJc= +k8s.io/kube-scheduler v0.20.2/go.mod h1:H21kpnQN7U3jRz/MwMxdGPC66UBuTibbq5LEy5AztBg= +k8s.io/kubectl v0.20.2/go.mod h1:/bchZw5fZWaGZxaRxxfDQKej/aDEtj/Tf9YSS4Jl0es= +k8s.io/kubelet v0.20.2/go.mod h1:i441hnZtH2wUiDNqpXVZYaNCqEOBd2sM7x2mV0n7dJs= +k8s.io/kubernetes v1.21.1 h1:U7cVOSdG+sMNOfL9XlenBV7avSBDHyWPE66gWnnYIIc= +k8s.io/kubernetes v1.21.1/go.mod h1:ef++isEL1PW0taH6z7DXrSztPglrZ7jQhyvcMEtm0gQ= +k8s.io/legacy-cloud-providers v0.20.2/go.mod h1:waU+hRRzS6RwPt2jK4RyVPbnLdEHUYowSB5WG3N6b8Y= +k8s.io/metrics v0.20.2/go.mod h1:yTck5nl5wt/lIeLcU6g0b8/AKJf2girwe0PQiaM4Mwk= +k8s.io/mount-utils v0.20.2/go.mod h1:Jv9NRZ5L2LF87A17GaGlArD+r3JAJdZFvo4XD1cG4Kc= +k8s.io/sample-apiserver v0.20.2/go.mod h1:Q4VuPfFr3WOSkv6XKmY8FukZESdtH5MWqO0umFDfHcM= +k8s.io/system-validators v1.4.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ= +k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0 h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0 h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0 h1:7ccXrupWZIS3twbUGrtKmHS2DXY6xegFua+6O3xgAFU= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 h1:duVSyluuJA+u0BnkcLR01smoLrGgDTfWt5c8ODYG8fU= -mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM= -rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= -sigs.k8s.io/controller-runtime v0.5.2 h1:pyXbUfoTo+HA3jeIfr0vgi+1WtmNh0CwlcnQGLXwsSw= -sigs.k8s.io/controller-runtime v0.5.2/go.mod h1:JZUwSMVbxDupo0lTJSSFP5pimEyxGynROImSsqIOx1A= -sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= -sigs.k8s.io/controller-tools v0.2.8 h1:UmYsnu89dn8/wBhjKL3lkGyaDGRnPDYUx2+iwXRnylA= -sigs.k8s.io/controller-tools v0.2.8/go.mod h1:9VKHPszmf2DHz/QmHkcfZoewO6BL7pPs9uAiBVsaJSE= -sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao= +sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU= +sigs.k8s.io/controller-tools v0.5.0 h1:3u2RCwOlp0cjCALAigpOcbAf50pE+kHSdueUosrC/AE= +sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= -vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc h1:MksmcCZQWAQJCTA5T0jgI/0sJ51AVm4Z41MrmfczEoc= -vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 00000000..45dbbbbc --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/mage/docker/lib.go b/mage/docker/lib.go deleted file mode 100644 index 39a2f4ce..00000000 --- a/mage/docker/lib.go +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package dockerutil - -import ( - "encoding/json" - "strings" - - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" -) - -// Internal datastax DNS addresses -// to use for distros (like Alpine) -// that do not query DNS servers in order. -var DatastaxDns = []string{"10.100.6.66", "10.100.6.67"} - -type DockerCmd struct { - Args []string - ConfigDir string - Input string - Env map[string]string -} - -func (cmd DockerCmd) ToCliArgs() []string { - var args []string - if cmd.ConfigDir != "" { - args = append(args, "--config", cmd.ConfigDir) - } - args = append(args, cmd.Args...) - return args -} - -func (cmd DockerCmd) WithCfg(cfgDir string) DockerCmd { - cmd.ConfigDir = cfgDir - return cmd -} - -func (cmd DockerCmd) WithInput(in string) DockerCmd { - cmd.Input = in - return cmd -} - -func FromArgs(args []string) DockerCmd { - return DockerCmd{Args: args} -} - -func FromArgsInput(args []string, in string) DockerCmd { - return DockerCmd{Args: args, Input: in} -} - -func exec(cmd DockerCmd, - withInput func(map[string]string, string, string, ...string) error, - withoutInput func(map[string]string, string, ...string) error) error { - - var err error - args := cmd.ToCliArgs() - if cmd.Input != "" { - err = withInput(cmd.Env, "docker", cmd.Input, args...) - - } else { - err = withoutInput(cmd.Env, "docker", args...) - } - return err -} - -func output(cmd DockerCmd, - withInput func(map[string]string, string, string, ...string) (string, error), - withoutInput func(map[string]string, string, ...string) (string, error)) (string, error) { - - var err error - var out string - args := cmd.ToCliArgs() - if cmd.Input != "" { - out, err = withInput(cmd.Env, "docker", cmd.Input, args...) - - } else { - out, err = withoutInput(cmd.Env, "docker", args...) - } - return out, err -} - -func (cmd DockerCmd) Exec() error { - return exec(cmd, shutil.RunWithEnvWithInput, shutil.RunWithEnv) -} - -func (cmd DockerCmd) ExecV() error { - return exec(cmd, shutil.RunVWithEnvWithInput, shutil.RunVWithEnv) -} - -func (cmd DockerCmd) ExecVPanic() { - err := exec(cmd, shutil.RunVWithEnvWithInput, shutil.RunVWithEnv) - mageutil.PanicOnError(err) -} - -func (cmd DockerCmd) Output() (string, error) { - return output(cmd, shutil.OutputWithEnvWithInput, shutil.OutputWithEnv) -} - -func (cmd DockerCmd) OutputPanic() string { - out, err := output(cmd, shutil.OutputWithEnvWithInput, shutil.OutputWithEnv) - mageutil.PanicOnError(err) - return out -} - -func Exec(containerId string, env []string, privileged bool, user string, workDir string, exec []string) DockerCmd { - args := []string{"exec"} - - for _, x := range env { - args = append(args, "--env") - args = append(args, x) - } - if privileged { - - args = append(args, "--privileged") - } - if user != "" { - args = append(args, "--user", user) - } - if workDir != "" { - args = append(args, "--workdir", workDir) - } - args = append(args, containerId) - args = append(args, exec...) - return FromArgs(args) -} - -func Run(imageName string, volumes []string, dnsAddrs []string, env []string, runArgs []string, execArgs []string) DockerCmd { - args := []string{"run", "--rm"} - - for _, x := range env { - args = append(args, "--env") - args = append(args, x) - } - for _, x := range dnsAddrs { - args = append(args, "--dns") - args = append(args, x) - } - for _, x := range volumes { - args = append(args, "-v") - args = append(args, x) - } - args = append(args, runArgs...) - args = append(args, imageName) - args = append(args, execArgs...) - return FromArgs(args) -} - -func Build(contextDir string, targetStage string, dockerFilePath string, namesAndTags []string, buildArgs []string) DockerCmd { - args := []string{"buildx", "build", contextDir} - - if targetStage != "" { - args = append(args, "--target") - args = append(args, targetStage) - } - if dockerFilePath != "" { - args = append(args, "-f") - args = append(args, dockerFilePath) - } - for _, x := range namesAndTags { - args = append(args, "-t") - args = append(args, x) - } - for _, x := range buildArgs { - args = append(args, "--build-arg") - args = append(args, x) - } - args = append(args, "--load") - args = append(args, "--cache-from") - args = append(args, "type=local,src=/tmp/.buildx-cache") - args = append(args, "--cache-to") - args = append(args, "type=local,dest=/tmp/.buildx-cache") - - c := FromArgs(args) - if c.Env == nil { - c.Env = map[string]string{} - } - - return c -} - -func Login(configDir string, user string, pw string, repo string) DockerCmd { - args := []string{ - "login", "-u", user, - "--password-stdin", - repo, - } - return FromArgsInput(args, pw) -} - -func Push(tag string) DockerCmd { - args := []string{"push", tag} - return FromArgs(args) -} - -func Tag(src string, target string) DockerCmd { - args := []string{"tag", src, target} - return FromArgs(args) -} - -type Container struct { - Id string `json:"ID"` - Image string `json:"Image"` - Command string `json:"Command"` - CreatedAt string `json:"CreatedAt"` - RunningFor string `json:"RunningFor"` - Status string `json:"Status"` - Size string `json:"Size"` - Names string `json:"Names"` - Labels string `json:"Labels"` - Mounts string `json:"Mounts"` - Networks string `json:"Networks"` - Ports string `json:"Ports"` - LocalVolumes string `json:"LocalVolumes"` -} - -func LsContainers(format string) DockerCmd { - args := []string{ - "container", "ls", - "--format", format, - "--no-trunc", - } - return FromArgs(args) -} - -func GetAllContainersPanic() []Container { - var containers []Container - format := "\"{{json .}}\"" - rawJson := LsContainers(format).OutputPanic() - for _, j := range strings.Split(rawJson, "\n") { - var c Container - //trim extra quotes around the json - js := strings.Trim(j, "\"") - err := json.Unmarshal([]byte(strings.TrimSpace(js)), &c) - mageutil.PanicOnError(err) - containers = append(containers, c) - } - return containers -} diff --git a/mage/ginkgo/lib.go b/mage/ginkgo/lib.go index 3399de70..98f40f4c 100644 --- a/mage/ginkgo/lib.go +++ b/mage/ginkgo/lib.go @@ -16,8 +16,6 @@ import ( ginkgo "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - helm_util "github.com/k8ssandra/cass-operator/mage/helm" "github.com/k8ssandra/cass-operator/mage/kubectl" mageutil "github.com/k8ssandra/cass-operator/mage/util" ) @@ -123,31 +121,8 @@ func (ns NsWrapper) Terminate() { // This is important because deleting the namespace itself // can hang if this step is skipped. kcmd := kubectl.Delete("cassandradatacenter", "--all") - _, dcErrOut, dcErr := ns.ExecVCapture(kcmd) - - // Must run helm uninstall before deleting namespace - // or else it won't see that it has an active release - // out there - _, helmErrOut, helmErr := helm_util.UninstallCapture("cass-operator", ns.Namespace) - - _, nsErrOut, nsErr := kubectl.DeleteByTypeAndName("namespace", ns.Namespace).ExecVCapture() - - var errMsgs []string - if dcErr != nil { - errMsgs = append(errMsgs, fmt.Sprintf("Error deleting datacenters: %v\n\t%s", dcErr.Error(), dcErrOut)) - } - if helmErr != nil { - errMsgs = append(errMsgs, fmt.Sprintf("Error performing helm uninstall: %v\n\t%s", helmErr.Error(), helmErrOut)) - } - if nsErr != nil { - errMsgs = append(errMsgs, fmt.Sprintf("Error deleting namespace: %v\n\t%s", nsErr.Error(), nsErrOut)) - } - - if len(errMsgs) > 0 { - msg := fmt.Sprintf("One or more errors occurred while cleaning up test resources.\n%s", strings.Join(errMsgs, "\n")) - err := fmt.Errorf(msg) - Expect(err).ToNot(HaveOccurred()) - } + _, _, dcErr := ns.ExecVCapture(kcmd) + Expect(dcErr).ToNot(HaveOccurred()) } //=================================== @@ -419,46 +394,6 @@ func CreateDockerRegistrySecret(name string, namespace string) { k.InNamespace(namespace).ExecVCapture() } -func (ns NsWrapper) HelmInstall(chartPath string, overrides ...string) { - overridesMap := map[string]string{} - for i := 0; i < len(overrides)-1; i = i + 2 { - overridesMap[overrides[i]] = overrides[i+1] - } - HelmInstallWithOverrides(chartPath, ns.Namespace, overridesMap) -} - -func (ns NsWrapper) HelmInstallWithPSPEnabled(chartPath string) { - var overrides = map[string]string{ - "vmwarePSPEnabled": "true", - } - HelmInstallWithOverrides(chartPath, ns.Namespace, overrides) -} - -// This is not a method on NsWrapper to allow mage to use it to create an example cluster. -func HelmInstallWithOverrides(chartPath string, namespace string, overrides map[string]string) { - overrides["image"] = cfgutil.GetOperatorImage() - - if kubectl.DockerCredentialsDefined() { - CreateDockerRegistrySecret(ImagePullSecretName, namespace) - overrides["imagePullSecret"] = ImagePullSecretName - } - - err := helm_util.Install(chartPath, "cass-operator", namespace, overrides) - mageutil.PanicOnError(err) -} - -func HelmUpgradeWithOverrides(chartPath string, namespace string, overrides map[string]string) { - overrides["image"] = cfgutil.GetOperatorImage() - - // NOTE: This assumes the credential has already been defined during HelmInstallWithOverrides - if kubectl.DockerCredentialsDefined() { - overrides["imagePullSecret"] = ImagePullSecretName - } - - err := helm_util.Upgrade(chartPath, "cass-operator", namespace, overrides) - mageutil.PanicOnError(err) -} - // Note that the actual value will be cast to a string before the comparison with the expectedValue func (ns NsWrapper) ExpectKeyValue(m map[string]interface{}, key string, expectedValue string) { actualValue, ok := m[key].(string) diff --git a/mage/helm/lib.go b/mage/helm/lib.go deleted file mode 100644 index d9c2ab90..00000000 --- a/mage/helm/lib.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package helm_util - -import ( - "fmt" - - shutil "github.com/k8ssandra/cass-operator/mage/sh" -) - -func buildOverrideArgs(overrides map[string]string) []string { - args := []string{} - if len(overrides) > 0 { - var overrideString = "" - for key, val := range overrides { - if overrideString == "" { - overrideString = fmt.Sprintf("%s=%s", key, val) - } else { - overrideString = fmt.Sprintf("%s,%s=%s", overrideString, key, val) - } - } - - args = append(args, "--set", overrideString) - } - return args -} - -func Install(chartPath string, releaseName string, namespace string, overrides map[string]string) error { - args := []string{ - "install", - fmt.Sprintf("--namespace=%s", namespace), - } - - args = append(args, buildOverrideArgs(overrides)...) - args = append(args, releaseName, chartPath) - return shutil.RunV("helm", args...) -} - -func Upgrade(chartPath string, releaseName string, namespace string, overrides map[string]string) error { - args := []string{ - "upgrade", - fmt.Sprintf("--namespace=%s", namespace), - } - - args = append(args, buildOverrideArgs(overrides)...) - args = append(args, releaseName, chartPath) - return shutil.RunV("helm", args...) -} - -func uninstallArgs(releaseName string, namespace string) []string { - return []string{ - "uninstall", - fmt.Sprintf("--namespace=%s", namespace), - releaseName, - } -} - -func Uninstall(releaseName string, namespace string) error { - return shutil.RunV("helm", uninstallArgs(releaseName, namespace)...) -} - -func UninstallCapture(releaseName string, namespace string) (string, string, error) { - return shutil.RunVCapture("helm", uninstallArgs(releaseName, namespace)...) -} diff --git a/mage/integ-tests/lib.go b/mage/integ-tests/lib.go deleted file mode 100644 index 3a73065c..00000000 --- a/mage/integ-tests/lib.go +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package integutil - -import ( - "fmt" - "io/ioutil" - "os" - "strings" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - k3d "github.com/k8ssandra/cass-operator/mage/k3d" - kind "github.com/k8ssandra/cass-operator/mage/kind" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" -) - -const ( - envIntegDir = "M_INTEG_DIR" - envGinkgoNoColor = "M_GINKGO_NOCOLOR" - envLoadTestImages = "M_LOAD_TEST_IMAGES" - envK8sFlavor = "M_K8S_FLAVOR" -) - -func getTestSuiteDirs() []string { - contents, err := ioutil.ReadDir("./tests") - mageutil.PanicOnError(err) - var testDirs []string - for _, info := range contents { - if info.IsDir() && info.Name() != "testdata" { - testDirs = append(testDirs, info.Name()) - } - } - return testDirs -} - -// Prints a comma-delimited list of test suite dirs. -// This is mainly useful for a CI pipeline. -func List() { - dirs := getTestSuiteDirs() - fmt.Println(strings.Join(dirs, ",")) -} - -func runGinkgoTestSuite(path string) { - os.Setenv("CGO_ENABLED", "0") - args := []string{ - "test", - "-timeout", "99999s", - "-v", - "--ginkgo.v", - "--ginkgo.progress", - } - noColor := os.Getenv(envGinkgoNoColor) - if strings.ToLower(noColor) == "true" { - args = append(args, "--ginkgo.noColor") - } - args = append(args, path) - - cwd, _ := os.Getwd() - - err := os.Chdir(path) - mageutil.PanicOnError(err) - - shutil.RunVPanic("go", args...) - - err = os.Chdir(cwd) - mageutil.PanicOnError(err) -} - -type testType int - -const ( - OSS testType = iota - UBI_OSS - - DSE - UBI_DSE - - // NOTE: This line MUST be last in the const expression - TestTypeEnumLength int = iota -) - -func getTestType(testDir string) testType { - lower := strings.ToLower(testDir) - isOss := true - isUbi := false - - if strings.Contains(lower, "_dse") || strings.Contains(lower, "dse_") { - isOss = false - } - - if strings.Contains(lower, "_ubi") || strings.Contains(lower, "ubi_") { - isUbi = true - } - - if isOss && isUbi { - return UBI_OSS - - } else if isOss { - return OSS - } else if !isOss && isUbi { - return UBI_DSE - } else { - return DSE - } -} - -func loadImagesFromBuildSettings(ca cfgutil.ClusterActions, bs cfgutil.BuildSettings, testType testType) { - dev := bs.Dev - // always load shared images - images := dev.SharedImages - - // also load specific images based on test type - switch testType { - case DSE: - images = append(images, dev.DseImages...) - case UBI_DSE: - images = append(images, dev.UbiDseImages...) - case OSS: - images = append(images, dev.OssImages...) - case UBI_OSS: - images = append(images, dev.UbiOssImages...) - } - - for _, image := range images { - // we likely don't always care if we fail to pull - // because we could be testing local images - _ = shutil.RunV("docker", "pull", image) - ca.LoadImage(image) - } -} - -func loadClusterActions() cfgutil.ClusterActions { - clusterType := mageutil.EnvOrDefault(envK8sFlavor, "kind") - - // We only care about pulling and loading images - // in this library, so we have a more narrow list of - // supported flavors than the more general k8s mage library - var supportedFlavors = map[string]cfgutil.ClusterActions{ - "kind": kind.ClusterActions, - "k3d": k3d.ClusterActions, - } - - if cfg, ok := supportedFlavors[clusterType]; ok { - return cfg - } else { - panic(fmt.Sprintf("Unsupported %s specified: %s", envK8sFlavor, clusterType)) - } -} - -func loadImagesForTest(testDir string) { - clusterActions := loadClusterActions() - buildSettings := cfgutil.ReadBuildSettings() - testType := getTestType(testDir) - loadImagesFromBuildSettings(clusterActions, buildSettings, testType) -} - -// Run ginkgo integration tests. -// -// Default behavior is to discover and run -// all test suites located under the ./tests/ directory. -// -// To run a subset of test suites, specify the name of the suite -// directories in env var M_INTEG_DIR, separated by a comma -// -// To pull and load images based on test type (DSE, OSS, UBI) -// set the env var M_LOAD_TEST_IMAGES to true -// -// Examples: -// M_INTEG_DIR=scale_up,stop_resume -// M_LOAD_TEST_IMAGES=true M_INTEG_DIR=scale_up -// -// This target assumes that helm is installed and available on path. -func Run() { - var testDirs []string - integDir := os.Getenv(envIntegDir) - if integDir != "" { - testDirs = strings.Split(integDir, ",") - } else { - testDirs = getTestSuiteDirs() - } - - for _, dir := range testDirs { - path := fmt.Sprintf("./tests/%s", dir) - loadTestImages := os.Getenv(envLoadTestImages) - if strings.ToLower(loadTestImages) == "true" { - fmt.Println("Pulling and loading images from buildsettings.yaml") - loadImagesForTest(dir) - } - - runGinkgoTestSuite(path) - } -} diff --git a/mage/integ-tests/lib_test.go b/mage/integ-tests/lib_test.go deleted file mode 100644 index 59d2909d..00000000 --- a/mage/integ-tests/lib_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package integutil - -import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -func tempSetEnv(name, value string) (func(), error) { - oldValue, wasDefined := os.LookupEnv(name) - restore := func() { - if !wasDefined { - _ = os.Unsetenv(name) - } else { - _ = os.Setenv(name, oldValue) - } - } - - err := os.Setenv(name, value) - return restore, err -} - -func Test_GetTestTypeDse(t *testing.T) { - testDir := "some_test" - testType := getTestType(testDir) - assert.Equal(t, DSE, testType) -} - -func Test_GetTestTypeUbiDse(t *testing.T) { - testDir := "some_test_ubi" - testType := getTestType(testDir) - assert.Equal(t, UBI_DSE, testType) -} - -func Test_GetTestTypeOss(t *testing.T) { - testDir := "some_oss_testing" - testType := getTestType(testDir) - assert.Equal(t, OSS, testType) -} - -func Test_GetTestTypeUbiOss(t *testing.T) { - testDir := "some_ubi_oss_test" - testType := getTestType(testDir) - assert.Equal(t, UBI_OSS, testType) -} diff --git a/mage/k3d/lib.go b/mage/k3d/lib.go deleted file mode 100644 index 654b81bb..00000000 --- a/mage/k3d/lib.go +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package k3d - -import ( - "fmt" - "io/ioutil" - "os" - "strings" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - dockerutil "github.com/k8ssandra/cass-operator/mage/docker" - "github.com/k8ssandra/cass-operator/mage/kubectl" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" -) - -const ( - clusterName = "k3s-default" - context = "k3d-k3s-default" -) - -var ClusterActions = cfgutil.NewClusterActions( - deleteCluster, - clusterExists, - createCluster, - loadImage, - install, - reloadLocalImage, - applyDefaultStorage, - setupKubeconfig, - describeEnv, -) - -func describeEnv() map[string]string { - return make(map[string]string) -} - -func deleteCluster() error { - return shutil.RunV("k3d", "cluster", "delete", clusterName) -} - -func clusterExists() bool { - err := shutil.RunV("k3d", "cluster", "ls", clusterName) - return err == nil -} - -func createCluster() { - // just incase we get some flakiness with docker - // while creating a cluster, we want to - // give it a few chances to redeem itself - // after failing - retries := 5 - var err error - for retries > 0 { - err = shutil.RunV( - "k3d", - "cluster", - "create", - "-s", "6", - "--image", - "rancher/k3s:v1.17.6-k3s1", - ) - if err != nil { - fmt.Printf("k3d failed to create the cluster. %v retries left.\n", retries) - retries-- - } else { - return - } - } - mageutil.PanicOnError(err) -} - -func loadImage(image string) { - fmt.Printf("Loading image in k3d: %s", image) - shutil.RunVPanic("k3d", "image", "import", image) -} - -func install() { - cwd, err := os.Getwd() - mageutil.PanicOnError(err) - os.Chdir("/tmp") - shutil.RunVPanic("curl", - "https://raw.githubusercontent.com/rancher/k3d/main/install.sh", - "-o", "k3d_install.sh", - ) - os.Setenv("TAG", "v3.0.1") - os.Chmod("./k3d_install.sh", 0755) - shutil.RunVPanic("./k3d_install.sh") - os.Chdir(cwd) -} - -// Load the latest copy of a local image into k3d -func reloadLocalImage(image string) { - fullImage := fmt.Sprintf("docker.io/%s", image) - containers := dockerutil.GetAllContainersPanic() - for _, c := range containers { - if strings.HasPrefix(c.Image, "k3d-k3s") { - fmt.Printf("Deleting old image from Docker container: %s\n", c.Id) - execArgs := []string{"crictl", "rmi", fullImage} - //TODO properly check for existing image before deleting.. - _ = dockerutil.Exec(c.Id, nil, false, "", "", execArgs).ExecV() - } - } - fmt.Println("Loading new operator Docker image into k3d cluster") - shutil.RunVPanic("k3d", "image", "import", image) - fmt.Println("Finished loading new operator image into k3d.") -} - -func setupKubeconfig() { - currentConfig := kubectl.GetKubeconfig(true) - - //k3d returns the raw config values instead of a filepath - k3dConfig := shutil.OutputPanic("k3d", "kubeconfig", "get", clusterName) - tempK3dConfigFile := "/tmp/k3d_temp_config" - ioutil.WriteFile(tempK3dConfigFile, []byte(k3dConfig), os.ModePerm) - os.Chmod(tempK3dConfigFile, 0755) - - // merge current config + new k3d config - // the new config must appear before the current config to update it - // when merging - configPaths := fmt.Sprintf("%s:%s", tempK3dConfigFile, currentConfig) - os.Setenv("KUBECONFIG", configPaths) - fmt.Printf("Merging KUBECONFIG from: %s\n", configPaths) - merged := shutil.OutputPanic("kubectl", "config", "view", "--flatten") - - // look up current config file so we can retain its permissions - // before overwriting - configInfo, err := os.Stat(currentConfig) - mageutil.PanicOnError(err) - - // overwrite current config file with the merged file - err = ioutil.WriteFile(currentConfig, []byte(fmt.Sprintf("%s\n", merged)), configInfo.Mode()) - if err != nil { - fmt.Printf("Failed to write kubeconfig file at %s\n", currentConfig) - panic(err) - } - - kubectl.ClusterInfoForContext(context).ExecVPanic() -} - -func applyDefaultStorage() { - kubectl.ApplyFiles("operator/k8s-flavors/kind/rancher-local-path-storage.yaml"). - ExecVPanic() -} diff --git a/mage/k8s/lib.go b/mage/k8s/lib.go deleted file mode 100644 index a0c3b203..00000000 --- a/mage/k8s/lib.go +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package k8sutil - -import ( - "fmt" - "os" - "strings" - "time" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - gcp "github.com/k8ssandra/cass-operator/mage/gcloud" - ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" - integutil "github.com/k8ssandra/cass-operator/mage/integ-tests" - k3d "github.com/k8ssandra/cass-operator/mage/k3d" - kind "github.com/k8ssandra/cass-operator/mage/kind" - "github.com/k8ssandra/cass-operator/mage/kubectl" - "github.com/k8ssandra/cass-operator/mage/operator" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" - "github.com/magefile/mage/mg" -) - -const ( - OperatorImage = "k8ssandra/cass-operator:latest" - OperatorImageUBI = "k8ssandra/cass-operator:latest-ubi" - envLoadDevImages = "M_LOAD_DEV_IMAGES" - envK8sFlavor = "M_K8S_FLAVOR" -) - -var clusterActions *cfgutil.ClusterActions -var clusterType string - -var supportedFlavors = map[string]cfgutil.ClusterActions{ - "kind": kind.ClusterActions, - "k3d": k3d.ClusterActions, - "gke": gcp.ClusterActions, -} - -func getOperatorImage() string { - var img string - if baseOs := os.Getenv(operator.EnvBaseOs); baseOs != "" { - img = "k8ssandra/cass-operator:latest-ubi" - } else { - img = "k8ssandra/cass-operator:latest" - } - return img -} - -func loadImagesFromBuildSettings(cfg cfgutil.ClusterActions, settings cfgutil.BuildSettings) { - // load all images regardless of if they are dse or oss specific - dev := settings.Dev - images := dev.DseImages - images = append(images, dev.UbiDseImages...) - images = append(images, dev.OssImages...) - images = append(images, dev.UbiOssImages...) - images = append(images, dev.SharedImages...) - for _, image := range images { - // we likely don't always care if we fail to pull - // because we could be testing local images - _ = shutil.RunV("docker", "pull", image) - cfg.LoadImage(image) - } -} - -func loadSettings(cfg cfgutil.ClusterActions) { - loadDevImages := os.Getenv(envLoadDevImages) - if strings.ToLower(loadDevImages) == "true" { - fmt.Println("Pulling and loading images from buildsettings.yaml") - settings := cfgutil.ReadBuildSettings() - loadImagesFromBuildSettings(cfg, settings) - } -} - -// There is potential for globally scoped resources to be left -// over from a previous helm install -func cleanupLingeringHelmResources() { - _ = kubectl.DeleteByTypeAndName("clusterrole", "cass-operator-cluster-role").ExecV() - _ = kubectl.DeleteByTypeAndName("clusterrolebinding", "cass-operator").ExecV() - _ = kubectl.DeleteByTypeAndName("validatingwebhookconfiguration", "cassandradatacenter-webhook-registration").ExecV() - _ = kubectl.DeleteByTypeAndName("crd", "cassandradatacenters.cassandra.datastax.com").ExecV() -} - -func loadClusterSettings() { - if clusterType == "" { - // Default to kind because it is more reliable - clusterType = mageutil.EnvOrDefault(envK8sFlavor, "kind") - } - - if clusterActions == nil { - if cfg, ok := supportedFlavors[clusterType]; ok { - clusterActions = &cfg - } else { - panic(fmt.Sprintf("Unsupported %s specified: %s", envK8sFlavor, clusterType)) - } - } -} - -// Stand up an empty cluster. -// -// This will also configure kubectl to point -// at the new cluster. -// -// Set M_LOAD_DEV_IMAGES to "true" to pull and -// load the dev images listed in buildsettings.yaml -// into the cluster. -func SetupEmptyCluster() { - loadClusterSettings() - clusterActions.DeleteCluster() - clusterActions.CreateCluster() - // some clusters need a few seconds before we can get kubeconfig info - time.Sleep(10 * time.Second) - clusterActions.SetupKubeconfig() - loadSettings(*clusterActions) - clusterActions.ApplyDefaultStorage() - //TODO make this part optional - operator.BuildDocker() - operatorImg := getOperatorImage() - clusterActions.LoadImage(operatorImg) -} - -// Bootstrap a cluster, then run Ginkgo integration tests. -// -// Default behavior is to discover and run -// all test suites located under the ./tests/ directory. -// -// To run a subset of test suites, specify the name of the suite -// directories in env var M_INTEG_DIR, separated by a comma -// -// Example: -// M_INTEG_DIR=scale_up,stop_resume -// -// This target assumes that helm is installed and available on path. -func RunIntegTests() { - loadClusterSettings() - mg.Deps(SetupEmptyCluster) - integutil.Run() - noCleanup := os.Getenv(ginkgo_util.EnvNoCleanup) - if strings.ToLower(noCleanup) != "true" { - err := clusterActions.DeleteCluster() - mageutil.PanicOnError(err) - } -} - -// Perform all the steps to stand up an example cluster, -// except for applying the final cassandra yaml specification. -// This must either be applied manually or by calling SetupCassandraCluster -// or SetupDSECluster. -// This target assumes that helm is installed and available on path. -func SetupExampleCluster() { - mg.Deps(SetupEmptyCluster) - kubectl.CreateSecretLiteral("cassandra-superuser-secret", "devuser", "devpass").ExecVPanic() - - var namespace = "default" - overrides := map[string]string{} - - ginkgo_util.HelmInstallWithOverrides("./charts/cass-operator-chart", namespace, overrides) - - // Wait for 15 seconds for the operator to come up - // because the apiserver will call the webhook too soon and fail if we do not wait - time.Sleep(time.Second * 15) -} - -// Stand up an example cluster running Apache Cassandra. -// Loads all necessary resources to get a running Apache Cassandra data center and operator -// This target assumes that helm is installed and available on path. -func SetupCassandraCluster() { - mg.Deps(SetupExampleCluster) - kubectl.ApplyFiles( - "operator/example-cassdc-yaml/cassandra-3.11.x/example-cassdc-minimal.yaml", - ).ExecVPanic() - kubectl.WatchPods() -} - -// Stand up an example cluster running DSE 6.8. -// Loads all necessary resources to get a running DCE data center and operator -// This target assumes that helm is installed and available on path. -func SetupDSECluster() { - mg.Deps(SetupExampleCluster) - kubectl.ApplyFiles( - "operator/example-cassdc-yaml/dse-6.8.x/example-cassdc-minimal.yaml", - ).ExecVPanic() - kubectl.WatchPods() -} - -// Delete a running cluster. -func DeleteCluster() { - loadClusterSettings() - err := clusterActions.DeleteCluster() - mageutil.PanicOnError(err) -} - -// Cleanup potential previous integ test resources. -func EnsureEmptyCluster() { - loadClusterSettings() - if !clusterActions.ClusterExists() { - SetupEmptyCluster() - } else { - // always load settings in case we have new images - // that an existing cluster is missing - loadSettings(*clusterActions) - // make sure kubectl is pointing to our cluster - clusterActions.SetupKubeconfig() - // we should still ensure that the storage is set up - // correctly every time - clusterActions.ApplyDefaultStorage() - // we still need to build and load an updated - // set of our local operator images - operator.BuildDocker() - clusterActions.ReloadLocalImage(OperatorImage) - } - - //Find any lingering test namespaces and delete them - output := kubectl.Get("namespaces").OutputPanic() - rows := strings.Split(output, "\n") - for _, row := range rows { - name := strings.Fields(row)[0] - if strings.HasPrefix(name, "test-") { - fmt.Printf("Cleaning up namespace: %s\n", name) - // check if any cassdcs exist in the namespace. - // kubectl will return an error if the crd has not been - // applied first - err := kubectl.Get("cassdc").InNamespace(name).ExecV() - if err == nil { - // safe to perform a delete cassdcs --all at this point - err := kubectl.Delete("cassdcs", "--all"). - InNamespace(name). - ExecV() - - // if we fail to delete a dc, then we cannot delete the - // namespace because k8s will get stuck, so we need - // to stop execution here - mageutil.PanicOnError(err) - } - kubectl.DeleteByTypeAndName("namespace", name).ExecVPanic() - } - } - cleanupLingeringHelmResources() -} - -// Rebuild and load local operator image -// into cluster. -func ReloadOperator() { - loadClusterSettings() - operator.BuildDocker() - clusterActions.ReloadLocalImage(OperatorImage) -} - -// List k8s flavors that we support -// automating development workflows for -func ListSupportedFlavors() { - fmt.Println("--------------------------------------------------------------") - fmt.Printf("%s can be set to one of the following k8s flavors\n", envK8sFlavor) - fmt.Println("--------------------------------------------------------------") - for key := range supportedFlavors { - fmt.Println(key) - } - fmt.Println("--------------------------------------------------------------") -} - -// List environment variables that -// can be set for the specified cluster. -func Env() { - loadClusterSettings() - - // Env available for all cluster actions - fmt.Println("--------------------------------------------------------------") - fmt.Println(" Environment variables to be used in any cluster") - fmt.Println("--------------------------------------------------------------") - fmt.Printf("%s - If set to true, will load local dev images into cluster\n", envLoadDevImages) - fmt.Printf("%s - The type of k8s cluster to use. Run the listSupportedFlavors mage target for more info.\n", envK8sFlavor) - - fmt.Println("\n--------------------------------------------------------------") - fmt.Printf(" Environment variables specific to the specific cluster: %s\n", clusterType) - fmt.Println("--------------------------------------------------------------") - clusterSpecific := clusterActions.DescribeEnv() - - if len(clusterSpecific) == 0 { - fmt.Println("") - } else { - for key := range clusterSpecific { - fmt.Printf("%s - %s\n", key, clusterSpecific[key]) - } - } -} - -// If available, install the cli -// tool associated with the chosen k8s flavor -func InstallTool() { - loadClusterSettings() - clusterActions.InstallTool() -} - -// Configure kubectl to point to the specified cluster -func Kubeconfig() { - loadClusterSettings() - clusterActions.SetupKubeconfig() -} diff --git a/mage/kind/lib.go b/mage/kind/lib.go deleted file mode 100644 index 489dba55..00000000 --- a/mage/kind/lib.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package kind - -import ( - "fmt" - "os" - "strings" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - dockerutil "github.com/k8ssandra/cass-operator/mage/docker" - "github.com/k8ssandra/cass-operator/mage/kubectl" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" -) - -var ClusterActions = cfgutil.NewClusterActions( - deleteCluster, - clusterExists, - createCluster, - loadImage, - install, - reloadLocalImage, - applyDefaultStorage, - setupKubeconfig, - describeEnv, -) - -const ( - kindConfigPath = "M_KIND_CONFIG" -) - -func describeEnv() map[string]string { - return make(map[string]string) -} - -func applyDefaultStorage() { - kubectl.ApplyFiles("operator/k8s-flavors/kind/rancher-local-path-storage.yaml"). - ExecVPanic() -} - -func setupKubeconfig() { - kubectl.ClusterInfoForContext("kind-kind").ExecVPanic() -} - -func deleteCluster() error { - return shutil.RunV("kind", "delete", "cluster") -} - -func clusterExists() bool { - out := shutil.OutputPanic("kind", "get", "clusters") - return strings.TrimSpace(out) == "kind" -} - -func createCluster() { - config := mageutil.FromEnvOrDefault(kindConfigPath, "tests/testdata/kind/kind_config_6_workers.yaml") - - // Kind can be flaky when starting up a new cluster - // so let's give it a few chances to redeem itself - // after failing - retries := 5 - var err error - for retries > 0 { - // We explicitly request a kubernetes v1.15 cluster with --image - err = shutil.RunV( - "kind", - "create", - "cluster", - "--config", - config, - "--image", - "kindest/node:v1.17.11@sha256:5240a7a2c34bf241afb54ac05669f8a46661912eab05705d660971eeb12f6555", - "--wait", "600s", - ) - - if err != nil { - fmt.Printf("KIND failed to create the cluster. %v retries left.\n", retries) - retries-- - } else { - return - } - } - mageutil.PanicOnError(err) -} - -func loadImage(image string) { - fmt.Printf("Loading image in kind: %s", image) - shutil.RunVPanic("kind", "load", "docker-image", image) -} - -// Currently there is no concept of "global tool install" -// with the go cli. With the new module system, your project's -// go.mod and go.sum files will be updated with new dependencies -// even though we only care about getting a tool installed. -// -// To get around this, we run the go cli from the /tmp directory -// and our project will remain untouched. -func install() { - cwd, err := os.Getwd() - mageutil.PanicOnError(err) - os.Chdir("/tmp") - os.Setenv("GO111MODULE", "on") - shutil.RunVPanic("go", "get", "sigs.k8s.io/kind@v0.9.0") - os.Chdir(cwd) -} - -// Load the latest copy of a local image into kind -func reloadLocalImage(image string) { - fullImage := fmt.Sprintf("docker.io/%s", image) - containers := dockerutil.GetAllContainersPanic() - for _, c := range containers { - if strings.HasPrefix(c.Image, "kindest") { - fmt.Printf("Deleting old image from Docker container: %s\n", c.Id) - execArgs := []string{"crictl", "rmi", fullImage} - //TODO properly check for existing image before deleting.. - _ = dockerutil.Exec(c.Id, nil, false, "", "", execArgs).ExecV() - } - } - fmt.Println("Loading new operator Docker image into KIND cluster") - shutil.RunVPanic("kind", "load", "docker-image", image) - fmt.Println("Finished loading new operator image into Kind.") -} diff --git a/mage/operator/crd.patch b/mage/operator/crd.patch deleted file mode 100644 index fe77b064..00000000 --- a/mage/operator/crd.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml b/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml -index 06ac756..eef439b 100644 ---- a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml -+++ b/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml -@@ -1378,10 +1378,6 @@ spec: - - containerPort - type: object - type: array -- x-kubernetes-list-map-keys: -- - containerPort -- - protocol -- x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if -@@ -3710,10 +3706,6 @@ spec: - - containerPort - type: object - type: array -- x-kubernetes-list-map-keys: -- - containerPort -- - protocol -- x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if -@@ -4644,10 +4636,6 @@ spec: - - whenUnsatisfiable - type: object - type: array -- x-kubernetes-list-map-keys: -- - topologyKey -- - whenUnsatisfiable -- x-kubernetes-list-type: map - volumes: - description: 'List of volumes that can be mounted by containers - belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' diff --git a/mage/operator/deploy.go b/mage/operator/deploy.go deleted file mode 100644 index 51bfc2eb..00000000 --- a/mage/operator/deploy.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package operator - -import ( - "fmt" - "os" - "regexp" - "strings" - - dockerutil "github.com/k8ssandra/cass-operator/mage/docker" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" -) - -const ( - envArtifactoryUser = "MO_ART_USR" - envArtifactoryPw = "MO_ART_PSW" - envEcrId = "MO_ECR_ID" - envEcrSecret = "MO_ECR_SECRET" - envTags = "MO_TAGS" - envArtRepo = "MO_ART_REPO" - envEcrRepo = "MO_ECR_REPO" - envGHUser = "MO_GH_USR" - envGHToken = "MO_GH_TOKEN" - envGHPackageRepo = "MO_GH_PKG_REPO" - ghPackagesRegistry = "docker.pkg.github.com" -) - -func dockerTag(src string, target string) { - fmt.Println("- Re-tagging image:") - fmt.Printf(" %s\n", src) - fmt.Printf(" --> %s\n", target) - dockerutil.Tag(src, target).ExecVPanic() -} - -// This function is meant to simply retag a -// locally built image by adding a remote url -// to the front of it. -func retagLocalImageForRemotePush(localTag string, remoteUrl string) string { - newTag := fmt.Sprintf("%s/%s", remoteUrl, localTag) - dockerTag(localTag, newTag) - return newTag -} - -func retagAndPush(tags []string, remoteUrl string) { - for _, t := range tags { - newTag := retagLocalImageForRemotePush(strings.TrimSpace(t), remoteUrl) - fmt.Printf("- Pushing image %s\n", newTag) - dockerutil.Push(newTag).WithCfg(rootBuildDir).ExecVPanic() - } -} - -// Github packages expect the image tags to be in a specific format -// related to your repo, so we have extra logic to massage -// the tags into the format: //: -func retagAndPushForGH(tags []string) { - pkgRepo := mageutil.RequireEnv(envGHPackageRepo) - reg := regexp.MustCompile(`.*\:`) - for _, t := range tags { - tag := strings.TrimSpace(t) - updatedTag := reg.ReplaceAllString(tag, fmt.Sprintf("%s:", pkgRepo)) - fullGHTag := fmt.Sprintf("%s/%s", ghPackagesRegistry, strings.TrimSpace(updatedTag)) - dockerTag(tag, fullGHTag) - fmt.Printf("- Pushing image %s\n", fullGHTag) - dockerutil.Push(fullGHTag).WithCfg(rootBuildDir).ExecVPanic() - } -} - -func awsDockerLogin(keyId string, keySecret string) { - os.Setenv("AWS_ACCESS_KEY_ID", keyId) - os.Setenv("AWS_SECRET_ACCESS_KEY", keySecret) - loginStr := shutil.OutputPanic("aws", "ecr", "get-login", "--no-include-email", "--region", "us-east-1") - args := strings.Split(loginStr, " ") - err := dockerutil.FromArgs(args[1:len(args)]).WithCfg(rootBuildDir).ExecV() - if err != nil { - // Don't print the actual error message here, because it could - // contain a valid ECR token that expires in 12 hours - e := fmt.Errorf("Failed to login to ECR via docker cli") - panic(e) - } -} - -// Deploy operator image to ECR. -// -// Most test workflows for Cassandra as a Service rely on operator container -// images being available from the Elastic Container Registry. We typically -// push PR builds here to enable easy testing of work prior to merge. -// -// This target assumes that you have several environment variables set: -// MO_ECR_ID - ECR access key ID -// MO_ECR_SECRET - ECR secret access key -// MO_TAGS - pipe-delimited docker tags to retag/push to ECR -func DeployToECR() { - ecrRepo := mageutil.RequireEnv(envEcrRepo) - keyId := mageutil.RequireEnv(envEcrId) - keySecret := mageutil.RequireEnv(envEcrSecret) - awsDockerLogin(keyId, keySecret) - tags := mageutil.RequireEnv(envTags) - retagAndPush(strings.Split(tags, "|"), ecrRepo) -} - -// Deploy operator image to artifactory. -// -// Most of our internal end-to-end tests rely on operator container images -// being available from the Docker repository in Artifactory. Artifactory -// can get overloaded and so we typically push only commits to stable branches. -// -// This target assumes that you have several environment variables set: -// MO_ART_USR - artifactory user -// MO_ART_PSW - artifactory password/api key -// MO_TAGS - pipe-delimited docker tags to retag/push to Artifactory -func DeployToArtifactory() { - artifactoryRepo := mageutil.RequireEnv(envArtRepo) - user := mageutil.RequireEnv(envArtifactoryUser) - pw := mageutil.RequireEnv(envArtifactoryPw) - dockerutil.Login(rootBuildDir, user, pw, artifactoryRepo). - WithCfg(rootBuildDir).ExecVPanic() - tags := mageutil.RequireEnv(envTags) - retagAndPush(strings.Split(tags, "|"), artifactoryRepo) -} - -// Deploy operator image to Github packages. -// -// This target assumes that you have several environment variables set: -// MO_GH_USR - github user -// MO_GH_TOKEN - github token -// MO_TAGS - pipe-delimited docker tags to retag/push to Github packages -func DeployToGHPackages() { - user := mageutil.RequireEnv(envGHUser) - pw := mageutil.RequireEnv(envGHToken) - dockerutil.Login(rootBuildDir, user, pw, ghPackagesRegistry). - WithCfg(rootBuildDir).ExecVPanic() - tags := mageutil.RequireEnv(envTags) - retagAndPushForGH(strings.Split(tags, "|")) -} diff --git a/mage/operator/lib.go b/mage/operator/lib.go deleted file mode 100644 index 66bc0b31..00000000 --- a/mage/operator/lib.go +++ /dev/null @@ -1,597 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package operator - -import ( - "bufio" - "fmt" - "io/ioutil" - "os" - "os/user" - "path/filepath" - "runtime" - "strings" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - dockerutil "github.com/k8ssandra/cass-operator/mage/docker" - gitutil "github.com/k8ssandra/cass-operator/mage/git" - shutil "github.com/k8ssandra/cass-operator/mage/sh" - mageutil "github.com/k8ssandra/cass-operator/mage/util" - "github.com/magefile/mage/mg" - "gopkg.in/yaml.v2" -) - -const ( - dockerBase = "./operator/docker/base/Dockerfile" - cassOperatorTarget = "cass-operator" - cassOperatorUbiTarget = "cass-operator-ubi" - dockerUbi = "./operator/docker/ubi/Dockerfile" - rootBuildDir = "./build" - sdkBuildDir = "operator/build" - diagramsDir = "./docs/developer/diagrams" - operatorSdkImage = "operator-sdk-binary" - testSdkImage = "operator-sdk-binary-tester" - genClientImage = "operator-gen-client" - mermaidJsImage = "operator-mermaid-js" - generatedDseDataCentersCrd = "operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml" - helmChartCrd = "charts/cass-operator-chart/templates/customresourcedefinition.yaml" - packagePath = "github.com/k8ssandra/cass-operator/operator" - envGitBranch = "MO_BRANCH" - envVersionString = "MO_VERSION" - envGitHash = "MO_HASH" - EnvBaseOs = "MO_BASE_OS" - - errorUnstagedPreGenerate = ` - Unstaged changes detected. - - Please clean your working tree of - uncommitted changes before running this target.` - - errorUnstagedPostSdkGenerate = ` - Unstaged changes found after running "operator-sdk generate" - - This indicates that the operator-sdk - updated some boilerplate in your working tree. - - You may be able commit these changes if you have - intentionally modified a resource spec and wish - to update the sdk boilerplate, but be careful - with backwards compatibility.` - - errorUnstagedPostClientGenerate = ` - Unstaged changes found after running the generate-groups.sh - script from the k8s code-generator. - - This indicates that the code-generator - updated some boilerplate in your working tree. - - You may be able commit these changes if you have - intentionally modified something that caused a - client change and wish to update the client boilerplate, - but be careful with backwards compatibility.` -) - -// check unstaged changes and exit with the changes if they are present -func checkForUnstagedChanges(message string) { - if unstagedChanges := gitutil.GetUnstagedChanges(); unstagedChanges != "" { - err := fmt.Errorf(message + "\n\n" + unstagedChanges) - panic(err) - } -} - -func writeBuildFile(fileName string, contents string) { - mageutil.EnsureDir(rootBuildDir) - outputPath := filepath.Join(rootBuildDir, fileName) - err := ioutil.WriteFile(outputPath, []byte(contents), 0666) - if err != nil { - fmt.Printf("Failed to write file at %s\n", outputPath) - panic(err) - } -} - -func runGoModVendor() { - os.Setenv("GO111MODULE", "on") - shutil.RunVPanic("go", "mod", "tidy") - shutil.RunVPanic("go", "mod", "download") - shutil.RunVPanic("go", "mod", "vendor") -} - -// Generate operator-sdk-binary docker image -func createSdkDockerImage() { - dockerutil.Build("./", "install-operator-sdk", "tools/operator-sdk/Dockerfile", - []string{operatorSdkImage}, nil).ExecVPanic() -} - -// Generate operator-sdk-binary-tester docker image -func createTestSdkDockerImage() { - dockerutil.Build("./", "test-operator-sdk", "tools/operator-sdk/Dockerfile", - []string{testSdkImage}, nil).ExecVPanic() -} - -// generate the files and clean up afterwards -func generateK8sAndOpenApi() { - cwd, _ := os.Getwd() - runArgs := []string{"-t", "--rm"} - repoPath := "/go/src/github.com/k8ssandra/cass-operator" - execArgs := []string{ - "/bin/bash", "-c", - fmt.Sprintf("set -eufx; export GO111MODULE=on; cd %s/operator && operator-sdk generate k8s && operator-sdk generate crds && rm -rf build", repoPath), - } - volumes := []string{fmt.Sprintf("%s:%s", cwd, repoPath)} - dockerutil.Run(operatorSdkImage, volumes, nil, nil, runArgs, execArgs).ExecVPanic() -} - -type yamlWalker struct { - yaml map[interface{}]interface{} - err error - editsMade bool -} - -func (y *yamlWalker) walk(key string) { - if y.err != nil { - return - } - val, ok := y.yaml[key] - if !ok { - y.err = fmt.Errorf("walk failed on %s", key) - } else { - y.yaml = val.(map[interface{}]interface{}) - } -} - -func (y *yamlWalker) remove(key string) { - if y.err != nil { - return - } - delete(y.yaml, key) - y.editsMade = true -} - -func (y *yamlWalker) update(key string, val interface{}) { - if y.err != nil { - return - } - y.yaml[key] = val - y.editsMade = true -} - -func (y *yamlWalker) get(key string) (interface{}, bool) { - val, ok := y.yaml[key] - return val, ok -} - -func ensurePreserveUnknownFields(data map[interface{}]interface{}) yamlWalker { - // Ensure the openAPI and k8s allow unrecognized fields. - // See postProcessCrd for why. - walker := yamlWalker{yaml: data, err: nil, editsMade: false} - preserve := "x-kubernetes-preserve-unknown-fields" - walker.walk("spec") - walker.walk("validation") - walker.walk("openAPIV3Schema") - if presVal, exists := walker.get(preserve); !exists || presVal != true { - walker.update(preserve, true) - } - return walker -} - -func removeConfigSection(data map[interface{}]interface{}) yamlWalker { - // Strip the config section from the CRD. - // See postProcessCrd for why. x := data["spec"].(t) - walker := yamlWalker{yaml: data, err: nil, editsMade: false} - walker.walk("spec") - walker.walk("validation") - walker.walk("openAPIV3Schema") - walker.walk("properties") - walker.walk("spec") - walker.walk("properties") - if _, exists := walker.get("config"); exists { - walker.remove("config") - } - return walker -} - -func postProcessCrd() { - // Remove the "config" section from the CRD, and enable - // x-kubernetes-preserve-unknown-fields. - // - // This is necessary because the config field has a dynamic - // schema which depends on the DSE version selected, and - // dynamic schema aren't possible to fully specify and - // validate via openAPI V3. - // - // Instead, we remove the config field from the schema - // entirely and instruct openAPI/k8s to preserve fields even - // if they aren't specified in the CRD. The field itself is defined - // as a json.RawMessage, see dsedatacenter_types.go in the - // api's subdirectory for details. - // - // We might be able to remove this when this lands: - // [kubernetes-sigs/controller-tools#345](https://github.com/kubernetes-sigs/controller-tools/pull/345) - - var data map[interface{}]interface{} - d, err := ioutil.ReadFile(generatedDseDataCentersCrd) - mageutil.PanicOnError(err) - - err = yaml.Unmarshal(d, &data) - mageutil.PanicOnError(err) - - w1 := ensurePreserveUnknownFields(data) - mageutil.PanicOnError(w1.err) - - w2 := removeConfigSection(data) - mageutil.PanicOnError(w2.err) - - if w1.editsMade || w2.editsMade { - updated, err := yaml.Marshal(data) - mageutil.PanicOnError(err) - - err = ioutil.WriteFile(generatedDseDataCentersCrd, updated, os.ModePerm) - mageutil.PanicOnError(err) - } -} - -func doSdkGenerate() { - cwd, _ := os.Getwd() - os.Chdir("operator") - runGoModVendor() - os.Chdir(cwd) - - // This is needed for operator-sdk generate k8s to run - os.MkdirAll(sdkBuildDir, os.ModePerm) - shutil.RunVPanic("touch", fmt.Sprintf("%s/Dockerfile", sdkBuildDir)) - - generateK8sAndOpenApi() - postProcessCrd() - patchCrdToTemplate() -} - -func cpCrdToChart() { - crd, err := ioutil.ReadFile(generatedDseDataCentersCrd) - mageutil.PanicOnError(err) - - err = ioutil.WriteFile(helmChartCrd, crd, os.ModePerm) - mageutil.PanicOnError(err) -} - -func patchCrdToTemplate() { - shutil.RunVPanic("patch", generatedDseDataCentersCrd, "mage/operator/crd.patch", "-o", helmChartCrd) -} - -// Generate files with the operator-sdk. -// -// This launches a docker container and executes `operator-sdk generate` -// with the k8s and kube-openapi code-generators -// -// The k8s code-generator currently only generates DeepCopy() functions -// for all custom resource types under pkg/apis/... -// -// The kube-openapi code-generator generates a crd yaml file for -// every custom resource under pkg/apis/... that are tagged for OpenAPIv3. -// The generated crd files are located under deploy/crds/... -func SdkGenerate() { - fmt.Println("- Updating operator-sdk generated files") - createSdkDockerImage() - doSdkGenerate() -} - -// Test that asserts that boilerplate files generated by the operator SDK are up to date. -// -// Ensures that we don't change the DseDatacenterSpec without also regenerating -// the boilerplate files that the Operator SDK manages which depend on that spec. -// -// Note: this test WILL UPDATE YOUR WORKING DIRECTORY if it fails. -// There is no dry run mode for sdk generation, so this test simply -// tries to do it and fails if there are uncommitted changes to your -// working directory afterward. -func TestSdkGenerate() { - fmt.Println("- Asserting that generated files are already up to date") - checkForUnstagedChanges(errorUnstagedPreGenerate) - createSdkDockerImage() - doSdkGenerate() - checkForUnstagedChanges(errorUnstagedPostSdkGenerate) -} - -// Tests the operator-sdk itself. -// -// Uses the example project and kubernetes CLI tools. This -// does not test the DSE operator code in any way. -func TestSdk() { - fmt.Println("- Testing the operator-sdk itself") - createSdkDockerImage() - createTestSdkDockerImage() -} - -type GitData struct { - Branch string - LongHash string - HasUncommittedChanges bool - ShortHash string -} - -func getGitData() GitData { - return GitData{ - Branch: gitutil.GetBranch(envGitBranch), - HasUncommittedChanges: gitutil.HasStagedChanges() || gitutil.HasUnstagedChanges(), - LongHash: gitutil.GetLongHash(envGitHash), - ShortHash: gitutil.GetShortHash(envGitHash), - } -} - -type FullVersion struct { - Core cfgutil.Version - Branch string - Uncommitted bool - Hash string -} - -func trimFullVersionBranch(v FullVersion) FullVersion { - str := v.String() - overflow := len(str) - 128 - if overflow > 0 { - v.Branch = v.Branch[:len(v.Branch)-overflow] - } - return v -} - -func (v FullVersion) String() string { - str := fmt.Sprintf("%v", v.Core) - if v.Core.Prerelease != "" { - str = fmt.Sprintf("%s.", str) - } else { - str = fmt.Sprintf("%s-", str) - } - if v.Branch != "master" { - sanitized := cfgutil.EnsureAlphaNumericDash(v.Branch) - str = fmt.Sprintf("%s%s.", str, sanitized) - } - if v.Uncommitted { - str = fmt.Sprintf("%suncommitted.", str) - } - str = fmt.Sprintf("%s%s", str, v.Hash) - return str -} - -func calcFullVersion(settings cfgutil.BuildSettings, git GitData) FullVersion { - return FullVersion{ - Core: settings.Version, - Branch: git.Branch, - Uncommitted: git.HasUncommittedChanges, - Hash: git.ShortHash, - } -} - -func calcVersionAndTags(version FullVersion, ubiBase bool) []string { - repoPath := "k8ssandra/cass-operator" - var tagsToPush []string - - if ubiBase { - tagsToPush = []string{ - fmt.Sprintf("%s:%s-ubi", repoPath, version.Hash), - fmt.Sprintf("%s:latest-ubi", repoPath), - } - } else { - tagsToPush = []string{ - fmt.Sprintf("%s:%s", repoPath, version.Hash), - fmt.Sprintf("%s:latest", repoPath), - } - } - - return tagsToPush -} - -func runDockerBuild(dockerTags []string, extraBuildArgs []string, target string) { - dockerutil.Build(".", target, dockerBase, dockerTags, extraBuildArgs).ExecVPanic() -} - -func runGoBuild(version string) { - os.Chdir("./operator") - os.Setenv("CGO_ENABLED", "0") - binaryPath := fmt.Sprintf("../build/bin/cass-operator-%s-%s", runtime.GOOS, runtime.GOARCH) - goArgs := []string{ - "build", "-o", binaryPath, - "-ldflags", fmt.Sprintf("-X main.version=%s", version), - fmt.Sprintf("%s/cmd/manager", packagePath), - } - shutil.RunVPanic("go", goArgs...) - os.Chdir("..") -} - -func PrintVersion() { - settings := cfgutil.ReadBuildSettings() - fmt.Printf("%v\n", settings.Version) -} - -func PrintFullVersion() { - settings := cfgutil.ReadBuildSettings() - git := getGitData() - version := calcFullVersion(settings, git) - fmt.Printf("%v\n", version) -} - -// Builds operator go code. -// -// By default, a dev version will be stamped into -// the binary. -// -// Set env variable MO_VERSION to specify a specific -// version to stamp. -func BuildGo() { - mg.Deps(Clean) - fmt.Println("- Building operator go module") - version := mageutil.EnvOrDefault(envVersionString, "DEV") - runGoBuild(version) -} - -// Runs unit tests for operator go code. -func TestGo() { - fmt.Println("- Running go unit tests") - os.Chdir("./operator") - os.Setenv("CGO_ENABLED", "0") - goArgs := []string{"test", "./...", "-v"} - shutil.RunVPanic("go", goArgs...) - os.Chdir("..") -} - -// Runs unit tests for operator mage library. -// -// Since we have a good amount of logic around building -// and versioning the operator, we want to make sure that -// the logic is sound. -func TestMage() { - fmt.Println("- Running operator mage unit tests") - os.Setenv("CGO_ENABLED", "0") - os.Chdir("./mage/operator") - goArgs := []string{"test"} - shutil.RunVPanic("go", goArgs...) - os.Chdir("../../") -} - -// Builds Docker image for the operator. -// -// This step will also build and test the operator go code. -// The docker image will be tagged based on the state -// of your git working tree. -func BuildDocker() { - fmt.Println("- Building operator docker image") - settings := cfgutil.ReadBuildSettings() - git := getGitData() - version := calcFullVersion(settings, git) - - //build regular docker image - dockerTags := calcVersionAndTags(version, false) - runDockerBuild(dockerTags, nil, cassOperatorTarget) - - if baseOs := os.Getenv(EnvBaseOs); baseOs != "" { - //build ubi docker image - args := []string{fmt.Sprintf("BASE_OS=%s", baseOs)} - ubiDockerTags := calcVersionAndTags(version, true) - runDockerBuild(ubiDockerTags, args, cassOperatorUbiTarget) - dockerTags = append(dockerTags, ubiDockerTags...) - } - - // Write the versioned image tags to a file in our build - // directory so that other targets in the build process can identify - // what was built. This is particularly important to know - // for targets that retag and deploy to external docker repositories - outputText := strings.Join(dockerTags, "|") - writeBuildFile("tagsToPush.txt", outputText) -} - -func buildMermaidJsDockerImage() { - dockerutil.Build("./tools/mermaid-js", "", "./tools/mermaid-js/Dockerfile", - []string{mermaidJsImage}, []string{}).ExecVPanic() -} - -func generateDocDiagram(in string, out string) { - runArgs := []string{} - execArgs := []string{ - "-i", in, - "-o", out, - } - diagramsDirAbs, err := filepath.Abs(diagramsDir) - mageutil.PanicOnError(err) - volumes := []string{fmt.Sprintf("%s:%s", diagramsDirAbs, "/data")} - dockerutil.Run(mermaidJsImage, volumes, nil, nil, runArgs, execArgs).ExecVPanic() -} - -func doGenerateDocDiagrams() { - diagramSrcExt := ".mmd" - svgExt := ".svg" - files, err := ioutil.ReadDir(diagramsDir) - mageutil.PanicOnError(err) - for _, file := range files { - if strings.HasSuffix(file.Name(), diagramSrcExt) { - base := strings.TrimSuffix(file.Name(), diagramSrcExt) - svg := fmt.Sprintf("%s%s", base, svgExt) - generateDocDiagram(file.Name(), svg) - } - } -} - -func buildCodeGeneratorDockerImage() { - // Use the version of code-generator that we are pinned to - // in operator/go.mod. - var genVersion string - f, err := os.Open("./go.mod") - mageutil.PanicOnError(err) - defer f.Close() - scanner := bufio.NewScanner(f) - for scanner.Scan() { - txt := scanner.Text() - if strings.Contains(txt, "code-generator =>") { - versionIdx := strings.LastIndex(txt, " ") - genVersion = txt[versionIdx+1:] - break - } - } - mageutil.PanicOnError(scanner.Err()) - fmt.Println(genVersion) - dockerutil.Build("./", "", "./tools/k8s-code-generator/Dockerfile", - []string{genClientImage}, []string{fmt.Sprintf("CODEGEN_VERSION=%s", genVersion)}).ExecVPanic() - -} - -func doGenerateClient() { - cwd, _ := os.Getwd() - usr, err := user.Current() - mageutil.PanicOnError(err) - runArgs := []string{"-t", "--rm", "-u", fmt.Sprintf("%s:%s", usr.Uid, usr.Gid)} - execArgs := []string{"client", "github.com/k8ssandra/cass-operator/operator/pkg/generated", - "github.com/k8ssandra/cass-operator/operator/pkg/apis", "cassandra:v1beta1"} - volumes := []string{fmt.Sprintf("%s:/go/src/github.com/k8ssandra/cass-operator", cwd)} - dockerutil.Run(genClientImage, volumes, nil, nil, runArgs, execArgs).ExecVPanic() -} - -// Generate diagrams for docs. -func GenerateDiagrams() { - buildMermaidJsDockerImage() - doGenerateDocDiagrams() -} - -// Gen operator client code. -// -// Uses k8s code-generator to generate client code that -// resides in the operator/pkg/generated/clientset/ directory. -func GenerateClient() { - buildCodeGeneratorDockerImage() - doGenerateClient() -} - -// Asserts that generated client boilerplate files are up to date. -// -// Note: this test WILL UPDATE YOUR WORKING DIRECTORY if it fails. -// There is no dry run mode for code-generation, so this test simply -// tries to do it and fails if there are uncommitted changes to your -// working directory afterward. -func TestGenerateClient() { - fmt.Println("- Asserting that generated client files are already up to date") - checkForUnstagedChanges(errorUnstagedPreGenerate) - buildCodeGeneratorDockerImage() - doGenerateClient() - checkForUnstagedChanges(errorUnstagedPostClientGenerate) -} - -// Alias for buildDocker target -func Build() { - mg.Deps(BuildDocker) -} - -// Run all automated test targets -func Test() { - mg.Deps(TestMage) - mg.Deps(TestGo) - mg.Deps(TestSdk) - mg.Deps(TestSdkGenerate) - mg.Deps(TestGenerateClient) -} - -// Remove the operator build directories, and the top-level build directory. -// -// It's maybe a bit weird that this clean target reaches up out of it's -// directory to clean a top level thing, but right now that top-level thing -// holds the operator golang binary, so we clean it here. -func Clean() { - os.RemoveAll(sdkBuildDir) - os.RemoveAll(rootBuildDir) -} - -// Run go tests and build a docker image if they pass -func TestAndBuild() { - mg.SerialDeps(TestGo, BuildDocker) -} diff --git a/mage/operator/lib_test.go b/mage/operator/lib_test.go deleted file mode 100644 index 9781be93..00000000 --- a/mage/operator/lib_test.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package operator - -import ( - "testing" - - cfgutil "github.com/k8ssandra/cass-operator/mage/config" - "github.com/stretchr/testify/assert" -) - -func TestMageOperator_trimFullVersionBranch_ok(t *testing.T) { - v := cfgutil.Version{ - Major: 1, - Minor: 2, - Patch: 3, - Prerelease: "alpha-1", - } - full := FullVersion{ - Core: v, - Branch: "something-short", - Uncommitted: true, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - want := "something-short" - got := trimFullVersionBranch(full).Branch - assert.Equal(t, got, want) -} -func TestMageOperator_trimFullVersionBranch_overflow(t *testing.T) { - v := cfgutil.Version{ - Major: 1, - Minor: 2, - Patch: 3, - Prerelease: "alpha-1", - } - full := FullVersion{ - Core: v, - Branch: "something-long-really-should-be-trimmed-to-avoid-128-chars-or-we-cant-push", - Uncommitted: true, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - trimmed := trimFullVersionBranch(full) - want := 128 - got := len(trimmed.String()) - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_simple(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "", - } - full := FullVersion{ - Core: v, - Branch: "ko-123-test", - Uncommitted: false, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-ko-123-test.341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_prerelease(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "alpha-9", - } - full := FullVersion{ - Core: v, - Branch: "ko-123-test", - Uncommitted: false, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-alpha-9.ko-123-test.341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_uncommitted(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "", - } - full := FullVersion{ - Core: v, - Branch: "ko-123-test", - Uncommitted: true, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-ko-123-test.uncommitted.341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_prerelease_uncommitted(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "alpha-9", - } - full := FullVersion{ - Core: v, - Branch: "ko-123-test", - Uncommitted: true, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-alpha-9.ko-123-test.uncommitted.341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_master(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "", - } - full := FullVersion{ - Core: v, - Branch: "master", - Uncommitted: false, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} - -func TestMageOperator_fullVersion_string_master_prerelease(t *testing.T) { - v := cfgutil.Version{ - Major: 9, - Minor: 3, - Patch: 7, - Prerelease: "beta-2", - } - full := FullVersion{ - Core: v, - Branch: "master", - Uncommitted: false, - Hash: "341fe22e8af310fd7694a0c5db4f065131799047", - } - - want := "9.3.7-beta-2.341fe22e8af310fd7694a0c5db4f065131799047" - got := full.String() - assert.Equal(t, got, want) -} diff --git a/mage/sh/lib.go b/mage/sh/lib.go index 99b5d12c..cd5b9ef9 100644 --- a/mage/sh/lib.go +++ b/mage/sh/lib.go @@ -5,10 +5,10 @@ package shutil import ( "bytes" + "fmt" "io" "os" "os/exec" - "fmt" "strings" "github.com/k8ssandra/cass-operator/mage/util" @@ -133,7 +133,7 @@ func RunVWithInput(cmd string, in string, args ...string) error { return RunVWithEnvWithInput(nil, cmd, in, args...) } -func RunVWithEnvWithInput(env map[string]string, cmd string, in string, args...string) error { +func RunVWithEnvWithInput(env map[string]string, cmd string, in string, args ...string) error { c := cmdWithStdIn(env, cmd, in, args...) c.Stdout = os.Stdout c.Stderr = os.Stderr @@ -156,4 +156,4 @@ func OutputWithEnvWithInput(env map[string]string, cmd string, in string, args . c.Stdin = &buffer out, err := c.Output() return string(out), err -} \ No newline at end of file +} diff --git a/magefile.go b/magefile.go index 865f8694..0375e555 100644 --- a/magefile.go +++ b/magefile.go @@ -10,14 +10,8 @@ import ( // mage:import jenkins "github.com/k8ssandra/cass-operator/mage/jenkins" - // mage:import operator - "github.com/k8ssandra/cass-operator/mage/operator" - // mage:import integ - _ "github.com/k8ssandra/cass-operator/mage/integ-tests" // mage:import lint _ "github.com/k8ssandra/cass-operator/mage/linting" - // mage:import k8s - _ "github.com/k8ssandra/cass-operator/mage/k8s" ) // Clean all build artifacts, does not clean up old docker images. diff --git a/main.go b/main.go new file mode 100644 index 00000000..007bd5dc --- /dev/null +++ b/main.go @@ -0,0 +1,146 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "flag" + "os" + "strconv" + "strings" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/controllers" + "github.com/k8ssandra/cass-operator/pkg/utils" + //+kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(api.AddToScheme(scheme)) + //+kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + var probeAddr string + flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + options := ctrl.Options{ + Scheme: scheme, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "b569adb7.cassandra.datastax.com", + } + + ns, err := utils.GetWatchNamespace() + if err != nil { + setupLog.Error(err, "unable to get WatchNamespace, "+ + "the manager will watch and manage resources in all namespaces") + } + + // Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2) + if strings.Contains(ns, ",") { + setupLog.Info("manager set up with multiple namespaces", "namespaces", ns) + // configure cluster-scoped with MultiNamespacedCacheBuilder + options.Namespace = "" + options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(ns, ",")) + } else { + setupLog.Info("watch namespace configured", "namespace", ns) + options.Namespace = ns + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&controllers.CassandraDatacenterReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("CassandraDatacenter"), + Scheme: mgr.GetScheme(), + Recorder: mgr.GetEventRecorderFor("cass-operator"), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "CassandraDatacenter") + os.Exit(1) + } + + skipWebhookEnvVal := os.Getenv("SKIP_VALIDATING_WEBHOOK") + if skipWebhookEnvVal == "" { + skipWebhookEnvVal = "FALSE" + } + skipWebhook, err := strconv.ParseBool(skipWebhookEnvVal) + if err != nil { + setupLog.Error(err, "bad value for SKIP_VALIDATING_WEBHOOK env") + os.Exit(1) + } + + if !skipWebhook { + if err = (&api.CassandraDatacenter{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "CassandraDatacenter") + os.Exit(1) + } + } + //+kubebuilder:scaffold:builder + + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/operator/cmd/manager/main.go b/operator/cmd/manager/main.go deleted file mode 100644 index 5cd780e2..00000000 --- a/operator/cmd/manager/main.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package main - -import ( - "context" - "errors" - "flag" - "fmt" - "io/ioutil" - "os" - "runtime" - "strconv" - "strings" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - - webhook "github.com/k8ssandra/cass-operator/operator/pkg/admissionwebhook" - "github.com/k8ssandra/cass-operator/operator/pkg/apis" - "github.com/k8ssandra/cass-operator/operator/pkg/controller" - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics" - "github.com/operator-framework/operator-sdk/pkg/leader" - "github.com/operator-framework/operator-sdk/pkg/log/zap" - "github.com/operator-framework/operator-sdk/pkg/metrics" - "github.com/operator-framework/operator-sdk/pkg/ready" - sdkVersion "github.com/operator-framework/operator-sdk/version" - "github.com/spf13/pflag" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" - controllerRuntime "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client/config" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/manager/signals" - - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/images" -) - -// Change below variables to serve metrics on different host or port. -var ( - metricsHost = "0.0.0.0" - metricsPort int32 = 8383 - operatorMetricsPort int32 = 8686 - version = "DEV" -) -var log = logf.Log.WithName("cmd") - -func printVersion() { - log.Info("Go Version", - "goVersion", runtime.Version()) - - log.Info("Go OS/Arch", - "os", runtime.GOOS, - "arch", runtime.GOARCH) - - log.Info("Version of operator-sdk", - "operatorSdkVersion", sdkVersion.Version) - - log.Info("Operator version", - "operatorVersion", version) -} - -func main() { - - // workaround for cases where the empty string can't come through - // environment variable values - we'll use star to mean all namespaces - { - env := "WATCH_NAMESPACE" - v, ok := os.LookupEnv(env) - if ok && v == "*" { - os.Setenv(env, "") - } - } - - // Add the zap logger flag set to the CLI. The flag set must - // be added before calling pflag.Parse(). - pflag.CommandLine.AddFlagSet(zap.FlagSet()) - - // Add flags registered by imported packages (e.g. glog and - // controller-runtime) - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - - pflag.Parse() - - // Use a zap logr.Logger implementation. If none of the zap - // flags are configured (or if the zap flag set is not being - // used), this defaults to a production zap logger. - // - // The logger instantiated here can be changed to any logger - // implementing the logr.Logger interface. This logger will - // be propagated through the whole operator, generating - // uniform and structured logs. - logf.SetLogger(zap.Logger()) - - printVersion() - - namespace, err := k8sutil.GetWatchNamespace() - if err != nil { - log.Error(err, "Failed to get watch namespace") - os.Exit(1) - } - - // Get a config to talk to the apiserver - cfg, err := config.GetConfig() - if err != nil { - log.Error(err, "could not get k8s config") - os.Exit(1) - } - - // Use the operator-sdk ready pkg - readyFile := ready.NewFileReady() - err = readyFile.Set() - if err != nil { - log.Error(err, "Problem creating readyFile. Exited non-zero") - os.Exit(1) - } - log.Info("created the readyFile.") - defer readyFile.Unset() - - ctx := context.Background() - // Become the leader before proceeding - err = leader.Become(ctx, "cass-operator-lock") - - if err != nil { - log.Error(err, "could not become leader") - os.Exit(1) - } - - if err = webhook.EnsureWebhookConfigVolume(cfg); err != nil { - log.Error(err, "Failed to ensure webhook volume") - } - var certDir string - if certDir, err = webhook.EnsureWebhookCertificate(cfg); err != nil { - log.Error(err, "Failed to ensure webhook CA configuration") - } - - if err = readBaseOsIntoEnv(); err != nil { - log.Error(err, "Failed to read base OS into env") - } - - // Set default manager options - options := manager.Options{ - Namespace: namespace, - MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), - CertDir: certDir, - Port: 8443, - } - - // Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2) - // Note that this is not intended to be used for excluding namespaces, this is better done via a Predicate - // Also note that you may face performance issues when using this with a high number of namespaces. - // More Info: https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/cache#MultiNamespacedCacheBuilder - if strings.Contains(namespace, ",") { - options.Namespace = "" - options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(namespace, ",")) - } - - // Create a new manager to provide shared dependencies and start components - mgr, err := manager.New(cfg, options) - if err != nil { - log.Error(err, "could not make manager") - os.Exit(1) - } - - log.Info("Registering Components.") - - // Setup Scheme for all resources - if err := apis.AddToScheme(mgr.GetScheme()); err != nil { - log.Error(err, "could not add to scheme") - os.Exit(1) - } - - // Setup all Controllers - if err := controller.AddToManager(mgr); err != nil { - log.Error(err, "could not add to manager") - os.Exit(1) - } - - skipWebhookEnvVal := os.Getenv("SKIP_VALIDATING_WEBHOOK") - if skipWebhookEnvVal == "" { - skipWebhookEnvVal = "FALSE" - } - skipWebhook, err := strconv.ParseBool(skipWebhookEnvVal) - if err != nil { - log.Error(err, "bad value for SKIP_VALIDATING_WEBHOOK env") - os.Exit(1) - } - - if !skipWebhook { - err = controllerRuntime.NewWebhookManagedBy(mgr).For(&api.CassandraDatacenter{}).Complete() - if err != nil { - log.Error(err, "unable to create validating webhook for CassandraDatacenter") - os.Exit(1) - } - } - - // Add the Metrics Service - addMetrics(ctx, cfg) - - log.Info("Starting the Cmd.") - - // Start the Cmd - if err := mgr.Start(signals.SetupSignalHandler()); err != nil { - log.Error(err, "Manager exited non-zero") - os.Exit(1) - } -} - -func readBaseOsIntoEnv() error { - baseOsArgFilePath := "/var/lib/cass-operator/base_os" - - info, err := os.Stat(baseOsArgFilePath) - if os.IsNotExist(err) { - msg := fmt.Sprintf("Could not locate base OS arg file at %s", baseOsArgFilePath) - err = fmt.Errorf("%s. %v", msg, err) - return err - } - - if info.IsDir() { - msg := fmt.Sprintf("Base OS arg path is a directory not a file: %s", baseOsArgFilePath) - err = fmt.Errorf("%s. %v", msg, err) - return err - } - - rawVal, err := ioutil.ReadFile(baseOsArgFilePath) - if err != nil { - msg := fmt.Sprintf("Failed to read base OS arg file at %s", baseOsArgFilePath) - err = fmt.Errorf("%s. %v", msg, err) - return err - } - - baseOs := strings.TrimSpace(string(rawVal)) - os.Setenv(images.EnvBaseImageOS, baseOs) - log.Info(fmt.Sprintf("%s set to '%s'", images.EnvBaseImageOS, baseOs)) - - return nil -} - -// addMetrics will create the Services and Service Monitors to allow the operator export the metrics by using -// the Prometheus operator -func addMetrics(ctx context.Context, cfg *rest.Config) { - // Get the namespace the operator is currently deployed in. - operatorNs, err := k8sutil.GetOperatorNamespace() - if err != nil { - if errors.Is(err, k8sutil.ErrRunLocal) { - log.Info("Skipping CR metrics server creation; not running in a cluster.") - return - } - } - - if err := serveCRMetrics(cfg, operatorNs); err != nil { - log.Info("Could not generate and serve custom resource metrics", "error", err.Error()) - } - - // Add to the below struct any other metrics ports you want to expose. - servicePorts := []v1.ServicePort{ - {Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}}, - {Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}}, - } - - // Create Service object to expose the metrics port(s). - service, err := metrics.CreateMetricsService(ctx, cfg, servicePorts) - if err != nil { - log.Info("Could not create metrics Service", "error", err.Error()) - } - - // CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources - // necessary to configure Prometheus to scrape metrics from this operator. - services := []*v1.Service{service} - - // The ServiceMonitor is created in the same namespace where the operator is deployed - _, err = metrics.CreateServiceMonitors(cfg, operatorNs, services) - if err != nil { - log.Info("Could not create ServiceMonitor object", "error", err.Error()) - // If this operator is deployed to a cluster without the prometheus-operator running, it will return - // ErrServiceMonitorNotPresent, which can be used to safely skip ServiceMonitor creation. - if err == metrics.ErrServiceMonitorNotPresent { - log.Info("Install prometheus-operator in your cluster to create ServiceMonitor objects", "error", err.Error()) - } - } -} - -// serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types. -// It serves those metrics on "http://metricsHost:operatorMetricsPort". -func serveCRMetrics(cfg *rest.Config, operatorNs string) error { - // The function below returns a list of filtered operator/CR specific GVKs. For more control, override the GVK list below - // with your own custom logic. Note that if you are adding third party API schemas, probably you will need to - // customize this implementation to avoid permissions issues. - filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme) - if err != nil { - return err - } - - // The metrics will be generated from the namespaces which are returned here. - // NOTE that passing nil or an empty list of namespaces in GenerateAndServeCRMetrics will result in an error. - ns, err := kubemetrics.GetNamespacesForMetrics(operatorNs) - if err != nil { - return err - } - - // Generate and serve custom resource specific metrics. - err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort) - if err != nil { - return err - } - return nil -} diff --git a/operator/deploy/README.md b/operator/deploy/README.md deleted file mode 100644 index 2f3fa9a0..00000000 --- a/operator/deploy/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Deploying the operator and making a Cassandra cluster with it - -## Make a Kubernetes cluster - -For the rest of this README I'm going to assume your `kubectl` is working with a GKE cluster on the receiving end of the API commands. Most of this should hold up for other k8s environments. - -## Create a namespace - -``` -kubectl create ns optest -``` - -## Create a secret so you can use the DS internal Artificatory (datastax-docker.jfrog.io) for docker images - -``` -kubectl -n optest create secret docker-registry cass-operator-artifactory-secret --docker-server=datastax-docker.jfrog.io --docker-username=USERNAME --docker-password=PASSWORD -``` - -Feel free to ask Jim or some folks in #cloud-eng on Slack to get the right values to for that secret. - -## Apply a bunch of yamls - -``` -kubectl -n optest apply -f role.yaml -kubectl -n optest apply -f role_binding.yaml -kubectl -n optest apply -f service_account.yaml -kubectl -n optest apply -f crds/datastax_v1alpha1_dsedatacenter_crd.yaml -``` - -This created a `Role`, `RoleBinding`, `ServiceAccount` (using that secret to pull Docker images), -and the `DseDatacenter` CRD. - -## Deploy the Operator - -Edit `operator.yaml` and swap the string REPLACE_IMAGE with the operator build you want to use. For example, `datastax-docker.jfrog.io/cass-operator/operator:master.2290d5ab557b97f6c736fee5911a62dea8c63d29` - -Then, deploy the operator. - -``` -kubectl -n optest apply -f operator.yaml -``` - -## Create your StorageClass - -It's up to the k8s admin to create a `StorageClass` the operator can use to set up volumes for the DSE cluster. I've left an example one for GKE us-west2 clusters using 100GB SSD volumes in `gke/storage.yaml`. - -``` -kubectl -n optest apply -f gke/storage.yaml -``` - -## Create a Cassandra Cluster - -At this point the only step left is to create a `CassandraDatacenter` and wait for the operator to provision the pods and volumes. I've left an example that uses the `StorageClass` created in the previous step. - -``` -kubectl -n optest apply -f gke/gke-example-dc.yaml -``` diff --git a/operator/deploy/cluster_role.yaml b/operator/deploy/cluster_role.yaml deleted file mode 100644 index a0a52570..00000000 --- a/operator/deploy/cluster_role.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: cass-operator-cluster-role -rules: -- apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - verbs: - - create - - get - - update - resourceNames: - - "cassandradatacenter-webhook-registration" diff --git a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml b/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml deleted file mode 100644 index 3c60ea3a..00000000 --- a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml +++ /dev/null @@ -1,6591 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: cassandradatacenters.cassandra.datastax.com -spec: - group: cassandra.datastax.com - names: - kind: CassandraDatacenter - listKind: CassandraDatacenterList - plural: cassandradatacenters - shortNames: - - cassdc - - cassdcs - singular: cassandradatacenter - scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: CassandraDatacenter is the Schema for the cassandradatacenters - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: CassandraDatacenterSpec defines the desired state of a CassandraDatacenter - properties: - additionalSeeds: - items: - type: string - type: array - additionalServiceConfig: - description: AdditionalServiceConfig allows to define additional parameters - that are included in the created Services. Note, user can override - values set by cass-operator and doing so could break cass-operator - functionality. Avoid label "cass-operator" and anything that starts - with "cassandra.datastax.com/" - properties: - additionalSeedService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - allpodsService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - dcService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - nodePortService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - seedService: - description: ServiceConfigAdditions exposes additional options for - each service - properties: - additionalAnnotations: - additionalProperties: - type: string - type: object - additionalLabels: - additionalProperties: - type: string - type: object - type: object - type: object - allowMultipleNodesPerWorker: - description: Turning this option on allows multiple server pods to be - created on a k8s worker node. By default the operator creates just - one server pod per k8s worker node using k8s podAntiAffinity and requiredDuringSchedulingIgnoredDuringExecution. - type: boolean - canaryUpgrade: - description: Indicates that configuration and container image changes - should only be pushed to the first rack of the datacenter - type: boolean - canaryUpgradeCount: - description: The number of nodes that will be updated when CanaryUpgrade - is true. Note that the value is either 0 or greater than the rack - size, then all nodes in the rack will get updated. - format: int32 - type: integer - clusterName: - description: The name by which CQL clients and instances will know the - cluster. If the same cluster name is shared by multiple Datacenters - in the same Kubernetes namespace, they will join together in a multi-datacenter - cluster. - minLength: 2 - type: string - configBuilderImage: - description: Container image for the config builder init container. - type: string - configBuilderResources: - description: Kubernetes resource requests and limits per server config - initialization container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - configSecret: - description: "ConfigSecret is the name of a secret that contains configuration - for Cassandra. The secret is expected to have a property named config - whose value should be a JSON formatted string that should look like - this: \n config: |- { \"cassandra-yaml\": { \"read_request_timeout_in_ms\": - 10000 }, \"jmv-options\": { \"max_heap_size\": - 1024M } } \n ConfigSecret is mutually exclusive with Config. - ConfigSecret takes precedence and will be used exclusively if both - properties are set. The operator sets a watch such that an update - to the secret will trigger an update of the StatefulSets." - type: string - disableSystemLoggerSidecar: - description: Configuration for disabling the simple log tailing sidecar - container. Our default is to have it enabled. - type: boolean - dockerImageRunsAsCassandra: - description: Does the Server Docker image run as the Cassandra user? - type: boolean - dseWorkloads: - properties: - analyticsEnabled: - type: boolean - graphEnabled: - type: boolean - searchEnabled: - type: boolean - type: object - forceUpgradeRacks: - description: Rack names in this list are set to the latest StatefulSet - configuration even if Cassandra nodes are down. Use this to recover - from an upgrade that couldn't roll out. - items: - type: string - type: array - managementApiAuth: - description: Config for the Management API certificates - properties: - insecure: - type: object - manual: - properties: - clientSecretName: - type: string - serverSecretName: - type: string - skipSecretValidation: - type: boolean - required: - - clientSecretName - - serverSecretName - type: object - type: object - networking: - properties: - hostNetwork: - type: boolean - nodePort: - properties: - internode: - type: integer - internodeSSL: - type: integer - native: - type: integer - nativeSSL: - type: integer - type: object - type: object - nodeAffinityLabels: - additionalProperties: - type: string - description: NodeAffinityLabels to pin the Datacenter, using node affinity - type: object - nodeSelector: - additionalProperties: - type: string - description: 'A map of label keys and values to restrict Cassandra node - scheduling to k8s workers with matchiing labels. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector' - type: object - podTemplateSpec: - description: PodTemplate provides customisation options (labels, annotations, - affinity rules, resource requests, and so on) for the cassandra pods - properties: - metadata: - description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' - type: object - spec: - description: 'Specification of the desired behavior of the pod. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' - properties: - activeDeadlineSeconds: - description: Optional duration in seconds the pod may be active - on the node relative to StartTime before the system will actively - try to mark it failed and kill associated containers. Value - must be a positive integer. - format: int64 - type: integer - affinity: - description: If specified, the pod's scheduling constraints - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for - the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a - no-op). A null preferred scheduling term matches - no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range - 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an - update), the system may or may not try to eventually - evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) with the - highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, etc. - as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the greatest - sum of weights, i.e. for each node that meets all - of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if the - node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - description: AutomountServiceAccountToken indicates whether - a service account token should be automatically mounted. - type: boolean - containers: - description: List of containers belonging to the pod. Containers - cannot currently be added or removed. There must be at least - one container in a Pod. Cannot be updated. - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config - management to default or override container images in - workload controllers like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should - take in response to container lifecycle events. Cannot - be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but - is primarily informational. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port - which is listening on the default "0.0.0.0" address - inside a container will be accessible from the network. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if - the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: 'Security options the pod should run with. - More info: https://kubernetes.io/docs/concepts/policy/security-context/ - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has - successfully initialized. If specified, no other probes - are executed until this completes successfully. If this - probe fails, the Pod will be restarted, just as if the - livenessProbe failed. This can be used to provide different - probe parameters at the beginning of a Pod''s lifecycle, - when it might take a long time to load data or warm - a cache, than during steady-state operation. This cannot - be updated. This is an alpha feature enabled by the - StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - dnsConfig: - description: Specifies the DNS parameters of a pod. Parameters - specified here will be merged to the generated DNS configuration - based on DNSPolicy. - properties: - nameservers: - description: A list of DNS name server IP addresses. This - will be appended to the base nameservers generated from - DNSPolicy. Duplicated nameservers will be removed. - items: - type: string - type: array - options: - description: A list of DNS resolver options. This will be - merged with the base options generated from DNSPolicy. - Duplicated entries will be removed. Resolution options - given in Options will override those that appear in the - base DNSPolicy. - items: - description: PodDNSConfigOption defines DNS resolver options - of a pod. - properties: - name: - description: Required. - type: string - value: - type: string - type: object - type: array - searches: - description: A list of DNS search domains for host-name - lookup. This will be appended to the base search paths - generated from DNSPolicy. Duplicated search paths will - be removed. - items: - type: string - type: array - type: object - dnsPolicy: - description: Set DNS policy for the pod. Defaults to "ClusterFirst". - Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', - 'Default' or 'None'. DNS parameters given in DNSConfig will - be merged with the policy selected with DNSPolicy. To have - DNS options set along with hostNetwork, you have to specify - DNS policy explicitly to 'ClusterFirstWithHostNet'. - type: string - enableServiceLinks: - description: 'EnableServiceLinks indicates whether information - about services should be injected into pod''s environment - variables, matching the syntax of Docker links. Optional: - Defaults to true.' - type: boolean - ephemeralContainers: - description: List of ephemeral containers run in this pod. Ephemeral - containers may be run in an existing pod to perform user-initiated - actions such as debugging. This list cannot be specified when - creating a pod, and it cannot be modified by updating the - pod spec. In order to add an ephemeral container to an existing - pod, use the pod's ephemeralcontainers subresource. This field - is alpha-level and is only honored by servers that enable - the EphemeralContainers feature. - items: - description: An EphemeralContainer is a container that may - be added temporarily to an existing pod for user-initiated - activities such as debugging. Ephemeral containers have - no resource or scheduling guarantees, and they will not - be restarted when they exit or when a pod is removed or - restarted. If an ephemeral container causes a pod to exceed - its resource allocation, the pod may be evicted. Ephemeral - containers may not be added by directly updating the pod - spec. They must be added via the pod's ephemeralcontainers - subresource, and they will appear in the pod spec once added. - This is an alpha feature enabled by the EphemeralContainers - feature flag. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Lifecycle is not allowed for ephemeral containers. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the ephemeral container specified - as a DNS_LABEL. This name must be unique among all containers, - init containers and ephemeral containers. - type: string - ports: - description: Ports are not allowed for ephemeral containers. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - readinessProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: Resources are not allowed for ephemeral containers. - Ephemeral containers use spare resources already allocated - to the pod. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: SecurityContext is not allowed for ephemeral - containers. - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: Probes are not allowed for ephemeral containers. - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - targetContainerName: - description: If set, the name of the container from PodSpec - that this ephemeral container targets. The ephemeral - container will be run in the namespaces (IPC, PID, etc) - of this container. If not set then the ephemeral container - is run in whatever namespaces are shared for the pod. - Note that the container runtime must support this feature. - type: string - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - hostAliases: - description: HostAliases is an optional list of hosts and IPs - that will be injected into the pod's hosts file if specified. - This is only valid for non-hostNetwork pods. - items: - description: HostAlias holds the mapping between IP and hostnames - that will be injected as an entry in the pod's hosts file. - properties: - hostnames: - description: Hostnames for the above IP address. - items: - type: string - type: array - ip: - description: IP address of the host file entry. - type: string - type: object - type: array - hostIPC: - description: 'Use the host''s ipc namespace. Optional: Default - to false.' - type: boolean - hostNetwork: - description: Host networking requested for this pod. Use the - host's network namespace. If this option is set, the ports - that will be used must be specified. Default to false. - type: boolean - hostPID: - description: 'Use the host''s pid namespace. Optional: Default - to false.' - type: boolean - hostname: - description: Specifies the hostname of the Pod If not specified, - the pod's hostname will be set to a system-defined value. - type: string - imagePullSecrets: - description: 'ImagePullSecrets is an optional list of references - to secrets in the same namespace to use for pulling any of - the images used by this PodSpec. If specified, these secrets - will be passed to individual puller implementations for them - to use. For example, in the case of docker, only DockerConfig - type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' - items: - description: LocalObjectReference contains enough information - to let you locate the referenced object inside the same - namespace. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - type: array - initContainers: - description: 'List of initialization containers belonging to - the pod. Init containers are executed in order prior to containers - being started. If any init container fails, the pod is considered - to have failed and is handled according to its restartPolicy. - The name for an init container or normal container must be - unique among all containers. Init containers may not have - Lifecycle actions, Readiness probes, Liveness probes, or Startup - probes. The resourceRequirements of an init container are - taken into account during scheduling by finding the highest - request/limit for each resource type, and then using the max - of of that value or the sum of the normal containers. Limits - are applied to init containers in a similar fashion. Init - containers cannot currently be added or removed. Cannot be - updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' - items: - description: A single application container that you want - to run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker - image''s CMD is used if this is not provided. Variable - references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. The $(VAR_NAME) - syntax can be escaped with a double $$, ie: $$(VAR_NAME). - Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a - shell. The docker image''s ENTRYPOINT is used if this - is not provided. Variable references $(VAR_NAME) are - expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string - will be unchanged. The $(VAR_NAME) syntax can be escaped - with a double $$, ie: $$(VAR_NAME). Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previous defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - The $(VAR_NAME) syntax can be escaped with a double - $$, ie: $$(VAR_NAME). Escaped references will - never be expanded, regardless of whether the variable - exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, metadata.labels, - metadata.annotations, spec.nodeName, spec.serviceAccountName, - status.hostIP, status.podIP, status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported - as an event when the container is starting. When a key - exists in multiple sources, the value associated with - the last source will take precedence. Values defined - by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of - a set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret must - be defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config - management to default or override container images in - workload controllers like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, - IfNotPresent. Defaults to Always if :latest tag is specified, - or IfNotPresent otherwise. Cannot be updated. More info: - https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should - take in response to container lifecycle events. Cannot - be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according - to its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before - a container is terminated due to an API request - or management event such as liveness/startup probe - failure, preemption, resource contention, etc. The - handler is not called if the container crashes or - exits. The reason for termination is passed to the - handler. The Pod''s termination grace period countdown - begins before the PreStop hooked is executed. Regardless - of the outcome of the handler, the container will - eventually terminate within the Pod''s termination - grace period. Other management of the container - blocks until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: One and only one of the following - should be specified. Exec specifies the action - to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') - in the container's filesystem. The command - is simply exec'd, it is not run inside a - shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you - need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the - request. HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting - to the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: - implement a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to - access on the container. Number must be - in the range 1 to 65535. Name must be an - IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but - is primarily informational. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port - which is listening on the default "0.0.0.0" address - inside a container will be accessible from the network. - Cannot be updated. - items: - description: ContainerPort represents a network port - in a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, - 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in - a pod must have a unique name. Name for the port - that can be referred to by services. - type: string - protocol: - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if - the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - securityContext: - description: 'Security options the pod should run with. - More info: https://kubernetes.io/docs/concepts/policy/security-context/ - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as - Privileged 2) has CAP_SYS_ADMIN' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the - container process. Uses runtime default if unset. - May also be set in PodSecurityContext. If set in - both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run - as a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not - run as UID 0 (root) and fail to start the container - if it does. If unset or false, no such validation - will be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the - container process. Defaults to user specified in - image metadata if unspecified. May also be set in - PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to - the container. If unspecified, the container runtime - will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - properties: - level: - description: Level is SELinux level label that - applies to the container. - type: string - role: - description: Role is a SELinux role label that - applies to the container. - type: string - type: - description: Type is a SELinux type label that - applies to the container. - type: string - user: - description: User is a SELinux user label that - applies to the container. - type: string - type: object - windowsOptions: - description: The Windows specific settings applied - to all containers. If unspecified, the options from - the PodSecurityContext will be used. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential - spec named by the GMSACredentialSpecName field. - This field is alpha-level and is only honored - by servers that enable the WindowsGMSA feature - flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. This field - is alpha-level and is only honored by servers - that enable the WindowsGMSA feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes - precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has - successfully initialized. If specified, no other probes - are executed until this completes successfully. If this - probe fails, the Pod will be restarted, just as if the - livenessProbe failed. This can be used to provide different - probe parameters at the beginning of a Pod''s lifecycle, - when it might take a long time to load data or warm - a cache, than during steady-state operation. This cannot - be updated. This is an alpha feature enabled by the - StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: One and only one of the following should - be specified. Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory - for the command is root ('/') in the container's - filesystem. The command is simply exec'd, it - is not run inside a shell, so traditional shell - instructions ('|', etc) won't work. To use a - shell, you need to explicitly call out to that - shell. Exit status of 0 is treated as live/healthy - and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the - probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - httpGet: - description: HTTPGet specifies the http request to - perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the - probe. Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the - probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. - Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: 'TCPSocket specifies an action involving - a TCP port. TCP hooks not yet supported TODO: implement - a realistic TCP lifecycle hook' - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a - buffer for stdin in the container runtime. If this is - not set, reads from stdin in the container will always - result in EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is - empty until the first client attaches to stdin, and - then remains open and accepts data until the client - disconnects, at which time stdin is closed and remains - closed until the container is restarted. If this flag - is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written - is mounted into the container''s filesystem. Message - written is intended to be brief final status, such as - an assertion failure message. Will be truncated by the - node if greater than 4096 bytes. The total message length - across all containers will be limited to 12kb. Defaults - to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last - chunk of container log output if the termination message - file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, - whichever is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a - TTY for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. This is a beta feature. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's - filesystem. Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which - the volume should be mounted. Must not contain - ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and - the other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to - false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults - to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the - container's environment. Defaults to "" (volume's - root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which - might be configured in the container image. Cannot be - updated. - type: string - required: - - name - type: object - type: array - nodeName: - description: NodeName is a request to schedule this pod onto - a specific node. If it is non-empty, the scheduler simply - schedules this pod onto that node, assuming that it fits resource - requirements. - type: string - nodeSelector: - additionalProperties: - type: string - description: 'NodeSelector is a selector which must be true - for the pod to fit on a node. Selector which must match a - node''s labels for the pod to be scheduled on that node. More - info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Overhead represents the resource overhead associated - with running a pod for a given RuntimeClass. This field will - be autopopulated at admission time by the RuntimeClass admission - controller. If the RuntimeClass admission controller is enabled, - overhead must not be set in Pod create requests. The RuntimeClass - admission controller will reject Pod create requests which - have the overhead already set. If RuntimeClass is configured - and selected in the PodSpec, Overhead will be set to the value - defined in the corresponding RuntimeClass, otherwise it will - remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md - This field is alpha-level as of Kubernetes v1.16, and is only - honored by servers that enable the PodOverhead feature.' - type: object - preemptionPolicy: - description: PreemptionPolicy is the Policy for preempting pods - with lower priority. One of Never, PreemptLowerPriority. Defaults - to PreemptLowerPriority if unset. This field is alpha-level - and is only honored by servers that enable the NonPreemptingPriority - feature. - type: string - priority: - description: The priority value. Various system components use - this field to find the priority of the pod. When Priority - Admission Controller is enabled, it prevents users from setting - this field. The admission controller populates this field - from PriorityClassName. The higher the value, the higher the - priority. - format: int32 - type: integer - priorityClassName: - description: If specified, indicates the pod's priority. "system-node-critical" - and "system-cluster-critical" are two special keywords which - indicate the highest priorities with the former being the - highest priority. Any other name must be defined by creating - a PriorityClass object with that name. If not specified, the - pod priority will be default or zero if there is no default. - type: string - readinessGates: - description: 'If specified, all readiness gates will be evaluated - for pod readiness. A pod is ready when all its containers - are ready AND all conditions specified in the readiness gates - have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md' - items: - description: PodReadinessGate contains the reference to a - pod condition - properties: - conditionType: - description: ConditionType refers to a condition in the - pod's condition list with matching type. - type: string - required: - - conditionType - type: object - type: array - restartPolicy: - description: 'Restart policy for all containers within the pod. - One of Always, OnFailure, Never. Default to Always. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' - type: string - runtimeClassName: - description: 'RuntimeClassName refers to a RuntimeClass object - in the node.k8s.io group, which should be used to run this - pod. If no RuntimeClass resource matches the named class, - the pod will not be run. If unset or empty, the "legacy" RuntimeClass - will be used, which is an implicit class with an empty definition - that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md - This is a beta feature as of Kubernetes v1.14.' - type: string - schedulerName: - description: If specified, the pod will be dispatched by specified - scheduler. If not specified, the pod will be dispatched by - default scheduler. - type: string - securityContext: - description: 'SecurityContext holds pod-level security attributes - and common container settings. Optional: Defaults to empty. See - type description for default values of each field.' - properties: - fsGroup: - description: "A special supplemental group that applies - to all containers in a pod. Some volume types allow the - Kubelet to change the ownership of that volume to be owned - by the pod: \n 1. The owning GID will be the FSGroup 2. - The setgid bit is set (new files created in the volume - will be owned by FSGroup) 3. The permission bits are OR'd - with rw-rw---- \n If unset, the Kubelet will not modify - the ownership and permissions of any volume." - format: int64 - type: integer - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in SecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a - non-root user. If true, the Kubelet will validate the - image at runtime to ensure that it does not run as UID - 0 (root) and fail to start the container if it does. If - unset or false, no such validation will be performed. - May also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence for - that container. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a - random SELinux context for each container. May also be - set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - supplementalGroups: - description: A list of groups applied to the first process - run in each container, in addition to the container's - primary GID. If unspecified, no groups will be added - to any container. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used - for the pod. Pods with unsupported sysctls (by the container - runtime) might fail to launch. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options within a container's - SecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. This field is - alpha-level and is only honored by servers that enable - the WindowsGMSA feature flag. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. This field is alpha-level - and is only honored by servers that enable the WindowsGMSA - feature flag. - type: string - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. This field is beta-level and may - be disabled with the WindowsRunAsUserName feature - flag. - type: string - type: object - type: object - serviceAccount: - description: 'DeprecatedServiceAccount is a depreciated alias - for ServiceAccountName. Deprecated: Use serviceAccountName - instead.' - type: string - serviceAccountName: - description: 'ServiceAccountName is the name of the ServiceAccount - to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' - type: string - shareProcessNamespace: - description: 'Share a single process namespace between all of - the containers in a pod. When this is set containers will - be able to view and signal processes from other containers - in the same pod, and the first process in each container will - not be assigned PID 1. HostPID and ShareProcessNamespace cannot - both be set. Optional: Default to false.' - type: boolean - subdomain: - description: If specified, the fully qualified Pod hostname - will be "...svc.". If not specified, the pod will not have a domainname - at all. - type: string - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs to terminate - gracefully. May be decreased in delete request. Value must - be non-negative integer. The value zero indicates delete immediately. - If this value is nil, the default grace period will be used - instead. The grace period is the duration in seconds after - the processes running in the pod are sent a termination signal - and the time when the processes are forcibly halted with a - kill signal. Set this value longer than the expected cleanup - time for your process. Defaults to 30 seconds. - format: int64 - type: integer - tolerations: - description: If specified, the pod's tolerations. - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - topologySpreadConstraints: - description: TopologySpreadConstraints describes how a group - of pods ought to spread across topology domains. Scheduler - will schedule pods in a way which abides by the constraints. - This field is alpha-level and is only honored by clusters - that enables the EvenPodsSpread feature. All topologySpreadConstraints - are ANDed. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine - the number of pods in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - maxSkew: - description: 'MaxSkew describes the degree to which pods - may be unevenly distributed. It''s the maximum permitted - difference between the number of matching pods in any - two topology domains of a given topology type. For example, - in a 3-zone cluster, MaxSkew is set to 1, and pods with - the same labelSelector spread as 1/1/0: | zone1 | zone2 - | zone3 | | P | P | | - if MaxSkew is - 1, incoming pod can only be scheduled to zone3 to become - 1/1/1; scheduling it onto zone1(zone2) would make the - ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto - any zone. It''s a required field. Default value is 1 - and 0 is not allowed.' - format: int32 - type: integer - topologyKey: - description: TopologyKey is the key of node labels. Nodes - that have a label with this key and identical values - are considered to be in the same topology. We consider - each as a "bucket", and try to put balanced - number of pods into each bucket. It's a required field. - type: string - whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how to deal - with a pod if it doesn''t satisfy the spread constraint. - - DoNotSchedule (default) tells the scheduler not to - schedule it - ScheduleAnyway tells the scheduler to - still schedule it It''s considered as "Unsatisfiable" - if and only if placing incoming pod on any topology - violates "MaxSkew". For example, in a 3-zone cluster, - MaxSkew is set to 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming - pod can only be scheduled to zone2(zone3) to become - 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be - imbalanced, but scheduler won''t make it *more* imbalanced. - It''s a required field.' - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - description: 'List of volumes that can be mounted by containers - belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - partition: - description: 'The partition in the volume that you - want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, - you specify the partition as "1". Similarly, the - volume partition for /dev/sda is "0" (or you can - leave the property empty).' - format: int32 - type: integer - readOnly: - description: 'Specify "true" to force and set the - ReadOnly property in VolumeMounts to "true". If - omitted, the default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: AzureDisk represents an Azure Data Disk mount - on the host and bind mount to the pod. - properties: - cachingMode: - description: 'Host Caching mode: None, Read Only, - Read Write.' - type: string - diskName: - description: The Name of the data disk in the blob - storage - type: string - diskURI: - description: The URI the data disk in the blob storage - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed - data disk (only in managed availability set). defaults - to shared' - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: AzureFile represents an Azure File Service - mount on the host and bind mount to the pod. - properties: - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: the name of secret that contains Azure - Storage Account Name and Key - type: string - shareName: - description: Share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: CephFS represents a Ceph FS mount on the - host that shares a pod's lifetime - properties: - monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'Optional: Used as the mounted root, - rather than the full Ceph tree, default is /' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'Optional: SecretFile is the path to - key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'Optional: SecretRef is reference to - the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'Cinder represents a cinder volume attached - and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'Filesystem type to mount. Must be a - filesystem type supported by the host operating - system. Examples: "ext4", "xfs", "ntfs". Implicitly - inferred to be "ext4" if unspecified. More info: - https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'Optional: points to a secret object - containing parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: ConfigMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will - be projected into the volume as a file whose name - is the key and content is the value. If specified, - the listed keys will be projected into the specified - paths, and unlisted keys will not be present. If - a key is specified which is not present in the ConfigMap, - the volume setup will error unless it is marked - optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - keys must be defined - type: boolean - type: object - csi: - description: CSI (Container Storage Interface) represents - storage that is handled by an external CSI driver (Alpha - feature). - properties: - driver: - description: Driver is the name of the CSI driver - that handles this volume. Consult with your admin - for the correct name as registered in the cluster. - type: string - fsType: - description: Filesystem type to mount. Ex. "ext4", - "xfs", "ntfs". If not provided, the empty value - is passed to the associated CSI driver which will - determine the default filesystem to apply. - type: string - nodePublishSecretRef: - description: NodePublishSecretRef is a reference to - the secret object containing sensitive information - to pass to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the - secret object contains more than one secret, all - secret references are passed. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: VolumeAttributes stores driver-specific - properties that are passed to the CSI driver. Consult - your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: DownwardAPI represents downward API about - the pod that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' path. - Must be utf-8 encoded. The first item of the - relative path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'EmptyDir represents a temporary directory - that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to - use the node''s default medium. Must be an empty - string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also - applicable for memory medium. The maximum usage - on memory medium EmptyDir would be the minimum value - between the SizeLimit specified here and the sum - of memory limits of all containers in a pod. The - default is nil which means that the limit is undefined. - More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - fc: - description: FC represents a Fibre Channel resource that - is attached to a kubelet's host machine and then exposed - to the pod. - properties: - fsType: - description: 'Filesystem type to mount. Must be a - filesystem type supported by the host operating - system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred - to be "ext4" if unspecified. TODO: how do we prevent - errors in the filesystem from compromising the machine' - type: string - lun: - description: 'Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts.' - type: boolean - targetWWNs: - description: 'Optional: FC target worldwide names - (WWNs)' - items: - type: string - type: array - wwids: - description: 'Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs - and lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: FlexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: Driver is the name of the driver to use - for this volume. - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". The default filesystem depends - on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'Optional: Extra command options if any.' - type: object - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in - VolumeMounts.' - type: boolean - secretRef: - description: 'Optional: SecretRef is reference to - the secret object containing sensitive information - to pass to the plugin scripts. This may be empty - if no secret object is specified. If the secret - object contains more than one secret, all secrets - are passed to the plugin scripts.' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - required: - - driver - type: object - flocker: - description: Flocker represents a Flocker volume attached - to a kubelet's host machine. This depends on the Flocker - control service being running - properties: - datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated - type: string - datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - partition: - description: 'The partition in the volume that you - want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, - you specify the partition as "1". Similarly, the - volume partition for /dev/sda is "0" (or you can - leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More - info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'GitRepo represents a git repository at a - particular revision. DEPRECATED: GitRepo is deprecated. - To provision a container with a git repo, mount an EmptyDir - into an InitContainer that clones the repo using git, - then mount the EmptyDir into the Pod''s container.' - properties: - directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: Repository URL - type: string - revision: - description: Commit hash for the specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'Glusterfs represents a Glusterfs mount on - the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'Path is the Glusterfs volume path. More - info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'ReadOnly here will force the Glusterfs - volume to be mounted with read-only permissions. - Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'HostPath represents a pre-existing file - or directory on the host machine that is directly exposed - to the container. This is generally used for system - agents or other privileged things that are allowed to - see the host machine. Most containers will NOT need - this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host - directory mounts and who can/can not mount host directories - as read/write.' - properties: - path: - description: 'Path of the directory on the host. If - the path is a symlink, it will follow the link to - the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'Type for HostPath Volume Defaults to - "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'ISCSI represents an ISCSI Disk resource - that is attached to a kubelet''s host machine and then - exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP - authentication - type: boolean - chapAuthSession: - description: whether support iSCSI Session CHAP authentication - type: boolean - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, - new iSCSI interface : - will be created for the connection. - type: string - iqn: - description: Target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). - type: string - lun: - description: iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: iSCSI Target Portal List. The portal - is either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than - default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'Volume''s name. Must be a DNS_LABEL and - unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'NFS represents an NFS mount on the host - that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults - to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address - of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents - a reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host - machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - pdID: - description: ID that identifies Photon Controller - persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: PortworxVolume represents a portworx volume - attached and mounted on kubelets host machine - properties: - fsType: - description: FSType represents the filesystem type - to mount Must be a filesystem type supported by - the host operating system. Ex. "ext4", "xfs". Implicitly - inferred to be "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: VolumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: Items for all in one resources secrets, configmaps, - and downward API - properties: - defaultMode: - description: Mode bits to use on created files by - default. Must be a value between 0 and 0777. Directories - within the path are not affected by this setting. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set. - format: int32 - type: integer - sources: - description: list of volume projections - items: - description: Projection that may be projected along - with other supported volume types - properties: - configMap: - description: information about the configMap - data to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - ConfigMap will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed - keys will be projected into the specified - paths, and unlisted keys will not be present. - If a key is specified which is not present - in the ConfigMap, the volume setup will - error unless it is marked optional. Paths - must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of - the file to map the key to. May - not be an absolute path. May not - contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - downwardAPI: - description: information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a - field of the pod: only annotations, - labels, name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema - the FieldPath is written in - terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field - to select in the specified API - version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file to - be created. Must not be absolute - or contain the ''..'' path. Must - be utf-8 encoded. The first item - of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of - the container: only resources limits - and requests (limits.cpu, limits.memory, - requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: - required for volumes, optional - for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output - format of the exposed resources, - defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - secret: - description: information about the secret data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - Secret will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed - keys will be projected into the specified - paths, and unlisted keys will not be present. - If a key is specified which is not present - in the Secret, the volume setup will error - unless it is marked optional. Paths must - be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits - to use on this file, must be a value - between 0 and 0777. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of - the file to map the key to. May - not be an absolute path. May not - contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - type: object - serviceAccountToken: - description: information about the serviceAccountToken - data to project - properties: - audience: - description: Audience is the intended audience - of the token. A recipient of a token must - identify itself with an identifier specified - in the audience of the token, and otherwise - should reject the token. The audience - defaults to the identifier of the apiserver. - type: string - expirationSeconds: - description: ExpirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, - the kubelet volume plugin will proactively - rotate the service account token. The - kubelet will start trying to rotate the - token if the token is older than 80 percent - of its time to live or if the token is - older than 24 hours.Defaults to 1 hour - and must be at least 10 minutes. - format: int64 - type: integer - path: - description: Path is the path relative to - the mount point of the file to project - the token into. - type: string - required: - - path - type: object - type: object - type: array - required: - - sources - type: object - quobyte: - description: Quobyte represents a Quobyte mount on the - host that shares a pod's lifetime - properties: - group: - description: Group to map volume access to Default - is no group - type: string - readOnly: - description: ReadOnly here will force the Quobyte - volume to be mounted with read-only permissions. - Defaults to false. - type: boolean - registry: - description: Registry represents a single or multiple - Quobyte Registry services specified as a string - as host:port pair (multiple entries are separated - with commas) which acts as the central registry - for volumes - type: string - tenant: - description: Tenant owning the given Quobyte volume - in the Backend Used with dynamically provisioned - Quobyte volumes, value is set by the plugin - type: string - user: - description: User to map volume access to Defaults - to serivceaccount user - type: string - volume: - description: Volume is a string that references an - already created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'RBD represents a Rados Block Device mount - on the host that shares a pod''s lifetime. More info: - https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem - from compromising the machine' - type: string - image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'Keyring is the path to key ring for - RBDUser. Default is /etc/ceph/keyring. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'A collection of Ceph monitors. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'The rados pool name. Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'SecretRef is name of the authentication - secret for RBDUser. If provided overrides keyring. - Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: ScaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: The host address of the ScaleIO API Gateway. - type: string - protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef references to the secret for - ScaleIO user and other sensitive information. If - this is not provided, Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - sslEnabled: - description: Flag to enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. - type: string - storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. - type: string - system: - description: The name of the storage system as configured - in ScaleIO. - type: string - volumeName: - description: The name of a volume already created - in the ScaleIO system that is associated with this - volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'Secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a value between 0 and - 0777. Defaults to 0644. Directories within the path - are not affected by this setting. This might be - in conflict with other options that affect the file - mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be - projected into the volume as a file whose name is - the key and content is the value. If specified, - the listed keys will be projected into the specified - paths, and unlisted keys will not be present. If - a key is specified which is not present in the Secret, - the volume setup will error unless it is marked - optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits to use on - this file, must be a value between 0 and 0777. - If not specified, the volume defaultMode will - be used. This might be in conflict with other - options that affect the file mode, like fsGroup, - and the result can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May - not start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: Specify whether the Secret or its keys - must be defined - type: boolean - secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: StorageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef specifies the secret to use - for obtaining the StorageOS API credentials. If - not specified, default values will be attempted. - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeName: - description: VolumeName is the human-readable name - of the StorageOS volume. Volume names are only - unique within a namespace. - type: string - volumeNamespace: - description: VolumeNamespace specifies the scope of - the volume within StorageOS. If no namespace is - specified then the Pod's namespace will be used. This - allows the Kubernetes name scoping to be mirrored - within StorageOS for tighter integration. Set VolumeName - to any name to override the default behaviour. Set - to "default" if you are not using namespaces within - StorageOS. Namespaces that do not pre-exist within - StorageOS will be created. - type: string - type: object - vsphereVolume: - description: VsphereVolume represents a vSphere volume - attached and mounted on kubelets host machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. - "ext4", "xfs", "ntfs". Implicitly inferred to be - "ext4" if unspecified. - type: string - storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. - type: string - volumePath: - description: Path that identifies vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - required: - - containers - type: object - type: object - racks: - description: A list of the named racks in the datacenter, representing - independent failure domains. The number of racks should match the - replication factor in the keyspaces you plan to create, and the number - of racks cannot easily be changed once a datacenter is deployed. - items: - description: Rack ... - properties: - name: - description: The rack name - minLength: 2 - type: string - nodeAffinityLabels: - additionalProperties: - type: string - description: NodeAffinityLabels to pin the rack, using node affinity - type: object - zone: - description: Deprecated. Use nodeAffinityLabels instead. Zone - name to pin the rack, using node affinity - type: string - required: - - name - type: object - type: array - reaper: - description: 'Deprecated: Reaper''s sidecar mode has too many problems - in Kubernetes for it to usable. In order for it to work reliably, - changes in Reaper would be needed. See https://github.com/thelastpickle/cassandra-reaper/issues/956 - for details. Because those changes were not implemented in Reaper - and because Reaper support was instead added through k8ssandra, this - field will be removed in the 1.8.0 release.' - properties: - enabled: - type: boolean - image: - type: string - imagePullPolicy: - description: PullPolicy describes a policy for if/when to pull a - container image - type: string - resources: - description: Kubernetes resource requests and limits per reaper - container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - type: object - replaceNodes: - description: A list of pod names that need to be replaced. - items: - type: string - type: array - resources: - description: Kubernetes resource requests and limits, per pod - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - rollingRestartRequested: - description: Whether to do a rolling restart at the next opportunity. - The operator will set this back to false once the restart is in progress. - type: boolean - serverImage: - description: 'Cassandra server image name. More info: https://kubernetes.io/docs/concepts/containers/images' - type: string - serverType: - description: 'Server type: "cassandra" or "dse"' - enum: - - cassandra - - dse - type: string - serverVersion: - description: Version string for config builder, used to generate Cassandra - server configuration - pattern: (6\.8\.\d+)|(3\.11\.\d+)|(4\.0\.\d+) - type: string - serviceAccount: - description: The k8s service account to use for the server pods - type: string - size: - description: Desired number of Cassandra server nodes - format: int32 - minimum: 1 - type: integer - stopped: - description: A stopped CassandraDatacenter will have no running server - pods, like using "stop" with traditional System V init scripts. Other - Kubernetes resources will be left intact, and volumes will re-attach - when the CassandraDatacenter workload is resumed. - type: boolean - storageConfig: - description: Describes the persistent storage request of each server - node - properties: - additionalVolumes: - items: - description: StorageConfig defines additional storage configurations - properties: - mountPath: - description: Mount path into cassandra container - type: string - name: - description: Name of the pvc - pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?' - type: string - pvcSpec: - description: Persistent volume claim spec - properties: - accessModes: - description: 'AccessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: This field requires the VolumeSnapshotDataSource - alpha feature gate to be enabled and currently VolumeSnapshot - is the only supported data source. If the provisioner - can support VolumeSnapshot data source, it will create - a new volume and data will be restored to the volume - at the same time. If the provisioner does not support - VolumeSnapshot data source, volume will not be created - and the failure will be reported as an event. In the - future, we plan to support more data source types and - the behavior of the provisioner may change. - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum resources - the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - selector: - description: A label query over volumes to consider for - binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required by the - claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. This is a beta feature. - type: string - volumeName: - description: VolumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - required: - - mountPath - - name - - pvcSpec - type: object - type: array - cassandraDataVolumeClaimSpec: - description: PersistentVolumeClaimSpec describes the common attributes - of storage devices and allows a Source for provider-specific attributes - properties: - accessModes: - description: 'AccessModes contains the desired access modes - the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: This field requires the VolumeSnapshotDataSource - alpha feature gate to be enabled and currently VolumeSnapshot - is the only supported data source. If the provisioner can - support VolumeSnapshot data source, it will create a new volume - and data will be restored to the volume at the same time. - If the provisioner does not support VolumeSnapshot data source, - volume will not be created and the failure will be reported - as an event. In the future, we plan to support more data source - types and the behavior of the provisioner may change. - properties: - apiGroup: - description: APIGroup is the group for the resource being - referenced. If APIGroup is not specified, the specified - Kind must be in the core API group. For any other third-party - types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum resources the - volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. More info: - https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - selector: - description: A label query over volumes to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume is required - by the claim. Value of Filesystem is implied when not included - in claim spec. This is a beta feature. - type: string - volumeName: - description: VolumeName is the binding reference to the PersistentVolume - backing this claim. - type: string - type: object - type: object - superuserSecretName: - description: This secret defines the username and password for the Cassandra - server superuser. If it is omitted, we will generate a secret instead. - type: string - systemLoggerImage: - description: Container image for the log tailing sidecar container. - type: string - systemLoggerResources: - description: Kubernetes resource requests and limits per system logger - container. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute resources - required. If Requests is omitted for a container, it defaults - to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' - type: object - type: object - tolerations: - description: Tolerations applied to the Cassandra pod. Note that these - cannot be overridden with PodTemplateSpec. - items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . - properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, operator - must be Exists; this combination means to match all values and - all keys. - type: string - operator: - description: Operator represents a key's relationship to the value. - Valid operators are Exists and Equal. Defaults to Equal. Exists - is equivalent to wildcard for value, so that a pod can tolerate - all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time the - toleration (which must be of effect NoExecute, otherwise this - field is ignored) tolerates the taint. By default, it is not - set, which means tolerate the taint forever (do not evict). - Zero and negative values will be treated as 0 (evict immediately) - by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches to. - If the operator is Exists, the value should be empty, otherwise - just a regular string. - type: string - type: object - type: array - users: - description: Cassandra users to bootstrap - items: - properties: - secretName: - type: string - superuser: - type: boolean - required: - - secretName - - superuser - type: object - type: array - required: - - clusterName - - serverType - - serverVersion - - size - - storageConfig - type: object - status: - description: CassandraDatacenterStatus defines the observed state of CassandraDatacenter - properties: - cassandraOperatorProgress: - description: Last known progress state of the Cassandra Operator - type: string - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - status: - type: string - type: - type: string - required: - - message - - reason - - status - - type - type: object - type: array - lastRollingRestart: - format: date-time - type: string - lastServerNodeStarted: - description: The timestamp when the operator last started a Server node - with the management API - format: date-time - type: string - nodeReplacements: - items: - type: string - type: array - nodeStatuses: - additionalProperties: - properties: - hostID: - type: string - type: object - type: object - observedGeneration: - format: int64 - type: integer - quietPeriod: - format: date-time - type: string - superUserUpserted: - description: Deprecated. Use usersUpserted instead. The timestamp at - which CQL superuser credentials were last upserted to the management - API - format: date-time - type: string - usersUpserted: - description: The timestamp at which managed cassandra users' credentials - were last upserted to the management API - format: date-time - type: string - type: object - type: object - x-kubernetes-preserve-unknown-fields: true - version: v1beta1 - versions: - - name: v1beta1 - served: true - storage: true diff --git a/operator/deploy/namespace.yaml b/operator/deploy/namespace.yaml deleted file mode 100644 index cf7b7043..00000000 --- a/operator/deploy/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: cass-operator diff --git a/operator/deploy/operator.yaml b/operator/deploy/operator.yaml deleted file mode 100644 index fe11a9f6..00000000 --- a/operator/deploy/operator.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cass-operator - namespace: "" -spec: - replicas: 1 - selector: - matchLabels: - name: cass-operator - template: - metadata: - labels: - name: cass-operator - spec: - serviceAccountName: cass-operator - volumes: - - name: tmpconfig-volume - emptyDir: - medium: "Memory" - - name: cass-operator-certs-volume - secret: - secretName: cass-operator-webhook-config - containers: - - name: cass-operator - image: k8ssandra/cass-operator:latest - imagePullPolicy: IfNotPresent - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cass-operator-certs-volume - readOnly: false - - mountPath: /tmp/ - name: tmpconfig-volume - readOnly: false - securityContext: - runAsUser: 65534 - runAsGroup: 65534 - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - livenessProbe: - exec: - command: - - pgrep - - ".*operator" - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - failureThreshold: 3 - readinessProbe: - exec: - command: - - stat - - "/tmp/operator-sdk-ready" - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 5 - failureThreshold: 1 - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: "cass-operator" - - name: SKIP_VALIDATING_WEBHOOK - value: "FALSE" diff --git a/operator/deploy/role.yaml b/operator/deploy/role.yaml deleted file mode 100644 index a9102c0f..00000000 --- a/operator/deploy/role.yaml +++ /dev/null @@ -1,73 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: cass-operator - namespace: "" -rules: -- apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - verbs: - - '*' -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get -- apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - '*' -- apiGroups: - - monitoring.coreos.com - resources: - - servicemonitors - verbs: - - get - - create -- apiGroups: - - apps - resourceNames: - - cass-operator - resources: - - deployments/finalizers - verbs: - - update -- apiGroups: - - datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - '*' -- apiGroups: - - cassandra.datastax.com - resources: - - '*' - verbs: - - '*' -- apiGroups: - - batch - resources: - - '*' - verbs: - - '*' - diff --git a/operator/deploy/webhook_configuration.yaml b/operator/deploy/webhook_configuration.yaml deleted file mode 100644 index acb75fd6..00000000 --- a/operator/deploy/webhook_configuration.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: admissionregistration.k8s.io/v1beta1 -kind: ValidatingWebhookConfiguration -metadata: - name: "cassandradatacenter-webhook-registration" -webhooks: -- name: "cassandradatacenter-webhook.cassandra.datastax.com" - rules: - - apiGroups: ["cassandra.datastax.com"] - apiVersions: ["v1beta1"] - operations: ["CREATE", "UPDATE", "DELETE"] - resources: ["cassandradatacenters"] - scope: "*" - clientConfig: - service: - name: "cassandradatacenter-webhook-service" - namespace: "cass-operator" - path: /validate-cassandra-datastax-com-v1beta1-cassandradatacenter - admissionReviewVersions: ["v1beta1"] - failurePolicy: "Ignore" - matchPolicy: "Equivalent" - sideEffects: None - timeoutSeconds: 10 diff --git a/operator/deploy/webhook_secret.yaml b/operator/deploy/webhook_secret.yaml deleted file mode 100644 index 8ede3d73..00000000 --- a/operator/deploy/webhook_secret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -data: - tls.crt: "" - tls.key: "" -kind: Secret -metadata: - name: cass-operator-webhook-config diff --git a/operator/deploy/webhook_service.yaml b/operator/deploy/webhook_service.yaml deleted file mode 100644 index 49b1e61a..00000000 --- a/operator/deploy/webhook_service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: cassandradatacenter-webhook-service - labels: - name: cass-operator-webhook -spec: - ports: - - port: 443 - targetPort: 8443 - selector: - name: cass-operator diff --git a/operator/pkg/admissionwebhook/webhook.go b/operator/pkg/admissionwebhook/webhook.go deleted file mode 100644 index 6c960a1c..00000000 --- a/operator/pkg/admissionwebhook/webhook.go +++ /dev/null @@ -1,187 +0,0 @@ -package webhook - -import ( - "context" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/k8ssandra/cass-operator/operator/pkg/utils" - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - crclient "sigs.k8s.io/controller-runtime/pkg/client" -) - -var ( - altCertDir = filepath.Join(os.TempDir()) //Alt directory is necessary because regular key/cert mountpoint is read-only - certDir = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs") - - serverCertFile = filepath.Join(os.TempDir(), "k8s-webhook-server", "serving-certs", "tls.crt") - altServerCertFile = filepath.Join(altCertDir, "tls.crt") - altServerKeyFile = filepath.Join(altCertDir, "tls.key") - - log = logf.Log.WithName("cmd") -) - -func EnsureWebhookCertificate(cfg *rest.Config) (certDir string, err error) { - var contents []byte - var webhook map[string]interface{} - var bundled string - var client crclient.Client - namespace, err := k8sutil.GetOperatorNamespace() - if err != nil { - return "", err - } - var certpool *x509.CertPool - if contents, err = ioutil.ReadFile(serverCertFile); err == nil && len(contents) > 0 { - if client, err = crclient.New(cfg, crclient.Options{}); err == nil { - if err, _, webhook, _ = fetchWebhookForNamespace(client, namespace); err == nil { - if bundled, _, err = unstructured.NestedString(webhook, "clientConfig", "caBundle"); err == nil { - if base64.StdEncoding.EncodeToString([]byte(contents)) == bundled { - certpool, err = x509.SystemCertPool() - if err != nil { - certpool = x509.NewCertPool() - } - var block *pem.Block - if block, _ = pem.Decode(contents); err == nil && block != nil { - var cert *x509.Certificate - if cert, err = x509.ParseCertificate(block.Bytes); err == nil { - certpool.AddCert(cert) - log.Info("Attempting to validate operator CA") - verify_opts := x509.VerifyOptions{ - DNSName: fmt.Sprintf("cassandradatacenter-webhook-service.%s.svc", namespace), - Roots: certpool, - } - if _, err = cert.Verify(verify_opts); err == nil { - log.Info("Found valid certificate for webhook") - return certDir, nil - } - } - } - } - } - } - } - } - return updateSecretAndWebhook(cfg, namespace) -} - -func updateSecretAndWebhook(cfg *rest.Config, namespace string) (certDir string, err error) { - var key, cert string - var client crclient.Client - if key, cert, err = utils.GetNewCAandKey("cass-operator-webhook-config", namespace); err == nil { - if client, err = crclient.New(cfg, crclient.Options{}); err == nil { - secret := &v1.Secret{} - err = client.Get(context.Background(), crclient.ObjectKey{ - Namespace: namespace, - Name: "cass-operator-webhook-config", - }, secret) - if err == nil { - secret.StringData = make(map[string]string) - secret.StringData["tls.key"] = key - secret.StringData["tls.crt"] = cert - if err = client.Update(context.Background(), secret); err == nil { - log.Info("TLS secret for webhook updated") - if err = ioutil.WriteFile(altServerCertFile, []byte(cert), 0600); err == nil { - if err = ioutil.WriteFile(altServerKeyFile, []byte(key), 0600); err == nil { - certDir = altCertDir - log.Info("TLS secret updated in pod mount") - return certDir, updateWebhook(client, cert, namespace) - } - } - } - - } - } - } - log.Error(err, "Failed to update certificates") - return certDir, err -} - -func fetchWebhookForNamespace(client crclient.Client, namespace string) (err error, webhook_config *unstructured.Unstructured, webhook map[string]interface{}, unstructured_index int) { - - webhook_config = &unstructured.Unstructured{} - webhook_config.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "admissionregistration.k8s.io", - Kind: "ValidatingWebhookConfiguration", - Version: "v1beta1", - }) - err = client.Get(context.Background(), crclient.ObjectKey{ - Name: "cassandradatacenter-webhook-registration", - }, webhook_config) - if err != nil { - return err, webhook_config, webhook, 0 - } - var ok, present bool - var found_namespace string - var webhook_list []interface{} - if webhook_list, present, err = unstructured.NestedSlice(webhook_config.Object, "webhooks"); err == nil { - if present { - for webhook_index, webhook_untypped := range webhook_list { - webhook, ok = webhook_untypped.(map[string]interface{}) - if ok { - if found_namespace, _, err = unstructured.NestedString(webhook, "clientConfig", "service", "namespace"); found_namespace == namespace { - return nil, webhook_config, webhook, webhook_index - } - } - } - } - return errors.New("Webhook not found for namespace"), webhook_config, webhook, 0 - } - return err, webhook_config, webhook, 0 -} - -func updateWebhook(client crclient.Client, cert, namespace string) (err error) { - var webhook_slice []interface{} - var webhook map[string]interface{} - var present bool - var webhook_index int - var webhook_config *unstructured.Unstructured - err, webhook_config, webhook, webhook_index = fetchWebhookForNamespace(client, namespace) - if err == nil { - if err = unstructured.SetNestedField(webhook, namespace, "clientConfig", "service", "namespace"); err == nil { - if err = unstructured.SetNestedField(webhook, base64.StdEncoding.EncodeToString([]byte(cert)), "clientConfig", "caBundle"); err == nil { - if webhook_slice, present, err = unstructured.NestedSlice(webhook_config.Object, "webhooks"); present && err == nil { - webhook_slice[webhook_index] = webhook - if err = unstructured.SetNestedSlice(webhook_config.Object, webhook_slice, "webhooks"); err == nil { - err = client.Update(context.Background(), webhook_config) - } - } - } - } - } - return err -} - -func EnsureWebhookConfigVolume(cfg *rest.Config) (err error) { - var pod *v1.Pod - namespace, err := k8sutil.GetOperatorNamespace() - if err != nil { - return err - } - var client crclient.Client - if client, err = crclient.New(cfg, crclient.Options{}); err == nil { - if pod, err = k8sutil.GetPod(context.Background(), client, namespace); err == nil { - for _, volume := range pod.Spec.Volumes { - if "cass-operator-certs-volume" == volume.Name { - return nil - } - } - log.Error(fmt.Errorf("Secrets volume not found, unable to start webhook"), "") - os.Exit(1) - } - } - return err -} diff --git a/operator/pkg/apis/addtoscheme_cassandra_v1beta1.go b/operator/pkg/apis/addtoscheme_cassandra_v1beta1.go deleted file mode 100644 index 429f28cb..00000000 --- a/operator/pkg/apis/addtoscheme_cassandra_v1beta1.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package apis - -import ( - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, v1beta1.SchemeBuilder.AddToScheme) -} diff --git a/operator/pkg/apis/apis.go b/operator/pkg/apis/apis.go deleted file mode 100644 index c671e028..00000000 --- a/operator/pkg/apis/apis.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package apis - -import ( - "k8s.io/apimachinery/pkg/runtime" -) - -// AddToSchemes may be used to add all resources defined in the project to a Scheme -var AddToSchemes runtime.SchemeBuilder - -// AddToScheme adds all Resources to the Scheme -func AddToScheme(s *runtime.Scheme) error { - return AddToSchemes.AddToScheme(s) -} diff --git a/operator/pkg/apis/cassandra/group.go b/operator/pkg/apis/cassandra/group.go deleted file mode 100644 index 18f993c3..00000000 --- a/operator/pkg/apis/cassandra/group.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -// Package cassandra contains cassandra API versions. -// -// This file ensures Go source parsers acknowledge the cassandra package -// and any child packages. It can be removed if any other Go source files are -// added to this package. -package cassandra diff --git a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types_test.go b/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types_test.go deleted file mode 100644 index 69463879..00000000 --- a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types_test.go +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package v1beta1 - -import ( - "testing" - - "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestCassandraDatacenter_GetServerImage(t *testing.T) { - type fields struct { - TypeMeta metav1.TypeMeta - ObjectMeta metav1.ObjectMeta - Spec CassandraDatacenterSpec - Status CassandraDatacenterStatus - } - tests := []struct { - name string - fields fields - want string - errString string - }{ - { - name: "explicit server image specified", - fields: fields{ - Spec: CassandraDatacenterSpec{ - ServerImage: "jfrog.io:6789/dse-server-team/dse-server:6.8.0-123", - ServerVersion: "6.8.0", - }, - }, - want: "jfrog.io:6789/dse-server-team/dse-server:6.8.0-123", - errString: "", - }, - { - name: "invalid version specified", - fields: fields{ - Spec: CassandraDatacenterSpec{ - ServerImage: "", - ServerVersion: "9000", - }, - }, - want: "", - errString: "Unknown server type ''", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dc := &CassandraDatacenter{ - TypeMeta: tt.fields.TypeMeta, - ObjectMeta: tt.fields.ObjectMeta, - Spec: tt.fields.Spec, - Status: tt.fields.Status, - } - got := dc.GetServerImage() - if got != tt.want { - t.Errorf("CassandraDatacenter.GetServerImage() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_GenerateBaseConfigString(t *testing.T) { - tests := []struct { - name string - dc *CassandraDatacenter - want string - errString string - }{ - { - name: "Simple Test", - dc: &CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: "exampleDC", - }, - Spec: CassandraDatacenterSpec{ - ClusterName: "exampleCluster", - Config: []byte("{\"cassandra-yaml\":{\"authenticator\":\"AllowAllAuthenticator\",\"batch_size_fail_threshold_in_kb\":1280}}"), - }, - }, - want: `{"cassandra-yaml":{"authenticator":"AllowAllAuthenticator","batch_size_fail_threshold_in_kb":1280},"cluster-info":{"name":"exampleCluster","seeds":"exampleCluster-seed-service"},"datacenter-info":{"graph-enabled":0,"name":"exampleDC","solr-enabled":0,"spark-enabled":0}}`, - errString: "", - }, - { - name: "Simple Test for error", - dc: &CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: "exampleDC", - }, - Spec: CassandraDatacenterSpec{ - ClusterName: "exampleCluster", - Config: []byte("\"cassandra-yaml\":{\"authenticator\":\"AllowAllAuthenticator\",\"batch_size_fail_threshold_in_kb\":1280}}"), - }, - }, - want: "", - errString: "Error parsing Spec.Config for CassandraDatacenter resource: invalid character ':' after top-level value", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.dc.GetConfigAsJSON(tt.dc.Spec.Config) - if got != tt.want { - t.Errorf("GenerateBaseConfigString() got = %v, want %v", got, tt.want) - } - if err == nil { - if tt.errString != "" { - t.Errorf("GenerateBaseConfigString() err = %v, want %v", err, tt.errString) - } - } else { - if err.Error() != tt.errString { - t.Errorf("GenerateBaseConfigString() err = %v, want %v", err, tt.errString) - } - } - }) - } -} - -func TestCassandraDatacenter_GetContainerPorts(t *testing.T) { - type fields struct { - TypeMeta metav1.TypeMeta - ObjectMeta metav1.ObjectMeta - Spec CassandraDatacenterSpec - Status CassandraDatacenterStatus - } - tests := []struct { - name string - fields fields - want []corev1.ContainerPort - wantErr bool - }{ - { - name: "Cassandra 3.11.6", - fields: fields{ - Spec: CassandraDatacenterSpec{ - ClusterName: "exampleCluster", - ServerType: "cassandra", - ServerVersion: "3.11.6", - }, - }, - want: []corev1.ContainerPort{ - { - Name: "native", - ContainerPort: DefaultNativePort, - }, { - Name: "tls-native", - ContainerPort: 9142, - }, { - Name: "internode", - ContainerPort: DefaultInternodePort, - }, { - Name: "tls-internode", - ContainerPort: 7001, - }, { - Name: "jmx", - ContainerPort: 7199, - }, { - Name: "mgmt-api-http", - ContainerPort: 8080, - }, { - Name: "prometheus", - ContainerPort: 9103, - }, { - Name: "thrift", - ContainerPort: 9160, - }, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dc := &CassandraDatacenter{ - TypeMeta: tt.fields.TypeMeta, - ObjectMeta: tt.fields.ObjectMeta, - Spec: tt.fields.Spec, - Status: tt.fields.Status, - } - got, err := dc.GetContainerPorts() - if tt.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - assert.Equal(t, tt.want, got) - }) - } -} - -func TestCassandraDatacenter_GetSeedServiceName(t *testing.T) { - dc := &CassandraDatacenter{ - Spec: CassandraDatacenterSpec{ - ClusterName: "bob", - }, - } - want := "bob-seed-service" - got := dc.GetSeedServiceName() - - if want != got { - t.Errorf("CassandraDatacenter.GetSeedService() = %v, want %v", got, want) - } -} - -func TestCassandraDatacenter_SplitRacks_balances_racks_when_no_extra_nodes(t *testing.T) { - rackNodeCounts := SplitRacks(10, 5) - assert.ElementsMatch(t, rackNodeCounts, []int{2, 2, 2, 2, 2}, "Rack node counts were not balanced") -} - -func TestCassandraDatacenter_SplitRacks_balances_racks_when_some_extra_nodes(t *testing.T) { - rackNodeCounts := SplitRacks(13, 5) - assert.ElementsMatch(t, rackNodeCounts, []int{3, 3, 3, 2, 2}, "Rack node counts were not balanced") -} - -func TestCassandraDatacenter_GetRackLabels(t *testing.T) { - type args struct { - rackName string - } - tests := []struct { - name string - cassdc CassandraDatacenter - args args - want map[string]string - }{ - { - name: "test GetRackLabels()", - cassdc: CassandraDatacenter{ - Spec: CassandraDatacenterSpec{ - ClusterName: "exampleCluster", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "exampleDC", - }, - }, - args: args{ - rackName: "rack0", - }, - want: map[string]string{ - ClusterLabel: "exampleCluster", - DatacenterLabel: "exampleDC", - RackLabel: "rack0", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dc := &(tt.cassdc) - got := dc.GetRackLabels(tt.args.rackName) - assert.Equal(t, tt.want, got) - }) - } -} diff --git a/operator/pkg/apis/cassandra/v1beta1/doc.go b/operator/pkg/apis/cassandra/v1beta1/doc.go deleted file mode 100644 index b9a15df4..00000000 --- a/operator/pkg/apis/cassandra/v1beta1/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -// Package v1beta1 contains API Schema definitions for the cassandra v1beta1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=cassandra.datastax.com -package v1beta1 diff --git a/operator/pkg/apis/cassandra/v1beta1/register.go b/operator/pkg/apis/cassandra/v1beta1/register.go deleted file mode 100644 index b553a576..00000000 --- a/operator/pkg/apis/cassandra/v1beta1/register.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -// NOTE: Boilerplate only. Ignore this file. - -// Package v1beta1 contains API Schema definitions for the cassandra v1beta1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=cassandra.datastax.com -package v1beta1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "cassandra.datastax.com", Version: "v1beta1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} -) - -// everything below here wasn't generated by operator-sdk, but the sample-controller project has it in register.go, -// and we need it for client-gen -// see https://github.com/kubernetes/sample-controller/blob/master/pkg/apis/samplecontroller/v1alpha1/register.go - -// AddToScheme is a global function that registers this API group & version to a scheme -var AddToScheme = SchemeBuilder.AddToScheme - -// Resource takes an unqualified resource and returns a Group qualified GroupResource -func Resource(resource string) schema.GroupResource { - return SchemeGroupVersion.WithResource(resource).GroupResource() -} diff --git a/operator/pkg/apis/cassandra/v1beta1/zz_generated.openapi.go b/operator/pkg/apis/cassandra/v1beta1/zz_generated.openapi.go deleted file mode 100644 index d7a96d08..00000000 --- a/operator/pkg/apis/cassandra/v1beta1/zz_generated.openapi.go +++ /dev/null @@ -1,312 +0,0 @@ -// +build !ignore_autogenerated - -// This file was autogenerated by openapi-gen. Do not edit it manually! - -package v1beta1 - -import ( - spec "github.com/go-openapi/spec" - common "k8s.io/kube-openapi/pkg/common" -) - -func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - return map[string]common.OpenAPIDefinition{ - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenter": schema_pkg_apis_cassandra_v1beta1_CassandraDatacenter(ref), - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterSpec": schema_pkg_apis_cassandra_v1beta1_CassandraDatacenterSpec(ref), - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterStatus": schema_pkg_apis_cassandra_v1beta1_CassandraDatacenterStatus(ref), - } -} - -func schema_pkg_apis_cassandra_v1beta1_CassandraDatacenter(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "CassandraDatacenter is the Schema for the cassandradatacenters API", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterSpec", "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraDatacenterStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_cassandra_v1beta1_CassandraDatacenterSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "CassandraDatacenterSpec defines the desired state of a CassandraDatacenter", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "size": { - SchemaProps: spec.SchemaProps{ - Description: "Desired number of Cassandra server nodes", - Type: []string{"integer"}, - Format: "int32", - }, - }, - "serverVersion": { - SchemaProps: spec.SchemaProps{ - Description: "Version string for config builder, used to generate Cassandra server configuration", - Type: []string{"string"}, - Format: "", - }, - }, - "serverImage": { - SchemaProps: spec.SchemaProps{ - Description: "Cassandra server image name. More info: https://kubernetes.io/docs/concepts/containers/images", - Type: []string{"string"}, - Format: "", - }, - }, - "serverType": { - SchemaProps: spec.SchemaProps{ - Description: "Server type: \"cassandra\" or \"dse\"", - Type: []string{"string"}, - Format: "", - }, - }, - "config": { - SchemaProps: spec.SchemaProps{ - Description: "Config for the server, in YAML format", - Type: []string{"string"}, - Format: "byte", - }, - }, - "managementApiAuth": { - SchemaProps: spec.SchemaProps{ - Description: "Config for the Management API certificates", - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.ManagementApiAuthConfig"), - }, - }, - "resources": { - SchemaProps: spec.SchemaProps{ - Description: "Kubernetes resource requests and limits, per pod", - Ref: ref("k8s.io/api/core/v1.ResourceRequirements"), - }, - }, - "racks": { - SchemaProps: spec.SchemaProps{ - Description: "A list of the named racks in the datacenter, representing independent failure domains. The number of racks should match the replication factor in the keyspaces you plan to create, and the number of racks cannot easily be changed once a datacenter is deployed.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.Rack"), - }, - }, - }, - }, - }, - "storageConfig": { - SchemaProps: spec.SchemaProps{ - Description: "Describes the persistent storage request of each server node", - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.StorageConfig"), - }, - }, - "replaceNodes": { - SchemaProps: spec.SchemaProps{ - Description: "A list of pod names that need to be replaced.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "clusterName": { - SchemaProps: spec.SchemaProps{ - Description: "The name by which CQL clients and instances will know the cluster. If the same cluster name is shared by multiple Datacenters in the same Kubernetes namespace, they will join together in a multi-datacenter cluster.", - Type: []string{"string"}, - Format: "", - }, - }, - "stopped": { - SchemaProps: spec.SchemaProps{ - Description: "A stopped CassandraDatacenter will have no running server pods, like using \"stop\" with traditional System V init scripts. Other Kubernetes resources will be left intact, and volumes will re-attach when the CassandraDatacenter workload is resumed.", - Type: []string{"boolean"}, - Format: "", - }, - }, - "configBuilderImage": { - SchemaProps: spec.SchemaProps{ - Description: "Container image for the config builder init container.", - Type: []string{"string"}, - Format: "", - }, - }, - "canaryUpgrade": { - SchemaProps: spec.SchemaProps{ - Description: "Indicates that configuration and container image changes should only be pushed to the first rack of the datacenter", - Type: []string{"boolean"}, - Format: "", - }, - }, - "allowMultipleNodesPerWorker": { - SchemaProps: spec.SchemaProps{ - Description: "Turning this option on allows multiple server pods to be created on a k8s worker node. By default the operator creates just one server pod per k8s worker node using k8s podAntiAffinity and requiredDuringSchedulingIgnoredDuringExecution.", - Type: []string{"boolean"}, - Format: "", - }, - }, - "superuserSecretName": { - SchemaProps: spec.SchemaProps{ - Description: "This secret defines the username and password for the Cassandra server superuser. If it is omitted, we will generate a secret instead.", - Type: []string{"string"}, - Format: "", - }, - }, - "serviceAccount": { - SchemaProps: spec.SchemaProps{ - Description: "The k8s service account to use for the server pods", - Type: []string{"string"}, - Format: "", - }, - }, - "rollingRestartRequested": { - SchemaProps: spec.SchemaProps{ - Description: "Whether to do a rolling restart at the next opportunity. The operator will set this back to false once the restart is in progress.", - Type: []string{"boolean"}, - Format: "", - }, - }, - "nodeSelector": { - SchemaProps: spec.SchemaProps{ - Description: "A map of label keys and values to restrict Cassandra node scheduling to k8s workers with matchiing labels. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "podTemplateSpec": { - SchemaProps: spec.SchemaProps{ - Description: "PodTemplate provides customisation options (labels, annotations, affinity rules, resource requests, and so on) for the cassandra pods", - Ref: ref("k8s.io/api/core/v1.PodTemplateSpec"), - }, - }, - }, - Required: []string{"size", "serverVersion", "serverType", "storageConfig", "clusterName"}, - }, - }, - Dependencies: []string{ - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.ManagementApiAuthConfig", "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.Rack", "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.StorageConfig", "k8s.io/api/core/v1.PodTemplateSpec", "k8s.io/api/core/v1.ResourceRequirements"}, - } -} - -func schema_pkg_apis_cassandra_v1beta1_CassandraDatacenterStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "CassandraDatacenterStatus defines the observed state of CassandraDatacenter", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "conditions": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.DatacenterCondition"), - }, - }, - }, - }, - }, - "superUserUpserted": { - SchemaProps: spec.SchemaProps{ - Description: "The timestamp at which CQL superuser credentials were last upserted to the management API", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "lastServerNodeStarted": { - SchemaProps: spec.SchemaProps{ - Description: "The timestamp when the operator last started a Server node with the management API", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "cassandraOperatorProgress": { - SchemaProps: spec.SchemaProps{ - Description: "Last known progress state of the Cassandra Operator", - Type: []string{"string"}, - Format: "", - }, - }, - "lastRollingRestart": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), - }, - }, - "nodeStatuses": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraNodeStatus"), - }, - }, - }, - }, - }, - "nodeReplacements": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.CassandraNodeStatus", "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1.DatacenterCondition", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, - } -} diff --git a/operator/pkg/controller/add_cassandradatacenter.go b/operator/pkg/controller/add_cassandradatacenter.go deleted file mode 100644 index 5d77f8cc..00000000 --- a/operator/pkg/controller/add_cassandradatacenter.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package controller - -import ( - "github.com/k8ssandra/cass-operator/operator/pkg/controller/cassandradatacenter" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, cassandradatacenter.Add) -} diff --git a/operator/pkg/controller/cassandradatacenter/cassandradatacenter_controller.go b/operator/pkg/controller/cassandradatacenter/cassandradatacenter_controller.go deleted file mode 100644 index 6f62b992..00000000 --- a/operator/pkg/controller/cassandradatacenter/cassandradatacenter_controller.go +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package cassandradatacenter - -import ( - "fmt" - - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" - - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" - - appsv1 "k8s.io/api/apps/v1" - policyv1beta1 "k8s.io/api/policy/v1beta1" - logf "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/k8ssandra/cass-operator/operator/pkg/reconciliation" - corev1 "k8s.io/api/core/v1" - types "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("cassandradatacenter_controller") - -// Add creates a new CassandraDatacenter Controller and adds it to the Manager. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, reconciliation.NewReconciler(mgr)) -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New( - "cassandradatacenter-controller", - mgr, - controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to primary resource CassandraDatacenter - err = c.Watch( - &source.Kind{Type: &api.CassandraDatacenter{}}, - &handler.EnqueueRequestForObject{}, - // This allows us to update the status on every reconcile call without - // triggering an infinite loop. - predicate.GenerationChangedPredicate{}) - if err != nil { - return err - } - - // Here we list all the types that we create that are owned by the primary resource. - // - // Watch for changes to secondary resources StatefulSets, PodDisruptionBudgets, and Services and requeue the - // CassandraDatacenter that owns them. - - managedByCassandraOperatorPredicate := predicate.Funcs{ - CreateFunc: func(e event.CreateEvent) bool { - return oplabels.HasManagedByCassandraOperatorLabel(e.Meta.GetLabels()) - }, - DeleteFunc: func(e event.DeleteEvent) bool { - return oplabels.HasManagedByCassandraOperatorLabel(e.Meta.GetLabels()) - }, - UpdateFunc: func(e event.UpdateEvent) bool { - return oplabels.HasManagedByCassandraOperatorLabel(e.MetaOld.GetLabels()) || - oplabels.HasManagedByCassandraOperatorLabel(e.MetaNew.GetLabels()) - }, - GenericFunc: func(e event.GenericEvent) bool { - return oplabels.HasManagedByCassandraOperatorLabel(e.Meta.GetLabels()) - }, - } - - // NOTE: We do not currently watch PVC resources, but if we did, we'd have to - // account for the fact that they might use the old managed-by label value - // (oplabels.ManagedByLabelDefunctValue) for CassandraDatacenters originally - // created in version 1.1.0 or earlier. - - err = c.Watch( - &source.Kind{Type: &appsv1.StatefulSet{}}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &api.CassandraDatacenter{}, - }, - managedByCassandraOperatorPredicate, - ) - if err != nil { - return err - } - - err = c.Watch( - &source.Kind{Type: &policyv1beta1.PodDisruptionBudget{}}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &api.CassandraDatacenter{}, - }, - managedByCassandraOperatorPredicate, - ) - if err != nil { - return err - } - - err = c.Watch( - &source.Kind{Type: &corev1.Service{}}, - &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &api.CassandraDatacenter{}, - }, - managedByCassandraOperatorPredicate, - ) - if err != nil { - return err - } - - configSecretMapFn := handler.ToRequestsFunc(func(mapObj handler.MapObject) []reconcile.Request { - log.Info("config secret watch called", "Secret", mapObj.Meta.GetName()) - - requests := make([]reconcile.Request, 0) - secret := mapObj.Object.(*corev1.Secret) - if v, ok := secret.Annotations[api.DatacenterAnnotation]; ok { - log.Info("adding reconciliation request for config secret", "Secret", secret.Name) - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: secret.Namespace, - Name: v, - }, - }) - } - - return requests - }) - - isConfigSecret := func(annotations map[string]string) bool { - _, ok := annotations[api.DatacenterAnnotation] - return ok - } - - configSecretPredicate := predicate.Funcs{ - CreateFunc: func(e event.CreateEvent) bool { - return isConfigSecret(e.Meta.GetAnnotations()) - }, - - UpdateFunc: func(e event.UpdateEvent) bool { - return isConfigSecret(e.MetaOld.GetAnnotations()) || isConfigSecret(e.MetaNew.GetAnnotations()) - }, - - DeleteFunc: func(e event.DeleteEvent) bool { - return isConfigSecret(e.Meta.GetAnnotations()) - }, - - GenericFunc: func(e event.GenericEvent) bool { - return isConfigSecret(e.Meta.GetAnnotations()) - }, - } - - err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestsFromMapFunc{ToRequests: configSecretMapFn}, configSecretPredicate) - if err != nil { - return err - } - - // Setup watches for Nodes to check for taints being added - - nodeMapFn := handler.ToRequestsFunc( - func(a handler.MapObject) []reconcile.Request { - log.Info("Node Watch called") - requests := []reconcile.Request{} - - nodeName := a.Object.(*corev1.Node).Name - dcs := reconciliation.DatacentersForNode(nodeName) - - for _, dc := range dcs { - log.Info("node watch adding reconciliation request", - "cassandraDatacenter", dc.Name, - "namespace", dc.Namespace) - - // Create reconcilerequests for the related cassandraDatacenter - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: dc.Name, - Namespace: dc.Namespace, - }}, - ) - } - return requests - }) - - nodeTaintsChangedPredicate := predicate.Funcs{ - UpdateFunc: func(e event.UpdateEvent) bool { - nodeOld, ok1 := e.ObjectOld.(*corev1.Node) - nodeNew, ok2 := e.ObjectNew.(*corev1.Node) - - if !ok1 || !ok2 { - log.Error(nil, "Failed to cast update.Event objects to type Node", "objectOld", e.ObjectOld, "objectNew", e.ObjectNew) - return true - } - - if nodeOld == nil && nodeNew == nil { - return false - } - - if (nodeOld == nil && nodeNew != nil) || (nodeOld != nil && nodeNew == nil) { - return true - } - - return !utils.ElementsMatch( - nodeOld.Spec.Taints, nodeNew.Spec.Taints) - }, - } - - if utils.IsPSPEnabled() { - err = c.Watch( - &source.Kind{Type: &corev1.Node{}}, - &handler.EnqueueRequestsFromMapFunc{ - ToRequests: nodeMapFn, - }, - nodeTaintsChangedPredicate, - ) - if err != nil { - return err - } - } - - // Setup watches for pvc to check for taints being added - - pvcMapFn := handler.ToRequestsFunc( - func(a handler.MapObject) []reconcile.Request { - log.Info("PersistentVolumeClaim Watch called") - requests := []reconcile.Request{} - - pvc := a.Object.(*corev1.PersistentVolumeClaim) - pvcLabels := pvc.ObjectMeta.Labels - pvcNamespace := pvc.ObjectMeta.Namespace - - managedByValue, ok := pvcLabels[oplabels.ManagedByLabel] - if !ok { - return requests - } - - if (managedByValue == oplabels.ManagedByLabelValue) || (managedByValue == oplabels.ManagedByLabelDefunctValue) { - - dcName := pvcLabels[api.DatacenterLabel] - - log.Info("PersistentVolumeClaim watch adding reconciliation request", - "cassandraDatacenter", dcName, - "namespace", pvcNamespace) - - // Create reconcilerequests for the related cassandraDatacenter - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: dcName, - Namespace: pvcNamespace, - }}, - ) - } - return requests - }) - - if utils.IsPSPEnabled() { - err = c.Watch( - &source.Kind{Type: &corev1.PersistentVolumeClaim{}}, - &handler.EnqueueRequestsFromMapFunc{ - ToRequests: pvcMapFn, - }, - ) - if err != nil { - return err - } - } - - // Setup watches for Secrets. These secrets are often not owned by or created by - // the operator, so we must create a mapping back to the appropriate datacenters. - - rd, ok := r.(*reconciliation.ReconcileCassandraDatacenter) - if !ok { - // This should never happen. - John 06/10/2020 - return fmt.Errorf("%v was not of type ReconcileCassandraDatacenter", r) - } - dynamicSecretWatches := rd.SecretWatches - - toRequests := handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { - watchers := dynamicSecretWatches.FindWatchers(a.Meta, a.Object) - requests := []reconcile.Request{} - for _, watcher := range watchers { - requests = append(requests, reconcile.Request{NamespacedName: watcher}) - } - return requests - }) - - err = c.Watch( - &source.Kind{Type: &corev1.Secret{}}, - &handler.EnqueueRequestsFromMapFunc{ToRequests: toRequests}, - ) - if err != nil { - return err - } - - return nil -} - -// blank assignment to verify that ReconcileCassandraDatacenter implements reconciliation.Reconciler -var _ reconcile.Reconciler = &reconciliation.ReconcileCassandraDatacenter{} diff --git a/operator/pkg/controller/controller.go b/operator/pkg/controller/controller.go deleted file mode 100644 index 9c30e186..00000000 --- a/operator/pkg/controller/controller.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package controller - -import ( - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// AddToManagerFuncs is a list of functions to add all Controllers to the Manager -var AddToManagerFuncs []func(manager.Manager) error - -// AddToManager adds all Controllers to the Manager -func AddToManager(m manager.Manager) error { - for _, f := range AddToManagerFuncs { - if err := f(m); err != nil { - return err - } - } - return nil -} diff --git a/operator/pkg/reconciliation/handler_test.go b/operator/pkg/reconciliation/handler_test.go deleted file mode 100644 index 1d29538a..00000000 --- a/operator/pkg/reconciliation/handler_test.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package reconciliation - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/tools/record" - - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" -) - -func TestCalculateReconciliationActions(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - result, err := rc.calculateReconciliationActions() - assert.NoErrorf(t, err, "Should not have returned an error while calculating reconciliation actions") - assert.NotNil(t, result, "Result should not be nil") - - // Add a service and check the logic - - fakeClient, _ := fakeClientWithService(rc.Datacenter) - rc.Client = *fakeClient - - result, err = rc.calculateReconciliationActions() - assert.NoErrorf(t, err, "Should not have returned an error while calculating reconciliation actions") - assert.NotNil(t, result, "Result should not be nil") -} - -func TestCalculateReconciliationActions_GetServiceError(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - mockClient := &mocks.Client{} - rc.Client = mockClient - - k8sMockClientGet(mockClient, fmt.Errorf("")) - k8sMockClientUpdate(mockClient, nil).Times(1) - // k8sMockClientCreate(mockClient, nil) - - _, err := rc.calculateReconciliationActions() - assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") - - mockClient.AssertExpectations(t) -} - -func TestCalculateReconciliationActions_FailedUpdate(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - mockClient := &mocks.Client{} - rc.Client = mockClient - - k8sMockClientUpdate(mockClient, fmt.Errorf("failed to update CassandraDatacenter with removed finalizers")) - - _, err := rc.calculateReconciliationActions() - assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") - - mockClient.AssertExpectations(t) -} - -func TestProcessDeletion_FailedDelete(t *testing.T) { - t.Skip() - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - mockClient := &mocks.Client{} - rc.Client = mockClient - - k8sMockClientList(mockClient, nil). - Run(func(args mock.Arguments) { - arg := args.Get(1).(*v1.PersistentVolumeClaimList) - arg.Items = []v1.PersistentVolumeClaim{{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pvc-1", - }, - }} - }) - - k8sMockClientDelete(mockClient, fmt.Errorf("")) - k8sMockClientUpdate(mockClient, nil).Times(1) - - now := metav1.Now() - rc.Datacenter.SetDeletionTimestamp(&now) - - result, err := rc.calculateReconciliationActions() - assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") - assert.Equal(t, reconcile.Result{Requeue: true}, result, "Should requeue request") - - mockClient.AssertExpectations(t) -} - -func TestReconcile(t *testing.T) { - t.Skip() - - // Set up verbose logging - logger := zap.Logger(true) - logf.SetLogger(logger) - - var ( - name = "cluster-example-cluster.dc-example-datacenter" - namespace = "default" - size int32 = 2 - ) - storageSize := resource.MustParse("1Gi") - storageName := "server-data" - storageConfig := api.StorageConfig{ - CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ - StorageClassName: &storageName, - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, - }, - }, - } - - // Instance a CassandraDatacenter - dc := &api.CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: api.CassandraDatacenterSpec{ - ManagementApiAuth: api.ManagementApiAuthConfig{ - Insecure: &api.ManagementApiAuthInsecureConfig{}, - }, - Size: size, - ServerVersion: "6.8.0", - StorageConfig: storageConfig, - ClusterName: "cluster-example", - }, - } - - // Objects to keep track of - trackObjects := []runtime.Object{ - dc, - } - - s := scheme.Scheme - s.AddKnownTypes(api.SchemeGroupVersion, dc) - - fakeClient := fake.NewFakeClient(trackObjects...) - - r := &ReconcileCassandraDatacenter{ - client: fakeClient, - scheme: s, - recorder: record.NewFakeRecorder(100), - } - - request := reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: name, - Namespace: namespace, - }, - } - - result, err := r.Reconcile(request) - if err != nil { - t.Fatalf("Reconciliation Failure: (%v)", err) - } - - if result != (reconcile.Result{Requeue: true}) { - t.Error("Reconcile did not return a correct result.") - } -} - -func TestReconcile_NotFound(t *testing.T) { - t.Skip() - - // Set up verbose logging - logger := zap.Logger(true) - logf.SetLogger(logger) - - var ( - name = "datacenter-example" - namespace = "default" - size int32 = 2 - ) - - storageSize := resource.MustParse("1Gi") - storageName := "server-data" - storageConfig := api.StorageConfig{ - CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ - StorageClassName: &storageName, - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, - }, - }, - } - - // Instance a CassandraDatacenter - dc := &api.CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: api.CassandraDatacenterSpec{ - ManagementApiAuth: api.ManagementApiAuthConfig{ - Insecure: &api.ManagementApiAuthInsecureConfig{}, - }, - Size: size, - StorageConfig: storageConfig, - }, - } - - // Objects to keep track of - trackObjects := []runtime.Object{} - - s := scheme.Scheme - s.AddKnownTypes(api.SchemeGroupVersion, dc) - - fakeClient := fake.NewFakeClient(trackObjects...) - - r := &ReconcileCassandraDatacenter{ - client: fakeClient, - scheme: s, - } - - request := reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: name, - Namespace: namespace, - }, - } - - result, err := r.Reconcile(request) - if err != nil { - t.Fatalf("Reconciliation Failure: (%v)", err) - } - - expected := reconcile.Result{} - if result != expected { - t.Error("expected to get a zero-value reconcile.Result") - } -} - -func TestReconcile_Error(t *testing.T) { - // Set up verbose logging - logger := zap.Logger(true) - logf.SetLogger(logger) - - var ( - name = "datacenter-example" - namespace = "default" - size int32 = 2 - ) - - storageSize := resource.MustParse("1Gi") - storageName := "server-data" - storageConfig := api.StorageConfig{ - CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ - StorageClassName: &storageName, - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, - }, - }, - } - - // Instance a CassandraDatacenter - dc := &api.CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: api.CassandraDatacenterSpec{ - ManagementApiAuth: api.ManagementApiAuthConfig{ - Insecure: &api.ManagementApiAuthInsecureConfig{}, - }, - Size: size, - StorageConfig: storageConfig, - }, - } - - // Objects to keep track of - - s := scheme.Scheme - s.AddKnownTypes(api.SchemeGroupVersion, dc) - - mockClient := &mocks.Client{} - k8sMockClientGet(mockClient, fmt.Errorf("")) - - r := &ReconcileCassandraDatacenter{ - client: mockClient, - scheme: s, - } - - request := reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: name, - Namespace: namespace, - }, - } - - _, err := r.Reconcile(request) - if err == nil { - t.Fatalf("Reconciliation should have failed") - } -} - -func TestReconcile_CassandraDatacenterToBeDeleted(t *testing.T) { - t.Skip() - // Set up verbose logging - logger := zap.Logger(true) - logf.SetLogger(logger) - - var ( - name = "datacenter-example" - namespace = "default" - size int32 = 2 - ) - - storageSize := resource.MustParse("1Gi") - storageName := "server-data" - storageConfig := api.StorageConfig{ - CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ - StorageClassName: &storageName, - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, - }, - }, - } - - // Instance a CassandraDatacenter - now := metav1.Now() - dc := &api.CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - DeletionTimestamp: &now, - Finalizers: nil, - }, - Spec: api.CassandraDatacenterSpec{ - ManagementApiAuth: api.ManagementApiAuthConfig{ - Insecure: &api.ManagementApiAuthInsecureConfig{}, - }, - Size: size, - ServerVersion: "6.8.0", - StorageConfig: storageConfig, - }, - } - - // Objects to keep track of - trackObjects := []runtime.Object{ - dc, - } - - s := scheme.Scheme - s.AddKnownTypes(api.SchemeGroupVersion, dc) - - fakeClient := fake.NewFakeClient(trackObjects...) - - r := &ReconcileCassandraDatacenter{ - client: fakeClient, - scheme: s, - } - - request := reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: name, - Namespace: namespace, - }, - } - - result, err := r.Reconcile(request) - if err != nil { - t.Fatalf("Reconciliation Failure: (%v)", err) - } - - if result != (reconcile.Result{}) { - t.Error("Reconcile did not return an empty result.") - } -} diff --git a/operator/pkg/dynamicwatch/watch.go b/pkg/dynamicwatch/watch.go similarity index 91% rename from operator/pkg/dynamicwatch/watch.go rename to pkg/dynamicwatch/watch.go index 498395d5..14f15603 100644 --- a/operator/pkg/dynamicwatch/watch.go +++ b/pkg/dynamicwatch/watch.go @@ -4,21 +4,21 @@ package dynamicwatch import ( - "reflect" "context" "encoding/json" - "strings" "fmt" + "reflect" + "strings" + + "github.com/go-logr/logr" + "github.com/k8ssandra/cass-operator/pkg/utils" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/api/errors" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "github.com/go-logr/logr" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -30,7 +30,7 @@ const ( type DynamicWatches interface { UpdateWatch(watcher types.NamespacedName, watched []types.NamespacedName) error RemoveWatcher(watcher types.NamespacedName) error - FindWatchers(meta metav1.Object, object runtime.Object) []types.NamespacedName + FindWatchers(obj client.Object) []types.NamespacedName } type DynamicWatchesAnnotationImpl struct { @@ -44,10 +44,10 @@ type DynamicWatchesAnnotationImpl struct { func NewDynamicSecretWatches(client client.Client) DynamicWatches { impl := &DynamicWatchesAnnotationImpl{ Client: client, - Ctx: context.Background(), + Ctx: context.Background(), WatchedType: metav1.TypeMeta{ APIVersion: "v1", - Kind: "Secret", + Kind: "Secret", }, WatchedListType: metav1.TypeMeta{ APIVersion: "v1", @@ -63,7 +63,7 @@ func NewDynamicSecretWatches(client client.Client) DynamicWatches { // func namespacedNameString(meta metav1.Object) string { - return namespacedNameToString(types.NamespacedName{Name: meta.GetName(), Namespace: meta.GetNamespace(),}) + return namespacedNameToString(types.NamespacedName{Name: meta.GetName(), Namespace: meta.GetNamespace()}) } func namespacedNameFromString(s string) types.NamespacedName { @@ -72,12 +72,12 @@ func namespacedNameFromString(s string) types.NamespacedName { namespace := strings.TrimSuffix(s, name) namespace = strings.TrimRight(namespace, "/") - return types.NamespacedName{Name: name, Namespace: namespace,} + return types.NamespacedName{Name: name, Namespace: namespace} } -// There does not appear to be an explicit guarantee that +// There does not appear to be an explicit guarantee that // NamespacedName.String() will produced output in a given format. It's quite -// unlikely it will ever change, but to be safe, we implement our own +// unlikely it will ever change, but to be safe, we implement our own // serialization to a string. func namespacedNameToString(n types.NamespacedName) string { return fmt.Sprintf("%s/%s", n.Namespace, n.Name) @@ -117,7 +117,7 @@ func getLabelsOrEmptyMap(meta metav1.Object) map[string]string { // // Functions for loading and saving watchers in an annotation -// +// func (impl *DynamicWatchesAnnotationImpl) getWatcherNames(watched metav1.Object) []string { annotations := getAnnotationsOrEmptyMap(watched) @@ -126,12 +126,12 @@ func (impl *DynamicWatchesAnnotationImpl) getWatcherNames(watched metav1.Object) if !ok { content = "" } - + data := []string{} if content != "" { err := json.Unmarshal([]byte(content), &data) if err != nil { - impl.Logger.Error(err, "Failed to parse watchers data", + impl.Logger.Error(err, "Failed to parse watchers data", "watched", namespacedNameString(watched)) // As opposed to erroring out here, we'll just allow the @@ -207,23 +207,23 @@ func (impl *DynamicWatchesAnnotationImpl) listAllWatched(namespace string) ([]un watchedList.SetKind(impl.WatchedListType.Kind) watchedList.SetAPIVersion(impl.WatchedListType.APIVersion) - selector := map[string]string{WatchedLabel: "true",} + selector := map[string]string{WatchedLabel: "true"} listOptions := &client.ListOptions{ LabelSelector: labels.SelectorFromSet(selector), - Namespace: namespace, + Namespace: namespace, } err := impl.Client.List( impl.Ctx, watchedList, listOptions) - + if err != nil { if errors.IsNotFound(err) { return nil, nil } else { - return nil, err + return nil, err } } @@ -282,7 +282,7 @@ func (impl *DynamicWatchesAnnotationImpl) UpdateWatch(watcher types.NamespacedNa // `watcher` is not recorded as watching this resource in its // annotation. if impl.removeWatcher(watchedItem, watcherAsString) { - itemsToUpdate = append(itemsToUpdate, toUpdate{watchedItem: watchedItem, patch: patch,}) + itemsToUpdate = append(itemsToUpdate, toUpdate{watchedItem: watchedItem, patch: patch}) } } @@ -292,7 +292,7 @@ func (impl *DynamicWatchesAnnotationImpl) UpdateWatch(watcher types.NamespacedNa // Now we need to add `watcher` to the relevant resource for _, name := range watched { watchedItem, err := impl.getWatched(name) - + if err != nil { if errors.IsNotFound(err) { // we are attempting to watch a resource that does not exist... @@ -306,7 +306,7 @@ func (impl *DynamicWatchesAnnotationImpl) UpdateWatch(watcher types.NamespacedNa patch := client.MergeFrom(watchedItem.DeepCopy()) if impl.addWatcher(watchedItem, watcherAsString) { - itemsToUpdate = append(itemsToUpdate, toUpdate{watchedItem: watchedItem, patch: patch,}) + itemsToUpdate = append(itemsToUpdate, toUpdate{watchedItem: watchedItem, patch: patch}) } } @@ -331,7 +331,7 @@ func (impl *DynamicWatchesAnnotationImpl) RemoveWatcher(watcher types.Namespaced return impl.UpdateWatch(watcher, []types.NamespacedName{}) } -func (impl *DynamicWatchesAnnotationImpl) FindWatchers(watchedMeta metav1.Object, watchedObject runtime.Object) []types.NamespacedName { - watchersAsStrings := impl.getWatcherNames(watchedMeta) +func (impl *DynamicWatchesAnnotationImpl) FindWatchers(watchedObject client.Object) []types.NamespacedName { + watchersAsStrings := impl.getWatcherNames(watchedObject) return namespacedNamesFromStringArray(watchersAsStrings) } diff --git a/operator/pkg/events/events.go b/pkg/events/events.go similarity index 100% rename from operator/pkg/events/events.go rename to pkg/events/events.go diff --git a/operator/pkg/events/events_test.go b/pkg/events/events_test.go similarity index 75% rename from operator/pkg/events/events_test.go rename to pkg/events/events_test.go index b58e1211..e73bee1e 100644 --- a/operator/pkg/events/events_test.go +++ b/pkg/events/events_test.go @@ -3,11 +3,12 @@ package events import ( "testing" - "github.com/stretchr/testify/mock" + "github.com/go-logr/logr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + api "github.com/k8ssandra/cass-operator/api/v1beta1" "k8s.io/client-go/tools/record" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" ) type MockInfoLogger struct { @@ -21,14 +22,29 @@ func (l *MockInfoLogger) Info(msg string, keysAndValues ...interface{}) { func (l *MockInfoLogger) Enabled() bool { args := l.Called() - return args.Bool(0) + return args.Bool(0) +} + +func (l *MockInfoLogger) Error(err error, msg string, keysAndValues ...interface{}) { +} + +func (l *MockInfoLogger) V(level int) logr.InfoLogger { + return l +} + +func (l *MockInfoLogger) WithValues(keysAndValues ...interface{}) logr.InfoLogger { + return l +} + +func (l *MockInfoLogger) WithName(name string) logr.InfoLogger { + return l } func TestLoggingEventRecorder(t *testing.T) { logger := &MockInfoLogger{} recorder := &LoggingEventRecorder{ EventRecorder: &record.FakeRecorder{}, - ReqLogger: logger} + ReqLogger: logger} dc := &api.CassandraDatacenter{} logger.On("Info", @@ -53,17 +69,17 @@ func TestLoggingEventRecorder(t *testing.T) { for j := 0; j < 3; j++ { keysAndValues := map[string]string{} args := logger.Calls[j].Arguments - for i := 1; i < len(args) - 1; i += 2 { + for i := 1; i < len(args)-1; i += 2 { key, ok := args[i].(string) assert.True(t, ok) - value, ok := args[i + 1].(string) + value, ok := args[i+1].(string) assert.True(t, ok) keysAndValues[key] = value } assert.Equal( t, - map[string]string{"eventType": "SomeType", "reason": "SomeReason",}, + map[string]string{"eventType": "SomeType", "reason": "SomeReason"}, keysAndValues) } } diff --git a/operator/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go similarity index 93% rename from operator/pkg/generated/clientset/versioned/clientset.go rename to pkg/generated/clientset/versioned/clientset.go index ec6ab4fd..96aea87a 100644 --- a/operator/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -21,7 +21,7 @@ package versioned import ( "fmt" - cassandrav1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" + cassandrav1beta1 "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" @@ -59,7 +59,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { configShallowCopy := *c if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { if configShallowCopy.Burst <= 0 { - return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") } configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) } diff --git a/operator/pkg/generated/clientset/versioned/doc.go b/pkg/generated/clientset/versioned/doc.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/doc.go rename to pkg/generated/clientset/versioned/doc.go diff --git a/operator/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go similarity index 87% rename from operator/pkg/generated/clientset/versioned/fake/clientset_generated.go rename to pkg/generated/clientset/versioned/fake/clientset_generated.go index 44697e97..add7eaf5 100644 --- a/operator/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -19,9 +19,9 @@ limitations under the License. package fake import ( - clientset "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned" - cassandrav1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" - fakecassandrav1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake" + clientset "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned" + cassandrav1beta1 "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" + fakecassandrav1beta1 "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" diff --git a/operator/pkg/generated/clientset/versioned/fake/doc.go b/pkg/generated/clientset/versioned/fake/doc.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/fake/doc.go rename to pkg/generated/clientset/versioned/fake/doc.go diff --git a/operator/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go similarity index 93% rename from operator/pkg/generated/clientset/versioned/fake/register.go rename to pkg/generated/clientset/versioned/fake/register.go index b4540071..45a219c4 100644 --- a/operator/pkg/generated/clientset/versioned/fake/register.go +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -19,7 +19,7 @@ limitations under the License. package fake import ( - cassandrav1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -31,7 +31,7 @@ var scheme = runtime.NewScheme() var codecs = serializer.NewCodecFactory(scheme) var parameterCodec = runtime.NewParameterCodec(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ - cassandrav1beta1.AddToScheme, + api.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/operator/pkg/generated/clientset/versioned/scheme/doc.go b/pkg/generated/clientset/versioned/scheme/doc.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/scheme/doc.go rename to pkg/generated/clientset/versioned/scheme/doc.go diff --git a/operator/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go similarity index 93% rename from operator/pkg/generated/clientset/versioned/scheme/register.go rename to pkg/generated/clientset/versioned/scheme/register.go index e46d2afc..c36cad1f 100644 --- a/operator/pkg/generated/clientset/versioned/scheme/register.go +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -19,7 +19,7 @@ limitations under the License. package scheme import ( - cassandrav1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -31,7 +31,7 @@ var Scheme = runtime.NewScheme() var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ - cassandrav1beta1.AddToScheme, + api.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go similarity index 92% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go index 81a2c39b..2425671c 100644 --- a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go +++ b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandra_client.go @@ -19,8 +19,8 @@ limitations under the License. package v1beta1 import ( - v1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/scheme" + v1beta1 "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/scheme" rest "k8s.io/client-go/rest" ) @@ -67,7 +67,7 @@ func New(c rest.Interface) *CassandraV1beta1Client { } func setConfigDefaults(config *rest.Config) error { - gv := v1beta1.SchemeGroupVersion + gv := v1beta1.GroupVersion config.GroupVersion = &gv config.APIPath = "/apis" config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go similarity index 60% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go index 07ae165c..58f49e4a 100644 --- a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go +++ b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/cassandradatacenter.go @@ -19,10 +19,11 @@ limitations under the License. package v1beta1 import ( + "context" "time" - v1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - scheme "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/scheme" + v1beta1 "github.com/k8ssandra/cass-operator/api/v1beta1" + scheme "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" @@ -37,15 +38,15 @@ type CassandraDatacentersGetter interface { // CassandraDatacenterInterface has methods to work with CassandraDatacenter resources. type CassandraDatacenterInterface interface { - Create(*v1beta1.CassandraDatacenter) (*v1beta1.CassandraDatacenter, error) - Update(*v1beta1.CassandraDatacenter) (*v1beta1.CassandraDatacenter, error) - UpdateStatus(*v1beta1.CassandraDatacenter) (*v1beta1.CassandraDatacenter, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1beta1.CassandraDatacenter, error) - List(opts v1.ListOptions) (*v1beta1.CassandraDatacenterList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) + Create(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.CreateOptions) (*v1beta1.CassandraDatacenter, error) + Update(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (*v1beta1.CassandraDatacenter, error) + UpdateStatus(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (*v1beta1.CassandraDatacenter, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.CassandraDatacenter, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.CassandraDatacenterList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) CassandraDatacenterExpansion } @@ -64,20 +65,20 @@ func newCassandraDatacenters(c *CassandraV1beta1Client, namespace string) *cassa } // Get takes name of the cassandraDatacenter, and returns the corresponding cassandraDatacenter object, and an error if there is any. -func (c *cassandraDatacenters) Get(name string, options v1.GetOptions) (result *v1beta1.CassandraDatacenter, err error) { +func (c *cassandraDatacenters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CassandraDatacenter, err error) { result = &v1beta1.CassandraDatacenter{} err = c.client.Get(). Namespace(c.ns). Resource("cassandradatacenters"). Name(name). VersionedParams(&options, scheme.ParameterCodec). - Do(). + Do(ctx). Into(result) return } // List takes label and field selectors, and returns the list of CassandraDatacenters that match those selectors. -func (c *cassandraDatacenters) List(opts v1.ListOptions) (result *v1beta1.CassandraDatacenterList, err error) { +func (c *cassandraDatacenters) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CassandraDatacenterList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second @@ -88,13 +89,13 @@ func (c *cassandraDatacenters) List(opts v1.ListOptions) (result *v1beta1.Cassan Resource("cassandradatacenters"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). - Do(). + Do(ctx). Into(result) return } // Watch returns a watch.Interface that watches the requested cassandraDatacenters. -func (c *cassandraDatacenters) Watch(opts v1.ListOptions) (watch.Interface, error) { +func (c *cassandraDatacenters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second @@ -105,87 +106,90 @@ func (c *cassandraDatacenters) Watch(opts v1.ListOptions) (watch.Interface, erro Resource("cassandradatacenters"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). - Watch() + Watch(ctx) } // Create takes the representation of a cassandraDatacenter and creates it. Returns the server's representation of the cassandraDatacenter, and an error, if there is any. -func (c *cassandraDatacenters) Create(cassandraDatacenter *v1beta1.CassandraDatacenter) (result *v1beta1.CassandraDatacenter, err error) { +func (c *cassandraDatacenters) Create(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.CreateOptions) (result *v1beta1.CassandraDatacenter, err error) { result = &v1beta1.CassandraDatacenter{} err = c.client.Post(). Namespace(c.ns). Resource("cassandradatacenters"). + VersionedParams(&opts, scheme.ParameterCodec). Body(cassandraDatacenter). - Do(). + Do(ctx). Into(result) return } // Update takes the representation of a cassandraDatacenter and updates it. Returns the server's representation of the cassandraDatacenter, and an error, if there is any. -func (c *cassandraDatacenters) Update(cassandraDatacenter *v1beta1.CassandraDatacenter) (result *v1beta1.CassandraDatacenter, err error) { +func (c *cassandraDatacenters) Update(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (result *v1beta1.CassandraDatacenter, err error) { result = &v1beta1.CassandraDatacenter{} err = c.client.Put(). Namespace(c.ns). Resource("cassandradatacenters"). Name(cassandraDatacenter.Name). + VersionedParams(&opts, scheme.ParameterCodec). Body(cassandraDatacenter). - Do(). + Do(ctx). Into(result) return } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - -func (c *cassandraDatacenters) UpdateStatus(cassandraDatacenter *v1beta1.CassandraDatacenter) (result *v1beta1.CassandraDatacenter, err error) { +func (c *cassandraDatacenters) UpdateStatus(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (result *v1beta1.CassandraDatacenter, err error) { result = &v1beta1.CassandraDatacenter{} err = c.client.Put(). Namespace(c.ns). Resource("cassandradatacenters"). Name(cassandraDatacenter.Name). SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). Body(cassandraDatacenter). - Do(). + Do(ctx). Into(result) return } // Delete takes name of the cassandraDatacenter and deletes it. Returns an error if one occurs. -func (c *cassandraDatacenters) Delete(name string, options *v1.DeleteOptions) error { +func (c *cassandraDatacenters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). Namespace(c.ns). Resource("cassandradatacenters"). Name(name). - Body(options). - Do(). + Body(&opts). + Do(ctx). Error() } // DeleteCollection deletes a collection of objects. -func (c *cassandraDatacenters) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { +func (c *cassandraDatacenters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { var timeout time.Duration - if listOptions.TimeoutSeconds != nil { - timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second } return c.client.Delete(). Namespace(c.ns). Resource("cassandradatacenters"). - VersionedParams(&listOptions, scheme.ParameterCodec). + VersionedParams(&listOpts, scheme.ParameterCodec). Timeout(timeout). - Body(options). - Do(). + Body(&opts). + Do(ctx). Error() } // Patch applies the patch and returns the patched cassandraDatacenter. -func (c *cassandraDatacenters) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) { +func (c *cassandraDatacenters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) { result = &v1beta1.CassandraDatacenter{} err = c.client.Patch(pt). Namespace(c.ns). Resource("cassandradatacenters"). - SubResource(subresources...). Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). Body(data). - Do(). + Do(ctx). Into(result) return } diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/doc.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/doc.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/doc.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/doc.go diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/doc.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/doc.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/doc.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/doc.go diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go similarity index 90% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go index 86e0a2e4..c2e11351 100644 --- a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go +++ b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandra_client.go @@ -19,7 +19,7 @@ limitations under the License. package fake import ( - v1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" + v1beta1 "github.com/k8ssandra/cass-operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go similarity index 75% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go index 9bff3eae..4d49c967 100644 --- a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go +++ b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/fake/fake_cassandradatacenter.go @@ -19,7 +19,9 @@ limitations under the License. package fake import ( - v1beta1 "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + "context" + + v1beta1 "github.com/k8ssandra/cass-operator/api/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -39,7 +41,7 @@ var cassandradatacentersResource = schema.GroupVersionResource{Group: "cassandra var cassandradatacentersKind = schema.GroupVersionKind{Group: "cassandra.datastax.com", Version: "v1beta1", Kind: "CassandraDatacenter"} // Get takes name of the cassandraDatacenter, and returns the corresponding cassandraDatacenter object, and an error if there is any. -func (c *FakeCassandraDatacenters) Get(name string, options v1.GetOptions) (result *v1beta1.CassandraDatacenter, err error) { +func (c *FakeCassandraDatacenters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CassandraDatacenter, err error) { obj, err := c.Fake. Invokes(testing.NewGetAction(cassandradatacentersResource, c.ns, name), &v1beta1.CassandraDatacenter{}) @@ -50,7 +52,7 @@ func (c *FakeCassandraDatacenters) Get(name string, options v1.GetOptions) (resu } // List takes label and field selectors, and returns the list of CassandraDatacenters that match those selectors. -func (c *FakeCassandraDatacenters) List(opts v1.ListOptions) (result *v1beta1.CassandraDatacenterList, err error) { +func (c *FakeCassandraDatacenters) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CassandraDatacenterList, err error) { obj, err := c.Fake. Invokes(testing.NewListAction(cassandradatacentersResource, cassandradatacentersKind, c.ns, opts), &v1beta1.CassandraDatacenterList{}) @@ -72,14 +74,14 @@ func (c *FakeCassandraDatacenters) List(opts v1.ListOptions) (result *v1beta1.Ca } // Watch returns a watch.Interface that watches the requested cassandraDatacenters. -func (c *FakeCassandraDatacenters) Watch(opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCassandraDatacenters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(cassandradatacentersResource, c.ns, opts)) } // Create takes the representation of a cassandraDatacenter and creates it. Returns the server's representation of the cassandraDatacenter, and an error, if there is any. -func (c *FakeCassandraDatacenters) Create(cassandraDatacenter *v1beta1.CassandraDatacenter) (result *v1beta1.CassandraDatacenter, err error) { +func (c *FakeCassandraDatacenters) Create(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.CreateOptions) (result *v1beta1.CassandraDatacenter, err error) { obj, err := c.Fake. Invokes(testing.NewCreateAction(cassandradatacentersResource, c.ns, cassandraDatacenter), &v1beta1.CassandraDatacenter{}) @@ -90,7 +92,7 @@ func (c *FakeCassandraDatacenters) Create(cassandraDatacenter *v1beta1.Cassandra } // Update takes the representation of a cassandraDatacenter and updates it. Returns the server's representation of the cassandraDatacenter, and an error, if there is any. -func (c *FakeCassandraDatacenters) Update(cassandraDatacenter *v1beta1.CassandraDatacenter) (result *v1beta1.CassandraDatacenter, err error) { +func (c *FakeCassandraDatacenters) Update(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (result *v1beta1.CassandraDatacenter, err error) { obj, err := c.Fake. Invokes(testing.NewUpdateAction(cassandradatacentersResource, c.ns, cassandraDatacenter), &v1beta1.CassandraDatacenter{}) @@ -102,7 +104,7 @@ func (c *FakeCassandraDatacenters) Update(cassandraDatacenter *v1beta1.Cassandra // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeCassandraDatacenters) UpdateStatus(cassandraDatacenter *v1beta1.CassandraDatacenter) (*v1beta1.CassandraDatacenter, error) { +func (c *FakeCassandraDatacenters) UpdateStatus(ctx context.Context, cassandraDatacenter *v1beta1.CassandraDatacenter, opts v1.UpdateOptions) (*v1beta1.CassandraDatacenter, error) { obj, err := c.Fake. Invokes(testing.NewUpdateSubresourceAction(cassandradatacentersResource, "status", c.ns, cassandraDatacenter), &v1beta1.CassandraDatacenter{}) @@ -113,7 +115,7 @@ func (c *FakeCassandraDatacenters) UpdateStatus(cassandraDatacenter *v1beta1.Cas } // Delete takes name of the cassandraDatacenter and deletes it. Returns an error if one occurs. -func (c *FakeCassandraDatacenters) Delete(name string, options *v1.DeleteOptions) error { +func (c *FakeCassandraDatacenters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. Invokes(testing.NewDeleteAction(cassandradatacentersResource, c.ns, name), &v1beta1.CassandraDatacenter{}) @@ -121,15 +123,15 @@ func (c *FakeCassandraDatacenters) Delete(name string, options *v1.DeleteOptions } // DeleteCollection deletes a collection of objects. -func (c *FakeCassandraDatacenters) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(cassandradatacentersResource, c.ns, listOptions) +func (c *FakeCassandraDatacenters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(cassandradatacentersResource, c.ns, listOpts) _, err := c.Fake.Invokes(action, &v1beta1.CassandraDatacenterList{}) return err } // Patch applies the patch and returns the patched cassandraDatacenter. -func (c *FakeCassandraDatacenters) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) { +func (c *FakeCassandraDatacenters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CassandraDatacenter, err error) { obj, err := c.Fake. Invokes(testing.NewPatchSubresourceAction(cassandradatacentersResource, c.ns, name, pt, data, subresources...), &v1beta1.CassandraDatacenter{}) diff --git a/operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/generated_expansion.go similarity index 100% rename from operator/pkg/generated/clientset/versioned/typed/cassandra/v1beta1/generated_expansion.go rename to pkg/generated/clientset/versioned/typed/cassandra/v1beta1/generated_expansion.go diff --git a/operator/pkg/httphelper/client.go b/pkg/httphelper/client.go similarity index 100% rename from operator/pkg/httphelper/client.go rename to pkg/httphelper/client.go diff --git a/operator/pkg/httphelper/client_test.go b/pkg/httphelper/client_test.go similarity index 97% rename from operator/pkg/httphelper/client_test.go rename to pkg/httphelper/client_test.go index a83c6747..e3c1ee68 100644 --- a/operator/pkg/httphelper/client_test.go +++ b/pkg/httphelper/client_test.go @@ -11,7 +11,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" ) func Test_BuildPodHostFromPod(t *testing.T) { diff --git a/operator/pkg/httphelper/httpclient.go b/pkg/httphelper/httpclient.go similarity index 98% rename from operator/pkg/httphelper/httpclient.go rename to pkg/httphelper/httpclient.go index 14b2c944..d72801cb 100644 --- a/operator/pkg/httphelper/httpclient.go +++ b/pkg/httphelper/httpclient.go @@ -7,4 +7,4 @@ import "net/http" type HttpClient interface { Do(req *http.Request) (*http.Response, error) -} \ No newline at end of file +} diff --git a/operator/pkg/httphelper/security.go b/pkg/httphelper/security.go similarity index 99% rename from operator/pkg/httphelper/security.go rename to pkg/httphelper/security.go index 9c865e62..8c252c78 100644 --- a/operator/pkg/httphelper/security.go +++ b/pkg/httphelper/security.go @@ -13,7 +13,7 @@ import ( "net/http" "strings" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/operator/pkg/httphelper/security_test.go b/pkg/httphelper/security_test.go similarity index 100% rename from operator/pkg/httphelper/security_test.go rename to pkg/httphelper/security_test.go diff --git a/operator/pkg/httphelper/testdata/ca.crt b/pkg/httphelper/testdata/ca.crt similarity index 100% rename from operator/pkg/httphelper/testdata/ca.crt rename to pkg/httphelper/testdata/ca.crt diff --git a/operator/pkg/httphelper/testdata/ca.key b/pkg/httphelper/testdata/ca.key similarity index 100% rename from operator/pkg/httphelper/testdata/ca.key rename to pkg/httphelper/testdata/ca.key diff --git a/operator/pkg/httphelper/testdata/client.crt b/pkg/httphelper/testdata/client.crt similarity index 100% rename from operator/pkg/httphelper/testdata/client.crt rename to pkg/httphelper/testdata/client.crt diff --git a/operator/pkg/httphelper/testdata/client.key b/pkg/httphelper/testdata/client.key similarity index 100% rename from operator/pkg/httphelper/testdata/client.key rename to pkg/httphelper/testdata/client.key diff --git a/operator/pkg/httphelper/testdata/evil_ca.crt b/pkg/httphelper/testdata/evil_ca.crt similarity index 100% rename from operator/pkg/httphelper/testdata/evil_ca.crt rename to pkg/httphelper/testdata/evil_ca.crt diff --git a/operator/pkg/httphelper/testdata/evil_ca.key b/pkg/httphelper/testdata/evil_ca.key similarity index 100% rename from operator/pkg/httphelper/testdata/evil_ca.key rename to pkg/httphelper/testdata/evil_ca.key diff --git a/operator/pkg/httphelper/testdata/gencerts.sh b/pkg/httphelper/testdata/gencerts.sh similarity index 100% rename from operator/pkg/httphelper/testdata/gencerts.sh rename to pkg/httphelper/testdata/gencerts.sh diff --git a/operator/pkg/httphelper/testdata/server.crt b/pkg/httphelper/testdata/server.crt similarity index 100% rename from operator/pkg/httphelper/testdata/server.crt rename to pkg/httphelper/testdata/server.crt diff --git a/operator/pkg/httphelper/testdata/server.encrypted.key b/pkg/httphelper/testdata/server.encrypted.key similarity index 100% rename from operator/pkg/httphelper/testdata/server.encrypted.key rename to pkg/httphelper/testdata/server.encrypted.key diff --git a/operator/pkg/httphelper/testdata/server.key b/pkg/httphelper/testdata/server.key similarity index 100% rename from operator/pkg/httphelper/testdata/server.key rename to pkg/httphelper/testdata/server.key diff --git a/operator/pkg/httphelper/testdata/server.rsa.key b/pkg/httphelper/testdata/server.rsa.key similarity index 100% rename from operator/pkg/httphelper/testdata/server.rsa.key rename to pkg/httphelper/testdata/server.rsa.key diff --git a/operator/pkg/images/images.go b/pkg/images/images.go similarity index 99% rename from operator/pkg/images/images.go rename to pkg/images/images.go index 66371c41..56889a7d 100644 --- a/operator/pkg/images/images.go +++ b/pkg/images/images.go @@ -99,7 +99,7 @@ var imageLookupMap map[Image]string = map[Image]string{ UBIDSE_6_8_3: "datastax/dse-server:6.8.3-ubi7", UBIDSE_6_8_4: "datastax/dse-server:6.8.4-ubi7", - ConfigBuilder: "datastax/cass-config-builder:1.0.3", + ConfigBuilder: "datastax/cass-config-builder:1.0.4", UBIConfigBuilder: "datastax/cass-config-builder:1.0.3-ubi7", BusyBox: "busybox:1.32.0-uclibc", diff --git a/operator/pkg/images/images_test.go b/pkg/images/images_test.go similarity index 100% rename from operator/pkg/images/images_test.go rename to pkg/images/images_test.go diff --git a/operator/internal/result/result_helper.go b/pkg/internal/result/result_helper.go similarity index 66% rename from operator/internal/result/result_helper.go rename to pkg/internal/result/result_helper.go index 180599bf..c8e98778 100644 --- a/operator/internal/result/result_helper.go +++ b/pkg/internal/result/result_helper.go @@ -6,12 +6,12 @@ package result import ( "time" - "sigs.k8s.io/controller-runtime/pkg/reconcile" + ctrl "sigs.k8s.io/controller-runtime" ) type ReconcileResult interface { Completed() bool - Output() (reconcile.Result, error) + Output() (ctrl.Result, error) } type continueReconcile struct{} @@ -19,7 +19,7 @@ type continueReconcile struct{} func (c continueReconcile) Completed() bool { return false } -func (c continueReconcile) Output() (reconcile.Result, error) { +func (c continueReconcile) Output() (ctrl.Result, error) { panic("there was no Result to return") } @@ -28,8 +28,8 @@ type done struct{} func (d done) Completed() bool { return true } -func (d done) Output() (reconcile.Result, error) { - return reconcile.Result{}, nil +func (d done) Output() (ctrl.Result, error) { + return ctrl.Result{}, nil } type callBackSoon struct { @@ -39,9 +39,9 @@ type callBackSoon struct { func (c callBackSoon) Completed() bool { return true } -func (c callBackSoon) Output() (reconcile.Result, error) { +func (c callBackSoon) Output() (ctrl.Result, error) { t := time.Duration(c.secs) * time.Second - return reconcile.Result{Requeue: true, RequeueAfter: t}, nil + return ctrl.Result{Requeue: true, RequeueAfter: t}, nil } type errorOut struct { @@ -51,8 +51,8 @@ type errorOut struct { func (e errorOut) Completed() bool { return true } -func (e errorOut) Output() (reconcile.Result, error) { - return reconcile.Result{}, e.err +func (e errorOut) Output() (ctrl.Result, error) { + return ctrl.Result{}, e.err } func Continue() ReconcileResult { diff --git a/operator/internal/result/result_helper_test.go b/pkg/internal/result/result_helper_test.go similarity index 100% rename from operator/internal/result/result_helper_test.go rename to pkg/internal/result/result_helper_test.go diff --git a/operator/pkg/mocks/Client.go b/pkg/mocks/Client.go similarity index 66% rename from operator/pkg/mocks/Client.go rename to pkg/mocks/Client.go index 7ec5752c..0d6cc2ef 100644 --- a/operator/pkg/mocks/Client.go +++ b/pkg/mocks/Client.go @@ -7,10 +7,11 @@ package mocks import ( context "context" - client "sigs.k8s.io/controller-runtime/pkg/client" mock "github.com/stretchr/testify/mock" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" types "k8s.io/apimachinery/pkg/types" + client "sigs.k8s.io/controller-runtime/pkg/client" ) // Client is an autogenerated mock type for the Client type @@ -19,7 +20,7 @@ type Client struct { } // Create provides a mock function with given fields: ctx, obj, opts -func (_m *Client) Create(ctx context.Context, obj runtime.Object, opts ...client.CreateOption) error { +func (_m *Client) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -30,7 +31,7 @@ func (_m *Client) Create(ctx context.Context, obj runtime.Object, opts ...client ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, ...client.CreateOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...client.CreateOption) error); ok { r0 = rf(ctx, obj, opts...) } else { r0 = ret.Error(0) @@ -40,7 +41,7 @@ func (_m *Client) Create(ctx context.Context, obj runtime.Object, opts ...client } // Delete provides a mock function with given fields: ctx, obj, opts -func (_m *Client) Delete(ctx context.Context, obj runtime.Object, opts ...client.DeleteOption) error { +func (_m *Client) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -51,7 +52,7 @@ func (_m *Client) Delete(ctx context.Context, obj runtime.Object, opts ...client ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, ...client.DeleteOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...client.DeleteOption) error); ok { r0 = rf(ctx, obj, opts...) } else { r0 = ret.Error(0) @@ -61,7 +62,7 @@ func (_m *Client) Delete(ctx context.Context, obj runtime.Object, opts ...client } // DeleteAllOf provides a mock function with given fields: ctx, obj, opts -func (_m *Client) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...client.DeleteAllOfOption) error { +func (_m *Client) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -72,7 +73,7 @@ func (_m *Client) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...c ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, ...client.DeleteAllOfOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...client.DeleteAllOfOption) error); ok { r0 = rf(ctx, obj, opts...) } else { r0 = ret.Error(0) @@ -82,11 +83,11 @@ func (_m *Client) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...c } // Get provides a mock function with given fields: ctx, key, obj -func (_m *Client) Get(ctx context.Context, key types.NamespacedName, obj runtime.Object) error { +func (_m *Client) Get(ctx context.Context, key types.NamespacedName, obj client.Object) error { ret := _m.Called(ctx, key, obj) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, types.NamespacedName, runtime.Object) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, types.NamespacedName, client.Object) error); ok { r0 = rf(ctx, key, obj) } else { r0 = ret.Error(0) @@ -96,7 +97,7 @@ func (_m *Client) Get(ctx context.Context, key types.NamespacedName, obj runtime } // List provides a mock function with given fields: ctx, list, opts -func (_m *Client) List(ctx context.Context, list runtime.Object, opts ...client.ListOption) error { +func (_m *Client) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -107,7 +108,7 @@ func (_m *Client) List(ctx context.Context, list runtime.Object, opts ...client. ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, ...client.ListOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.ObjectList, ...client.ListOption) error); ok { r0 = rf(ctx, list, opts...) } else { r0 = ret.Error(0) @@ -117,7 +118,7 @@ func (_m *Client) List(ctx context.Context, list runtime.Object, opts ...client. } // Patch provides a mock function with given fields: ctx, obj, patch, opts -func (_m *Client) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error { +func (_m *Client) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -128,7 +129,7 @@ func (_m *Client) Patch(ctx context.Context, obj runtime.Object, patch client.Pa ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, client.Patch, ...client.PatchOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.Object, client.Patch, ...client.PatchOption) error); ok { r0 = rf(ctx, obj, patch, opts...) } else { r0 = ret.Error(0) @@ -154,7 +155,7 @@ func (_m *Client) Status() client.StatusWriter { } // Update provides a mock function with given fields: ctx, obj, opts -func (_m *Client) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error { +func (_m *Client) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -165,7 +166,7 @@ func (_m *Client) Update(ctx context.Context, obj runtime.Object, opts ...client ret := _m.Called(_ca...) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, runtime.Object, ...client.UpdateOption) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, client.Object, ...client.UpdateOption) error); ok { r0 = rf(ctx, obj, opts...) } else { r0 = ret.Error(0) @@ -173,3 +174,13 @@ func (_m *Client) Update(ctx context.Context, obj runtime.Object, opts ...client return r0 } + +// RESTMapper returns the rest this client is using. +func (_m *Client) RESTMapper() meta.RESTMapper { + return nil +} + +// Scheme returns the scheme this client is using. +func (_m *Client) Scheme() *runtime.Scheme { + return nil +} diff --git a/operator/pkg/mocks/HttpClient.go b/pkg/mocks/HttpClient.go similarity index 100% rename from operator/pkg/mocks/HttpClient.go rename to pkg/mocks/HttpClient.go diff --git a/operator/pkg/oplabels/labels.go b/pkg/oplabels/labels.go similarity index 73% rename from operator/pkg/oplabels/labels.go rename to pkg/oplabels/labels.go index a8f3ae8e..976f833b 100644 --- a/operator/pkg/oplabels/labels.go +++ b/pkg/oplabels/labels.go @@ -4,9 +4,9 @@ package oplabels const ( - ManagedByLabel = "app.kubernetes.io/managed-by" - ManagedByLabelValue = "cass-operator" - ManagedByLabelDefunctValue = "cassandra-operator" + ManagedByLabel = "app.kubernetes.io/managed-by" + ManagedByLabelValue = "cass-operator" + ManagedByLabelDefunctValue = "cassandra-operator" ) func AddManagedByLabel(m map[string]string) { diff --git a/operator/pkg/psp/emm.go b/pkg/psp/emm.go similarity index 99% rename from operator/pkg/psp/emm.go rename to pkg/psp/emm.go index 6f9a2b8c..adc3d6d0 100644 --- a/operator/pkg/psp/emm.go +++ b/pkg/psp/emm.go @@ -28,10 +28,10 @@ import ( "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/k8ssandra/cass-operator/pkg/utils" - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/internal/result" ) const ( diff --git a/operator/pkg/psp/emm_test.go b/pkg/psp/emm_test.go similarity index 99% rename from operator/pkg/psp/emm_test.go rename to pkg/psp/emm_test.go index 4cdf84e1..4c1f8d18 100644 --- a/operator/pkg/psp/emm_test.go +++ b/pkg/psp/emm_test.go @@ -14,8 +14,8 @@ import ( "github.com/go-logr/logr" logrtesting "github.com/go-logr/logr/testing" - "github.com/k8ssandra/cass-operator/operator/internal/result" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/k8ssandra/cass-operator/pkg/internal/result" + "github.com/k8ssandra/cass-operator/pkg/utils" ) func IsRequeue(t *testing.T, r result.ReconcileResult, msg string) { diff --git a/operator/pkg/psp/labels_annotations.go b/pkg/psp/labels_annotations.go similarity index 86% rename from operator/pkg/psp/labels_annotations.go rename to pkg/psp/labels_annotations.go index 885914b2..692d0f88 100644 --- a/operator/pkg/psp/labels_annotations.go +++ b/pkg/psp/labels_annotations.go @@ -3,17 +3,17 @@ package psp import ( "os" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" ) const ( - ExtensionIDLabel string = "appplatform.vmware.com/extension-id" - InstanceIDLabel string = "appplatform.vmware.com/instance-id" + ExtensionIDLabel string = "appplatform.vmware.com/extension-id" + InstanceIDLabel string = "appplatform.vmware.com/instance-id" EMMIntegratedAnnotation string = "appplatform.vmware.com/vsphere-emm-integrated" - ExtensionIDEnv string = "PSP_EXTENSION_ID" + ExtensionIDEnv string = "PSP_EXTENSION_ID" ) // The return value here _should_ be the same as `vSphereExtensionKey` in the @@ -46,7 +46,7 @@ func AddStatefulSetChanges(dc *api.CassandraDatacenter, statefulSet *appsv1.Stat cvt := &statefulSet.Spec.VolumeClaimTemplates[i] addLabels(dc.Name, cvt) } - + podTemplate := &statefulSet.Spec.Template addLabels(dc.Name, podTemplate) addAnnotations(podTemplate) diff --git a/operator/pkg/psp/networkpolicies.go b/pkg/psp/networkpolicies.go similarity index 93% rename from operator/pkg/psp/networkpolicies.go rename to pkg/psp/networkpolicies.go index adce4c5a..5096c24c 100644 --- a/operator/pkg/psp/networkpolicies.go +++ b/pkg/psp/networkpolicies.go @@ -1,20 +1,20 @@ package psp import ( - "fmt" "context" + "fmt" "github.com/go-logr/logr" - "sigs.k8s.io/controller-runtime/pkg/client" - "k8s.io/apimachinery/pkg/types" + networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - networkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/internal/result" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/internal/result" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/utils" ) type CheckNetworkPoliciesSPI interface { @@ -45,13 +45,13 @@ func newNetworkPolicyForCassandraDatacenter(dc *api.CassandraDatacenter) *networ } // VMWare with Kubernetes does not permit network traffic between namespaces -// by default. This means a NetworkPolicy must be created to allow the +// by default. This means a NetworkPolicy must be created to allow the // operator to make requests to the Management API. // // NOTE: The way VMWare implements NetworkPolicy appears to be non-standard. // For example, typially setting the namespace selector to an empty value // _should_ select all namespaces, but it does not in VMWare with Kubernetes. -// Consequently, it is important that changes here be verified in that +// Consequently, it is important that changes here be verified in that // environment. func CheckNetworkPolicies(spi CheckNetworkPoliciesSPI) result.ReconcileResult { logger := spi.GetLogger() @@ -111,6 +111,6 @@ func CheckNetworkPolicies(spi CheckNetworkPoliciesSPI) result.ReconcileResult { } } } - + return result.Continue() } diff --git a/operator/pkg/psp/psp_status.go b/pkg/psp/psp_status.go similarity index 89% rename from operator/pkg/psp/psp_status.go rename to pkg/psp/psp_status.go index 228804d2..36aae6cf 100644 --- a/operator/pkg/psp/psp_status.go +++ b/pkg/psp/psp_status.go @@ -4,23 +4,24 @@ package psp import ( + "context" "fmt" "strings" - "context" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/utils" + "gopkg.in/yaml.v2" corev1 "k8s.io/api/core/v1" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" - "k8s.io/apimachinery/pkg/api/errors" - "gopkg.in/yaml.v2" ) type HealthStatusUpdater interface { Update(dc api.CassandraDatacenter) error } -type NoOpUpdater struct {} +type NoOpUpdater struct{} func (*NoOpUpdater) Update(dc api.CassandraDatacenter) error { return nil @@ -66,20 +67,20 @@ type DAO interface { } type DAOImpl struct { - catalogNamespacedName types.NamespacedName + catalogNamespacedName types.NamespacedName healthChecksNamespacedName types.NamespacedName - client runtimeClient.Client + client runtimeClient.Client } func NewDao(client runtimeClient.Client, namespace string) DAO { return &DAOImpl{ client: client, healthChecksNamespacedName: types.NamespacedName{ - Name: "health-check-0", + Name: "health-check-0", Namespace: namespace, }, catalogNamespacedName: types.NamespacedName{ - Name: "health-catalog-0", + Name: "health-catalog-0", Namespace: namespace, }, } @@ -135,11 +136,11 @@ type Status struct { } type Health struct { - Spec `json:"spec"` + Spec `json:"spec"` Status `json:"status"` } -func instanceHealthSchema() map[string]interface{}{ +func instanceHealthSchema() map[string]interface{} { return map[string]interface{}{ "name": "instanceHealth", "fields": []map[string]interface{}{ @@ -162,7 +163,7 @@ func instanceHealthSchema() map[string]interface{}{ func buildSchema() map[string]interface{} { // In a good and just world, we'd generate most of this via reflection on // the Health/InstanceHealth structs, but lets get something that at least - // works before we go all fancy pants. As it happens, at the end of the + // works before we go all fancy pants. As it happens, at the end of the // day, this is just json, and you know what looks a lot like json? strings, // lists, and maps. Good thing Go gives us all of those out of the box. return map[string]interface{}{ @@ -175,7 +176,7 @@ func buildSchema() map[string]interface{} { func createInstanceHealth(dc api.CassandraDatacenter) InstanceHealth { // Everything is happiness and rainbows until proven otherwise - status := HealthGreen + status := HealthGreen if corev1.ConditionFalse == dc.GetConditionStatus(api.DatacenterReady) || corev1.ConditionTrue == dc.GetConditionStatus(api.DatacenterResuming) { status = HealthRed @@ -197,9 +198,9 @@ func createInstanceHealth(dc api.CassandraDatacenter) InstanceHealth { } health := InstanceHealth{ - Instance: dc.Name, + Instance: dc.Name, Namespace: dc.Namespace, - Health: status, + Health: status, } return health @@ -225,7 +226,6 @@ func updateHealth(health *Health, dc api.CassandraDatacenter) { health.Status.InstanceHealth = instanceHealths } - func loadHealthFromConfigMap(configMap *corev1.ConfigMap) (*Health, error) { health := &Health{} configRaw, ok := configMap.BinaryData["health"] @@ -243,8 +243,8 @@ func createHealthCheckConfigMap(health *Health, healthCheckNamespacedName types. utils.AddHashAnnotation(configMap) configMap.SetLabels( utils.MergeMap( - map[string]string{}, - configMap.GetLabels(), + map[string]string{}, + configMap.GetLabels(), map[string]string{HealthLabel: HealthLabelHealthValue})) return configMap @@ -274,20 +274,20 @@ func prefixKeys(m map[string]string, prefix string) map[string]string { func buildInstanceHealthCatalog() map[string]string { desc := strings.Join([]string{ "Provides the overall health of each Cassandra datacenter. A value ", - "of 'green' means the datacenter is available and all of its nodes ", + "of 'green' means the datacenter is available and all of its nodes ", "are in good working order. A value of 'yellow' means that the ", "datacenter is available, but some node may be down (e.g. there ", "might be a rolling restart in progress). A value of 'red' means ", "the cluster is not available (e.g. several nodes are down).", }, "") - return map[string]string { - "testname": "Instance Health", - "short": "Health of cassandra datacenter", - "desc": desc, - "table.label": "CassandraDatacenter Instances", - "columns.instance": "CassandraDatacenter Instance", + return map[string]string{ + "testname": "Instance Health", + "short": "Health of cassandra datacenter", + "desc": desc, + "table.label": "CassandraDatacenter Instances", + "columns.instance": "CassandraDatacenter Instance", "columns.namespace": "Namespace", - "columns.health": "Health", + "columns.health": "Health", } } @@ -307,15 +307,15 @@ func marshalMapToProperties(m map[string]string) string { return b.String() } -func createCatalogConfigMap(catalog Catalog, catalogName types.NamespacedName) (*corev1.ConfigMap) { +func createCatalogConfigMap(catalog Catalog, catalogName types.NamespacedName) *corev1.ConfigMap { content := marshalMapToProperties(catalog) configMap := newConfigMap(catalogName) configMap.Data["health_en"] = content utils.AddHashAnnotation(configMap) configMap.SetLabels( utils.MergeMap( - map[string]string{}, - configMap.GetLabels(), + map[string]string{}, + configMap.GetLabels(), map[string]string{HealthLabel: HealthLabelCatalogValue})) return configMap @@ -332,8 +332,7 @@ func newConfigMap(name types.NamespacedName) *corev1.ConfigMap { } func getConfigMap(client runtimeClient.Client, name types.NamespacedName) (*corev1.ConfigMap, error) { - configMap := &corev1.ConfigMap{ - } + configMap := &corev1.ConfigMap{} err := client.Get( context.TODO(), name, @@ -360,13 +359,13 @@ func upsertConfigMap(client runtimeClient.Client, configMap *corev1.ConfigMap) e resourceVersion := existingConfigMap.GetResourceVersion() configMap.Labels = utils.MergeMap( - map[string]string{}, - existingConfigMap.Labels, + map[string]string{}, + existingConfigMap.Labels, configMap.Labels) configMap.Annotations = utils.MergeMap( - map[string]string{}, - existingConfigMap.Annotations, + map[string]string{}, + existingConfigMap.Annotations, configMap.Annotations) configMap.DeepCopyInto(existingConfigMap) diff --git a/operator/pkg/reconciliation/check_nodes.go b/pkg/reconciliation/check_nodes.go similarity index 97% rename from operator/pkg/reconciliation/check_nodes.go rename to pkg/reconciliation/check_nodes.go index ff337db4..d119a16d 100644 --- a/operator/pkg/reconciliation/check_nodes.go +++ b/pkg/reconciliation/check_nodes.go @@ -11,9 +11,9 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/k8ssandra/cass-operator/pkg/utils" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" ) func (rc *ReconciliationContext) GetPodPVC(podNamespace string, podName string) (*corev1.PersistentVolumeClaim, error) { diff --git a/operator/pkg/reconciliation/construct_podtemplatespec.go b/pkg/reconciliation/construct_podtemplatespec.go similarity index 98% rename from operator/pkg/reconciliation/construct_podtemplatespec.go rename to pkg/reconciliation/construct_podtemplatespec.go index 03b5213c..52ddd356 100644 --- a/operator/pkg/reconciliation/construct_podtemplatespec.go +++ b/pkg/reconciliation/construct_podtemplatespec.go @@ -7,15 +7,16 @@ package reconciliation import ( "fmt" - "github.com/pkg/errors" "reflect" "sort" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/images" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/pkg/errors" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/images" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/utils" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -347,7 +348,7 @@ func getConfigDataEnVars(dc *api.CassandraDatacenter) ([]corev1.EnvVar, error) { if configHash, ok := dc.Annotations[api.ConfigHashAnnotation]; ok { envVars = append(envVars, corev1.EnvVar{ - Name: "CONFIG_HASH", + Name: "CONFIG_HASH", Value: configHash, }) return envVars, nil diff --git a/operator/pkg/reconciliation/construct_podtemplatespec_test.go b/pkg/reconciliation/construct_podtemplatespec_test.go similarity index 96% rename from operator/pkg/reconciliation/construct_podtemplatespec_test.go rename to pkg/reconciliation/construct_podtemplatespec_test.go index 75dea9dc..c3ca14af 100644 --- a/operator/pkg/reconciliation/construct_podtemplatespec_test.go +++ b/pkg/reconciliation/construct_podtemplatespec_test.go @@ -5,16 +5,17 @@ package reconciliation import ( "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "os" "reflect" "testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/api/resource" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/images" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/images" + "github.com/k8ssandra/cass-operator/pkg/oplabels" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" ) @@ -141,7 +142,7 @@ func TestCassandraDatacenter_buildInitContainer_with_overrides(t *testing.T) { t.Error("Unexpected default resources allocated for the init container.") } - assert.Contains(t, initContainers[0].Env, corev1.EnvVar{Name: "k1", Value: "v1"}, + assert.Contains(t, initContainers[0].Env, corev1.EnvVar{Name: "k1", Value: "v1"}, fmt.Sprintf("Unexpected env vars allocated for the init container: %v", initContainers[0].Env)) assert.Contains(t, initContainers[0].Env, corev1.EnvVar{Name: "USE_HOST_IP_FOR_BROADCAST", Value: "false"}, @@ -239,36 +240,36 @@ func TestServerConfigInitContainerEnvVars(t *testing.T) { hostIPEnvVar := corev1.EnvVar{Name: "HOST_IP", ValueFrom: selectorFromFieldPath("status.hostIP")} tests := []struct { - name string - annotations map[string]string + name string + annotations map[string]string config []byte configSecret string - want []corev1.EnvVar + want []corev1.EnvVar }{ { - name: "use config", + name: "use config", config: []byte(`{"cassandra-yaml":{"read_request_timeout_in_ms":10000}}`), want: []corev1.EnvVar{ podIPEnvVar, hostIPEnvVar, { - Name: "USE_HOST_IP_FOR_BROADCAST", + Name: "USE_HOST_IP_FOR_BROADCAST", Value: "false", }, { - Name: "RACK_NAME", + Name: "RACK_NAME", Value: rack, }, { - Name: "PRODUCT_VERSION", + Name: "PRODUCT_VERSION", Value: "3.11.10", }, { - Name: "PRODUCT_NAME", + Name: "PRODUCT_NAME", Value: "cassandra", }, { - Name: "DSE_VERSION", + Name: "DSE_VERSION", Value: "3.11.10", }, }, @@ -283,23 +284,23 @@ func TestServerConfigInitContainerEnvVars(t *testing.T) { podIPEnvVar, hostIPEnvVar, { - Name: "USE_HOST_IP_FOR_BROADCAST", + Name: "USE_HOST_IP_FOR_BROADCAST", Value: "false", }, { - Name: "RACK_NAME", + Name: "RACK_NAME", Value: rack, }, { - Name: "PRODUCT_VERSION", + Name: "PRODUCT_VERSION", Value: "3.11.10", }, { - Name: "PRODUCT_NAME", + Name: "PRODUCT_NAME", Value: "cassandra", }, { - Name: "DSE_VERSION", + Name: "DSE_VERSION", Value: "3.11.10", }, }, @@ -309,8 +310,8 @@ func TestServerConfigInitContainerEnvVars(t *testing.T) { templateSpec := &corev1.PodTemplateSpec{} dc := &api.CassandraDatacenter{ ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "test", + Namespace: "test", + Name: "test", Annotations: tt.annotations, }, Spec: api.CassandraDatacenterSpec{ @@ -318,7 +319,7 @@ func TestServerConfigInitContainerEnvVars(t *testing.T) { ServerType: "cassandra", ServerVersion: "3.11.10", Config: tt.config, - ConfigSecret: tt.configSecret, + ConfigSecret: tt.configSecret, }, } @@ -785,13 +786,13 @@ func TestCassandraDatacenter_buildPodTemplateSpec_overrideSecurityContext(t *tes dc := &api.CassandraDatacenter{ Spec: api.CassandraDatacenterSpec{ - ClusterName: "test", - ServerType: "cassandra", + ClusterName: "test", + ServerType: "cassandra", ServerVersion: "3.11.7", PodTemplateSpec: &corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ SecurityContext: &corev1.PodSecurityContext{ - RunAsUser: &uid, + RunAsUser: &uid, RunAsGroup: &gid, }, }, @@ -805,7 +806,7 @@ func TestCassandraDatacenter_buildPodTemplateSpec_overrideSecurityContext(t *tes assert.NotNil(t, spec) expected := &corev1.PodSecurityContext{ - RunAsUser: &uid, + RunAsUser: &uid, RunAsGroup: &gid, } @@ -1130,29 +1131,29 @@ func Test_makeUbiImage(t *testing.T) { func TestTolerations(t *testing.T) { tolerations := []corev1.Toleration{ { - Key: "cassandra-node", + Key: "cassandra-node", Operator: corev1.TolerationOpExists, - Value: "true", - Effect: corev1.TaintEffectNoExecute, + Value: "true", + Effect: corev1.TaintEffectNoExecute, }, { - Key: "search-node", + Key: "search-node", Operator: corev1.TolerationOpExists, - Value: "true", - Effect: corev1.TaintEffectNoSchedule, + Value: "true", + Effect: corev1.TaintEffectNoSchedule, }, } dc := &api.CassandraDatacenter{ ObjectMeta: metav1.ObjectMeta{ Namespace: "test", - Name: "test", + Name: "test", }, Spec: api.CassandraDatacenterSpec{ - ClusterName: "test", - ServerType: "cassandra", + ClusterName: "test", + ServerType: "cassandra", ServerVersion: "3.11.10", - Tolerations: tolerations, + Tolerations: tolerations, }, } @@ -1166,21 +1167,21 @@ func TestTolerations(t *testing.T) { dc = &api.CassandraDatacenter{ ObjectMeta: metav1.ObjectMeta{ Namespace: "test", - Name: "test", + Name: "test", }, Spec: api.CassandraDatacenterSpec{ - ClusterName: "test", - ServerType: "cassandra", + ClusterName: "test", + ServerType: "cassandra", ServerVersion: "3.11.10", - Tolerations: tolerations, + Tolerations: tolerations, PodTemplateSpec: &corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Tolerations: []corev1.Toleration{ { - Key: "cassandra-node", + Key: "cassandra-node", Operator: corev1.TolerationOpExists, - Value: "false", - Effect: corev1.TaintEffectNoSchedule, + Value: "false", + Effect: corev1.TaintEffectNoSchedule, }, }, }, diff --git a/operator/pkg/reconciliation/construct_service.go b/pkg/reconciliation/construct_service.go similarity index 97% rename from operator/pkg/reconciliation/construct_service.go rename to pkg/reconciliation/construct_service.go index 3f22c672..a2e66752 100644 --- a/operator/pkg/reconciliation/construct_service.go +++ b/pkg/reconciliation/construct_service.go @@ -7,9 +7,9 @@ package reconciliation import ( "net" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/utils" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" diff --git a/operator/pkg/reconciliation/construct_service_test.go b/pkg/reconciliation/construct_service_test.go similarity index 90% rename from operator/pkg/reconciliation/construct_service_test.go rename to pkg/reconciliation/construct_service_test.go index 50fc8750..39b2e51a 100644 --- a/operator/pkg/reconciliation/construct_service_test.go +++ b/pkg/reconciliation/construct_service_test.go @@ -4,12 +4,13 @@ package reconciliation import ( - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "reflect" "testing" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" ) func TestCassandraDatacenter_buildLabelSelectorForSeedService(t *testing.T) { diff --git a/operator/pkg/reconciliation/construct_statefulset.go b/pkg/reconciliation/construct_statefulset.go similarity index 93% rename from operator/pkg/reconciliation/construct_statefulset.go rename to pkg/reconciliation/construct_statefulset.go index e83c6530..26053239 100644 --- a/operator/pkg/reconciliation/construct_statefulset.go +++ b/pkg/reconciliation/construct_statefulset.go @@ -8,12 +8,12 @@ package reconciliation import ( "fmt" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/images" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/psp" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/images" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/psp" + "github.com/k8ssandra/cass-operator/pkg/utils" logf "sigs.k8s.io/controller-runtime/pkg/log" appsv1 "k8s.io/api/apps/v1" diff --git a/operator/pkg/reconciliation/construct_statefulset_test.go b/pkg/reconciliation/construct_statefulset_test.go similarity index 98% rename from operator/pkg/reconciliation/construct_statefulset_test.go rename to pkg/reconciliation/construct_statefulset_test.go index 1a42f0e7..595c2eb7 100644 --- a/operator/pkg/reconciliation/construct_statefulset_test.go +++ b/pkg/reconciliation/construct_statefulset_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" ) @@ -190,7 +190,7 @@ func Test_newStatefulSetForCassandraDatacenterWithAdditionalVolumes(t *testing.T assert.Equal(t, "/var/log/cassandra", got.Spec.Template.Spec.InitContainers[0].VolumeMounts[0].MountPath) assert.Equal(t, "server-config-init", got.Spec.Template.Spec.InitContainers[1].Name) - assert.Equal(t, "datastax/cass-config-builder:1.0.3", got.Spec.Template.Spec.InitContainers[1].Image) + assert.Equal(t, "datastax/cass-config-builder:1.0.4", got.Spec.Template.Spec.InitContainers[1].Image) assert.Equal(t, 1, len(got.Spec.Template.Spec.InitContainers[1].VolumeMounts)) assert.Equal(t, "server-config", got.Spec.Template.Spec.InitContainers[1].VolumeMounts[0].Name) assert.Equal(t, "/config", got.Spec.Template.Spec.InitContainers[1].VolumeMounts[0].MountPath) diff --git a/operator/pkg/reconciliation/constructor.go b/pkg/reconciliation/constructor.go similarity index 90% rename from operator/pkg/reconciliation/constructor.go rename to pkg/reconciliation/constructor.go index 79d553b0..b9c1ffe3 100644 --- a/operator/pkg/reconciliation/constructor.go +++ b/pkg/reconciliation/constructor.go @@ -6,9 +6,9 @@ package reconciliation // This file defines constructors for k8s objects import ( - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/utils" policyv1beta1 "k8s.io/api/policy/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/operator/pkg/reconciliation/context.go b/pkg/reconciliation/context.go similarity index 90% rename from operator/pkg/reconciliation/context.go rename to pkg/reconciliation/context.go index 7ecf61b9..a6a6488b 100644 --- a/operator/pkg/reconciliation/context.go +++ b/pkg/reconciliation/context.go @@ -14,14 +14,13 @@ import ( "k8s.io/client-go/tools/record" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/operator-framework/operator-sdk/pkg/k8sutil" - - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/dynamicwatch" - "github.com/k8ssandra/cass-operator/operator/pkg/events" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/psp" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/dynamicwatch" + "github.com/k8ssandra/cass-operator/pkg/events" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/psp" + "github.com/k8ssandra/cass-operator/pkg/utils" ) // ReconciliationContext contains all of the input necessary to calculate a list of ReconciliationActions @@ -57,7 +56,7 @@ func CreateReconciliationContext( rec record.EventRecorder, secretWatches dynamicwatch.DynamicWatches, reqLogger logr.Logger) (*ReconciliationContext, error) { - + rc := &ReconciliationContext{} rc.Request = req rc.Client = cli @@ -75,7 +74,7 @@ func CreateReconciliationContext( if utils.IsPSPEnabled() { // Add PSP health status updater // TODO: Feature gate this - operatorNs, err := k8sutil.GetOperatorNamespace() + operatorNs, err := utils.GetOperatorNamespace() if err != nil { return nil, err } diff --git a/operator/pkg/reconciliation/decommission_node.go b/pkg/reconciliation/decommission_node.go similarity index 97% rename from operator/pkg/reconciliation/decommission_node.go rename to pkg/reconciliation/decommission_node.go index f559798f..96b46d7a 100644 --- a/operator/pkg/reconciliation/decommission_node.go +++ b/pkg/reconciliation/decommission_node.go @@ -10,10 +10,10 @@ import ( v1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/events" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/events" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/internal/result" "k8s.io/apimachinery/pkg/types" ) diff --git a/operator/pkg/reconciliation/decommission_node_test.go b/pkg/reconciliation/decommission_node_test.go similarity index 85% rename from operator/pkg/reconciliation/decommission_node_test.go rename to pkg/reconciliation/decommission_node_test.go index a43fd64d..0fb18a68 100644 --- a/operator/pkg/reconciliation/decommission_node_test.go +++ b/pkg/reconciliation/decommission_node_test.go @@ -10,18 +10,15 @@ import ( "strings" "testing" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/internal/result" + "github.com/k8ssandra/cass-operator/pkg/mocks" + "github.com/stretchr/testify/mock" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" - "github.com/stretchr/testify/mock" ) func TestRetryDecommissionNode(t *testing.T) { @@ -147,11 +144,11 @@ type statusMock struct { called int } -func (s *statusMock) Update(ctx context.Context, obj runtime.Object, opts ...client.UpdateOption) error { +func (s *statusMock) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { return nil } -func (s *statusMock) Patch(ctx context.Context, obj runtime.Object, patch client.Patch, opts ...client.PatchOption) error { +func (s *statusMock) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { s.called = s.called + 1 return nil } diff --git a/operator/pkg/reconciliation/defaults.go b/pkg/reconciliation/defaults.go similarity index 68% rename from operator/pkg/reconciliation/defaults.go rename to pkg/reconciliation/defaults.go index d1fcd01d..0967ba95 100644 --- a/operator/pkg/reconciliation/defaults.go +++ b/pkg/reconciliation/defaults.go @@ -6,7 +6,4 @@ var ( // Provides reasonable defaults for the configuration container. DefaultsConfigInitContainer = buildResourceRequirements(1000, 256) - - // Provides reasonable defaults for the reaper sidecar container. - DefaultsReaperContainer = buildResourceRequirements(2000, 512) ) diff --git a/operator/pkg/reconciliation/handler.go b/pkg/reconciliation/handler.go similarity index 55% rename from operator/pkg/reconciliation/handler.go rename to pkg/reconciliation/handler.go index 58c19fd7..f01f144e 100644 --- a/operator/pkg/reconciliation/handler.go +++ b/pkg/reconciliation/handler.go @@ -5,30 +5,24 @@ package reconciliation import ( "fmt" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" + "sync" + + "github.com/k8ssandra/cass-operator/pkg/oplabels" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sync" - "time" corev1 "k8s.io/api/core/v1" - "github.com/google/uuid" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/dynamicwatch" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" - "github.com/k8ssandra/cass-operator/operator/pkg/psp" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/internal/result" + "github.com/k8ssandra/cass-operator/pkg/psp" + "github.com/k8ssandra/cass-operator/pkg/utils" ) // Use a var so we can mock this function @@ -126,7 +120,7 @@ func (rc *ReconciliationContext) updateDcMaps() error { // be taken on the CassandraDatacenter. If a change is needed then the apply function will be called on that reconciler and the // request will be requeued for the next reconciler to handle in the subsequent reconcile loop, otherwise the next reconciler // will be called. -func (rc *ReconciliationContext) calculateReconciliationActions() (reconcile.Result, error) { +func (rc *ReconciliationContext) CalculateReconciliationActions() (reconcile.Result, error) { rc.ReqLogger.Info("handler::calculateReconciliationActions") if utils.IsPSPEnabled() { @@ -183,97 +177,6 @@ func (rc *ReconciliationContext) calculateReconciliationActions() (reconcile.Res var log = logf.Log.WithName("reconciliation_handler") -// Reconciliation related data structures - -// ReconcileCassandraDatacenter reconciles a cassandraDatacenter object -// This is placed here to avoid a circular dependency -type ReconcileCassandraDatacenter struct { - // This client, initialized using mgr.client() above, is a split client - // that reads objects from the cache and writes to the apiserver - client client.Client - scheme *runtime.Scheme - recorder record.EventRecorder - - // SecretWatches is used in the controller when setting up the watches and - // during reconciliation where we update the mappings for the watches. - // Putting it here allows us to get it to both places. - SecretWatches dynamicwatch.DynamicWatches -} - -// Reconcile reads that state of the cluster for a Datacenter object -// and makes changes based on the state read -// and what is in the cassandraDatacenter.Spec -// Note: -// The Controller will requeue the Request to be processed again -// if the returned error is non-nil or Result.Requeue is true, -// otherwise upon completion it will remove the work from the queue. -// See: https://godoc.org/sigs.k8s.io/controller-runtime/pkg/reconcile#Result -func (r *ReconcileCassandraDatacenter) Reconcile(request reconcile.Request) (reconcile.Result, error) { - - startReconcile := time.Now() - - logger := log. - WithValues("requestNamespace", request.Namespace). - WithValues("requestName", request.Name). - // loopID is used to tie all events together that are spawned by the same reconciliation loop - WithValues("loopID", uuid.New().String()) - - defer func() { - reconcileDuration := time.Since(startReconcile).Seconds() - logger.Info("Reconcile loop completed", - "duration", reconcileDuration) - }() - - logger.Info("======== handler::Reconcile has been called") - - rc, err := CreateReconciliationContext(&request, r.client, r.scheme, r.recorder, r.SecretWatches, logger) - - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. - // Return and don't requeue - logger.Info("CassandraDatacenter resource not found. Ignoring since object must be deleted.") - return result.Done().Output() - } - - // Error reading the object - logger.Error(err, "Failed to get CassandraDatacenter.") - return result.Error(err).Output() - } - - if err := rc.isValid(rc.Datacenter); err != nil { - logger.Error(err, "CassandraDatacenter resource is invalid") - rc.Recorder.Eventf(rc.Datacenter, "Warning", "ValidationFailed", err.Error()) - return result.Error(err).Output() - } - - // TODO fold this into the quiet period - twentySecs := time.Second * 20 - lastNodeStart := rc.Datacenter.Status.LastServerNodeStarted - cooldownTime := time.Until(lastNodeStart.Add(twentySecs)) - - if cooldownTime > 0 { - logger.Info("Ending reconciliation early because a server node was recently started") - secs := 1 + int(cooldownTime.Seconds()) - return result.RequeueSoon(secs).Output() - } - - if rc.Datacenter.Status.QuietPeriod.After(time.Now()) { - logger.Info("Ending reconciliation early because the datacenter is in a quiet period") - cooldownTime = rc.Datacenter.Status.QuietPeriod.Sub(time.Now()) - secs := 1 + int(cooldownTime.Seconds()) - return result.RequeueSoon(secs).Output() - } - - res, err := rc.calculateReconciliationActions() - if err != nil { - logger.Error(err, "calculateReconciliationActions returned an error") - rc.Recorder.Eventf(rc.Datacenter, "Warning", "ReconcileFailed", err.Error()) - } - return res, err -} - func (rc *ReconciliationContext) addFinalizer() error { if len(rc.Datacenter.GetFinalizers()) < 1 && rc.Datacenter.GetDeletionTimestamp() == nil { rc.ReqLogger.Info("Adding Finalizer for the CassandraDatacenter") @@ -289,7 +192,7 @@ func (rc *ReconciliationContext) addFinalizer() error { return nil } -func (rc *ReconciliationContext) isValid(dc *api.CassandraDatacenter) error { +func (rc *ReconciliationContext) IsValid(dc *api.CassandraDatacenter) error { var errs []error = []error{} // Basic validation up here @@ -324,15 +227,3 @@ func (rc *ReconciliationContext) isValid(dc *api.CassandraDatacenter) error { return nil } - -// NewReconciler returns a new reconcile.Reconciler -func NewReconciler(mgr manager.Manager) reconcile.Reconciler { - client := mgr.GetClient() - dynamicWatches := dynamicwatch.NewDynamicSecretWatches(client) - return &ReconcileCassandraDatacenter{ - client: mgr.GetClient(), - scheme: mgr.GetScheme(), - recorder: mgr.GetEventRecorderFor("cass-operator"), - SecretWatches: dynamicWatches, - } -} diff --git a/pkg/reconciliation/handler_test.go b/pkg/reconciliation/handler_test.go new file mode 100644 index 00000000..84c1d8b1 --- /dev/null +++ b/pkg/reconciliation/handler_test.go @@ -0,0 +1,384 @@ +// Copyright DataStax, Inc. +// Please see the included license file for details. + +package reconciliation + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/k8ssandra/cass-operator/pkg/mocks" +) + +func TestCalculateReconciliationActions(t *testing.T) { + rc, _, cleanupMockScr := setupTest() + defer cleanupMockScr() + + result, err := rc.CalculateReconciliationActions() + assert.NoErrorf(t, err, "Should not have returned an error while calculating reconciliation actions") + assert.NotNil(t, result, "Result should not be nil") + + // Add a service and check the logic + + fakeClient, _ := fakeClientWithService(rc.Datacenter) + rc.Client = *fakeClient + + result, err = rc.CalculateReconciliationActions() + assert.NoErrorf(t, err, "Should not have returned an error while calculating reconciliation actions") + assert.NotNil(t, result, "Result should not be nil") +} + +func TestCalculateReconciliationActions_GetServiceError(t *testing.T) { + rc, _, cleanupMockScr := setupTest() + defer cleanupMockScr() + + mockClient := &mocks.Client{} + rc.Client = mockClient + + k8sMockClientGet(mockClient, fmt.Errorf("")) + k8sMockClientUpdate(mockClient, nil).Times(1) + // k8sMockClientCreate(mockClient, nil) + + _, err := rc.CalculateReconciliationActions() + assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") + + mockClient.AssertExpectations(t) +} + +func TestCalculateReconciliationActions_FailedUpdate(t *testing.T) { + rc, _, cleanupMockScr := setupTest() + defer cleanupMockScr() + + mockClient := &mocks.Client{} + rc.Client = mockClient + + k8sMockClientUpdate(mockClient, fmt.Errorf("failed to update CassandraDatacenter with removed finalizers")) + + _, err := rc.CalculateReconciliationActions() + assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") + + mockClient.AssertExpectations(t) +} + +func TestProcessDeletion_FailedDelete(t *testing.T) { + t.Skip() + rc, _, cleanupMockScr := setupTest() + defer cleanupMockScr() + + mockClient := &mocks.Client{} + rc.Client = mockClient + + k8sMockClientList(mockClient, nil). + Run(func(args mock.Arguments) { + arg := args.Get(1).(*v1.PersistentVolumeClaimList) + arg.Items = []v1.PersistentVolumeClaim{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pvc-1", + }, + }} + }) + + k8sMockClientDelete(mockClient, fmt.Errorf("")) + k8sMockClientUpdate(mockClient, nil).Times(1) + + now := metav1.Now() + rc.Datacenter.SetDeletionTimestamp(&now) + + result, err := rc.CalculateReconciliationActions() + assert.Errorf(t, err, "Should have returned an error while calculating reconciliation actions") + assert.Equal(t, reconcile.Result{Requeue: true}, result, "Should requeue request") + + mockClient.AssertExpectations(t) +} + +// func TestReconcile(t *testing.T) { +// t.Skip() + +// // Set up verbose logging +// logger := zap.New() +// logf.SetLogger(logger) + +// var ( +// name = "cluster-example-cluster.dc-example-datacenter" +// namespace = "default" +// size int32 = 2 +// ) +// storageSize := resource.MustParse("1Gi") +// storageName := "server-data" +// storageConfig := api.StorageConfig{ +// CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ +// StorageClassName: &storageName, +// AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, +// Resources: corev1.ResourceRequirements{ +// Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, +// }, +// }, +// } + +// // Instance a CassandraDatacenter +// dc := &api.CassandraDatacenter{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: name, +// Namespace: namespace, +// }, +// Spec: api.CassandraDatacenterSpec{ +// ManagementApiAuth: api.ManagementApiAuthConfig{ +// Insecure: &api.ManagementApiAuthInsecureConfig{}, +// }, +// Size: size, +// ServerVersion: "6.8.0", +// StorageConfig: storageConfig, +// ClusterName: "cluster-example", +// }, +// } + +// // Objects to keep track of +// trackObjects := []runtime.Object{ +// dc, +// } + +// s := scheme.Scheme +// s.AddKnownTypes(api.GroupVersion, dc) + +// fakeClient := fake.NewFakeClient(trackObjects...) + +// r := &ReconcileCassandraDatacenter{ +// client: fakeClient, +// scheme: s, +// recorder: record.NewFakeRecorder(100), +// } + +// request := reconcile.Request{ +// NamespacedName: types.NamespacedName{ +// Name: name, +// Namespace: namespace, +// }, +// } + +// result, err := r.Reconcile(request) +// if err != nil { +// t.Fatalf("Reconciliation Failure: (%v)", err) +// } + +// if result != (reconcile.Result{Requeue: true}) { +// t.Error("Reconcile did not return a correct result.") +// } +// } + +// func TestReconcile_NotFound(t *testing.T) { +// t.Skip() + +// // Set up verbose logging +// logger := zap.New() +// logf.SetLogger(logger) + +// var ( +// name = "datacenter-example" +// namespace = "default" +// size int32 = 2 +// ) + +// storageSize := resource.MustParse("1Gi") +// storageName := "server-data" +// storageConfig := api.StorageConfig{ +// CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ +// StorageClassName: &storageName, +// AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, +// Resources: corev1.ResourceRequirements{ +// Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, +// }, +// }, +// } + +// // Instance a CassandraDatacenter +// dc := &api.CassandraDatacenter{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: name, +// Namespace: namespace, +// }, +// Spec: api.CassandraDatacenterSpec{ +// ManagementApiAuth: api.ManagementApiAuthConfig{ +// Insecure: &api.ManagementApiAuthInsecureConfig{}, +// }, +// Size: size, +// StorageConfig: storageConfig, +// }, +// } + +// // Objects to keep track of +// trackObjects := []runtime.Object{} + +// s := scheme.Scheme +// s.AddKnownTypes(api.GroupVersion, dc) + +// fakeClient := fake.NewFakeClient(trackObjects...) + +// r := &ReconcileCassandraDatacenter{ +// client: fakeClient, +// scheme: s, +// } + +// request := reconcile.Request{ +// NamespacedName: types.NamespacedName{ +// Name: name, +// Namespace: namespace, +// }, +// } + +// result, err := r.Reconcile(request) +// if err != nil { +// t.Fatalf("Reconciliation Failure: (%v)", err) +// } + +// expected := reconcile.Result{} +// if result != expected { +// t.Error("expected to get a zero-value reconcile.Result") +// } +// } + +// func TestReconcile_Error(t *testing.T) { +// // Set up verbose logging +// logger := zap.New() +// logf.SetLogger(logger) + +// var ( +// name = "datacenter-example" +// namespace = "default" +// size int32 = 2 +// ) + +// storageSize := resource.MustParse("1Gi") +// storageName := "server-data" +// storageConfig := api.StorageConfig{ +// CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ +// StorageClassName: &storageName, +// AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, +// Resources: corev1.ResourceRequirements{ +// Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, +// }, +// }, +// } + +// // Instance a CassandraDatacenter +// dc := &api.CassandraDatacenter{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: name, +// Namespace: namespace, +// }, +// Spec: api.CassandraDatacenterSpec{ +// ManagementApiAuth: api.ManagementApiAuthConfig{ +// Insecure: &api.ManagementApiAuthInsecureConfig{}, +// }, +// Size: size, +// StorageConfig: storageConfig, +// }, +// } + +// // Objects to keep track of + +// s := scheme.Scheme +// s.AddKnownTypes(api.GroupVersion, dc) + +// mockClient := &mocks.Client{} +// k8sMockClientGet(mockClient, fmt.Errorf("")) + +// r := &ReconcileCassandraDatacenter{ +// client: mockClient, +// scheme: s, +// } + +// request := reconcile.Request{ +// NamespacedName: types.NamespacedName{ +// Name: name, +// Namespace: namespace, +// }, +// } + +// _, err := r.Reconcile(request) +// if err == nil { +// t.Fatalf("Reconciliation should have failed") +// } +// } + +// func TestReconcile_CassandraDatacenterToBeDeleted(t *testing.T) { +// t.Skip() +// // Set up verbose logging +// logger := zap.New() +// logf.SetLogger(logger) + +// var ( +// name = "datacenter-example" +// namespace = "default" +// size int32 = 2 +// ) + +// storageSize := resource.MustParse("1Gi") +// storageName := "server-data" +// storageConfig := api.StorageConfig{ +// CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{ +// StorageClassName: &storageName, +// AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, +// Resources: corev1.ResourceRequirements{ +// Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize}, +// }, +// }, +// } + +// // Instance a CassandraDatacenter +// now := metav1.Now() +// dc := &api.CassandraDatacenter{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: name, +// Namespace: namespace, +// DeletionTimestamp: &now, +// Finalizers: nil, +// }, +// Spec: api.CassandraDatacenterSpec{ +// ManagementApiAuth: api.ManagementApiAuthConfig{ +// Insecure: &api.ManagementApiAuthInsecureConfig{}, +// }, +// Size: size, +// ServerVersion: "6.8.0", +// StorageConfig: storageConfig, +// }, +// } + +// // Objects to keep track of +// trackObjects := []runtime.Object{ +// dc, +// } + +// s := scheme.Scheme +// s.AddKnownTypes(api.GroupVersion, dc) + +// fakeClient := fake.NewFakeClient(trackObjects...) + +// r := &ReconcileCassandraDatacenter{ +// client: fakeClient, +// scheme: s, +// } + +// request := reconcile.Request{ +// NamespacedName: types.NamespacedName{ +// Name: name, +// Namespace: namespace, +// }, +// } + +// result, err := r.Reconcile(request) +// if err != nil { +// t.Fatalf("Reconciliation Failure: (%v)", err) +// } + +// if result != (reconcile.Result{}) { +// t.Error("Reconcile did not return an empty result.") +// } +// } diff --git a/operator/pkg/reconciliation/rackinformation.go b/pkg/reconciliation/rackinformation.go similarity index 100% rename from operator/pkg/reconciliation/rackinformation.go rename to pkg/reconciliation/rackinformation.go diff --git a/operator/pkg/reconciliation/reconcile_configsecret.go b/pkg/reconciliation/reconcile_configsecret.go similarity index 94% rename from operator/pkg/reconciliation/reconcile_configsecret.go rename to pkg/reconciliation/reconcile_configsecret.go index 472aef0b..bc8f553b 100644 --- a/operator/pkg/reconciliation/reconcile_configsecret.go +++ b/pkg/reconciliation/reconcile_configsecret.go @@ -5,8 +5,9 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/internal/result" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -64,7 +65,7 @@ func (rc *ReconciliationContext) CheckConfigSecret() result.ReconcileResult { if exists { if err := rc.Client.Update(rc.Ctx, dcConfigSecret); err != nil { - rc.ReqLogger.Error(err,"failed to update datacenter config secret", "ConfigSecret", dcConfigSecret.Name) + rc.ReqLogger.Error(err, "failed to update datacenter config secret", "ConfigSecret", dcConfigSecret.Name) return result.Error(err) } } @@ -81,7 +82,7 @@ func (rc *ReconciliationContext) CheckConfigSecret() result.ReconcileResult { // If the secret does not have the annotation, it is added, and the secret is patched. The // secret should be the one specifiied by ConfigSecret. func (rc *ReconciliationContext) checkDatacenterNameAnnotation(secret *corev1.Secret) error { - if v, ok := secret.Annotations[api.DatacenterAnnotation]; ok && v == rc.Datacenter.Name { + if v, ok := secret.Annotations[api.DatacenterAnnotation]; ok && v == rc.Datacenter.Name { return nil } @@ -139,11 +140,11 @@ func (rc *ReconciliationContext) getDatacenterConfigSecret(name string) (*corev1 if err == nil { return secret, true, nil - } else if errors.IsNotFound(err) { + } else if errors.IsNotFound(err) { secret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: key.Namespace, - Name: name, + Name: name, }, Data: map[string][]byte{}, } @@ -156,4 +157,4 @@ func (rc *ReconciliationContext) getDatacenterConfigSecret(name string) (*corev1 } else { return nil, false, err } -} \ No newline at end of file +} diff --git a/operator/pkg/reconciliation/reconcile_datacenter.go b/pkg/reconciliation/reconcile_datacenter.go similarity index 94% rename from operator/pkg/reconciliation/reconcile_datacenter.go rename to pkg/reconciliation/reconcile_datacenter.go index 5e5b82e0..bedc03bf 100644 --- a/operator/pkg/reconciliation/reconcile_datacenter.go +++ b/pkg/reconciliation/reconcile_datacenter.go @@ -4,7 +4,7 @@ package reconciliation import ( - "github.com/k8ssandra/cass-operator/operator/internal/result" + "github.com/k8ssandra/cass-operator/pkg/internal/result" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -12,8 +12,8 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/utils" ) // ProcessDeletion ... diff --git a/operator/pkg/reconciliation/reconcile_datacenter_test.go b/pkg/reconciliation/reconcile_datacenter_test.go similarity index 97% rename from operator/pkg/reconciliation/reconcile_datacenter_test.go rename to pkg/reconciliation/reconcile_datacenter_test.go index 50ea835e..8aeb2199 100644 --- a/operator/pkg/reconciliation/reconcile_datacenter_test.go +++ b/pkg/reconciliation/reconcile_datacenter_test.go @@ -14,7 +14,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" + "github.com/k8ssandra/cass-operator/pkg/mocks" ) func TestDeletePVCs(t *testing.T) { diff --git a/operator/pkg/reconciliation/reconcile_endpoints.go b/pkg/reconciliation/reconcile_endpoints.go similarity index 94% rename from operator/pkg/reconciliation/reconcile_endpoints.go rename to pkg/reconciliation/reconcile_endpoints.go index cb301601..6bdd805f 100644 --- a/operator/pkg/reconciliation/reconcile_endpoints.go +++ b/pkg/reconciliation/reconcile_endpoints.go @@ -4,13 +4,13 @@ package reconciliation import ( - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/internal/result" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/k8ssandra/cass-operator/pkg/utils" ) func (rc *ReconciliationContext) CreateEndpointsForAdditionalSeedService() result.ReconcileResult { diff --git a/operator/pkg/reconciliation/reconcile_racks.go b/pkg/reconciliation/reconcile_racks.go similarity index 99% rename from operator/pkg/reconciliation/reconcile_racks.go rename to pkg/reconciliation/reconcile_racks.go index b6409ad6..8a4688b2 100644 --- a/operator/pkg/reconciliation/reconcile_racks.go +++ b/pkg/reconciliation/reconcile_racks.go @@ -14,6 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" policyv1beta1 "k8s.io/api/policy/v1beta1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -21,13 +22,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/events" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/psp" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/events" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/internal/result" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/psp" + "github.com/k8ssandra/cass-operator/pkg/utils" ) var ( @@ -141,7 +142,7 @@ func (rc *ReconciliationContext) CheckRackCreation() result.ReconcileResult { return result.Error(err) } - if statefulSetFound == false { + if !statefulSetFound { rc.ReqLogger.Info( "Need to create new StatefulSet for", "Rack", rackInfo.RackName) @@ -154,7 +155,6 @@ func (rc *ReconciliationContext) CheckRackCreation() result.ReconcileResult { return result.Error(err) } } - rc.statefulSets[idx] = statefulSet } @@ -210,15 +210,11 @@ func (rc *ReconciliationContext) CheckRackPodTemplate() result.ReconcileResult { return result.Error(err) } - needsUpdate := false - if !utils.ResourcesHaveSameHash(statefulSet, desiredSts) { logger. WithValues("rackName", rackName). Info("statefulset needs an update") - needsUpdate = true - // "fix" the replica count, and maintain labels and annotations the k8s admin may have set desiredSts.Spec.Replicas = statefulSet.Spec.Replicas desiredSts.Labels = utils.MergeMap(map[string]string{}, statefulSet.Labels, desiredSts.Labels) @@ -239,11 +235,14 @@ func (rc *ReconciliationContext) CheckRackPodTemplate() result.ReconcileResult { } desiredSts.Spec.UpdateStrategy = strategy } + stateMeta, err := meta.Accessor(statefulSet) + resVersion := stateMeta.GetResourceVersion() + if err != nil { + return result.Error(err) + } desiredSts.DeepCopyInto(statefulSet) - } - if needsUpdate { rc.Recorder.Eventf(rc.Datacenter, corev1.EventTypeNormal, events.UpdatingRack, "Updating rack %s", rackName) @@ -267,6 +266,7 @@ func (rc *ReconciliationContext) CheckRackPodTemplate() result.ReconcileResult { "statefulSet", statefulSet, ) + statefulSet.SetResourceVersion(resVersion) err = rc.Client.Update(rc.Ctx, statefulSet) if err != nil { logger.Error( @@ -1403,7 +1403,6 @@ func (rc *ReconciliationContext) ReconcileNextRack(statefulSet *appsv1.StatefulS if err := rc.Client.Create(rc.Ctx, statefulSet); err != nil { return err } - rc.Recorder.Eventf(rc.Datacenter, corev1.EventTypeNormal, events.CreatedResource, "Created statefulset %s", statefulSet.Name) @@ -2004,7 +2003,7 @@ func (rc *ReconciliationContext) CheckRollingRestart() result.ReconcileResult { return result.Error(err) } - dcPatch = client.MergeFrom(dc.DeepCopy()) + dcPatch = client.MergeFromWithOptions(dc.DeepCopy(), client.MergeFromWithOptimisticLock{}) dc.Spec.RollingRestartRequested = false err = rc.Client.Patch(rc.Ctx, dc, dcPatch) if err != nil { diff --git a/operator/pkg/reconciliation/reconcile_racks_helpers.go b/pkg/reconciliation/reconcile_racks_helpers.go similarity index 94% rename from operator/pkg/reconciliation/reconcile_racks_helpers.go rename to pkg/reconciliation/reconcile_racks_helpers.go index d4843061..60f6ca09 100644 --- a/operator/pkg/reconciliation/reconcile_racks_helpers.go +++ b/pkg/reconciliation/reconcile_racks_helpers.go @@ -5,8 +5,8 @@ package reconciliation import ( "fmt" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" ) diff --git a/operator/pkg/reconciliation/reconcile_racks_helpers_test.go b/pkg/reconciliation/reconcile_racks_helpers_test.go similarity index 100% rename from operator/pkg/reconciliation/reconcile_racks_helpers_test.go rename to pkg/reconciliation/reconcile_racks_helpers_test.go diff --git a/operator/pkg/reconciliation/reconcile_racks_test.go b/pkg/reconciliation/reconcile_racks_test.go similarity index 99% rename from operator/pkg/reconciliation/reconcile_racks_test.go rename to pkg/reconciliation/reconcile_racks_test.go index e4b42a53..7420afdf 100644 --- a/operator/pkg/reconciliation/reconcile_racks_test.go +++ b/pkg/reconciliation/reconcile_racks_test.go @@ -13,11 +13,11 @@ import ( "testing" "time" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" - "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/mocks" + "github.com/k8ssandra/cass-operator/pkg/oplabels" + "github.com/k8ssandra/cass-operator/pkg/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" appsv1 "k8s.io/api/apps/v1" diff --git a/operator/pkg/reconciliation/reconcile_services.go b/pkg/reconciliation/reconcile_services.go similarity index 95% rename from operator/pkg/reconciliation/reconcile_services.go rename to pkg/reconciliation/reconcile_services.go index ff30744a..ff849c2b 100644 --- a/operator/pkg/reconciliation/reconcile_services.go +++ b/pkg/reconciliation/reconcile_services.go @@ -4,13 +4,13 @@ package reconciliation import ( - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/internal/result" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + "github.com/k8ssandra/cass-operator/pkg/utils" ) func (rc *ReconciliationContext) CreateHeadlessServices() result.ReconcileResult { diff --git a/operator/pkg/reconciliation/reconcile_services_test.go b/pkg/reconciliation/reconcile_services_test.go similarity index 98% rename from operator/pkg/reconciliation/reconcile_services_test.go rename to pkg/reconciliation/reconcile_services_test.go index b8eb50a6..f6c68e35 100644 --- a/operator/pkg/reconciliation/reconcile_services_test.go +++ b/pkg/reconciliation/reconcile_services_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/mock" corev1 "k8s.io/api/core/v1" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" + "github.com/k8ssandra/cass-operator/pkg/mocks" ) func TestReconcileHeadlessService(t *testing.T) { diff --git a/operator/pkg/reconciliation/secrets.go b/pkg/reconciliation/secrets.go similarity index 98% rename from operator/pkg/reconciliation/secrets.go rename to pkg/reconciliation/secrets.go index a6ad119b..75f10e1f 100644 --- a/operator/pkg/reconciliation/secrets.go +++ b/pkg/reconciliation/secrets.go @@ -14,8 +14,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/utils" ) func generateUtf8Password() (string, error) { diff --git a/operator/pkg/reconciliation/secrets_test.go b/pkg/reconciliation/secrets_test.go similarity index 98% rename from operator/pkg/reconciliation/secrets_test.go rename to pkg/reconciliation/secrets_test.go index 22614fff..d52798c0 100644 --- a/operator/pkg/reconciliation/secrets_test.go +++ b/pkg/reconciliation/secrets_test.go @@ -10,7 +10,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" + api "github.com/k8ssandra/cass-operator/api/v1beta1" ) func Test_buildDefaultSuperuserSecret(t *testing.T) { diff --git a/operator/pkg/reconciliation/testing.go b/pkg/reconciliation/testing.go similarity index 94% rename from operator/pkg/reconciliation/testing.go rename to pkg/reconciliation/testing.go index 4de97789..fa887dc1 100644 --- a/operator/pkg/reconciliation/testing.go +++ b/pkg/reconciliation/testing.go @@ -13,8 +13,8 @@ import ( "net/http" "strings" - "github.com/k8ssandra/cass-operator/operator/pkg/psp" "github.com/go-logr/logr" + "github.com/k8ssandra/cass-operator/pkg/psp" mock "github.com/stretchr/testify/mock" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -29,9 +29,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/reconcile" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" - "github.com/k8ssandra/cass-operator/operator/pkg/mocks" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/pkg/httphelper" + "github.com/k8ssandra/cass-operator/pkg/mocks" ) // MockSetControllerReference returns a method that will automatically reverse the mock @@ -96,7 +96,7 @@ func CreateMockReconciliationContext( } s := scheme.Scheme - s.AddKnownTypes(api.SchemeGroupVersion, cassandraDatacenter) + s.AddKnownTypes(api.GroupVersion, cassandraDatacenter) fakeClient := fake.NewFakeClient(trackObjects...) @@ -156,7 +156,7 @@ func fakeClientWithService( func setupTest() (*ReconciliationContext, *corev1.Service, func()) { // Set up verbose logging - logger := zap.Logger(true) + logger := zap.New() log2.SetLogger(logger) cleanupMockScr := MockSetControllerReference() diff --git a/operator/pkg/reconciliation/utils.go b/pkg/reconciliation/utils.go similarity index 83% rename from operator/pkg/reconciliation/utils.go rename to pkg/reconciliation/utils.go index 61426307..78461f7f 100644 --- a/operator/pkg/reconciliation/utils.go +++ b/pkg/reconciliation/utils.go @@ -9,11 +9,11 @@ import ( func buildResourceRequirements(cpuMillis int64, memoryMB int64) corev1.ResourceRequirements { return corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - "cpu": *resource.NewMilliQuantity(cpuMillis, resource.DecimalSI), + "cpu": *resource.NewMilliQuantity(cpuMillis, resource.DecimalSI), "memory": *resource.NewScaledQuantity(memoryMB, resource.Mega), }, Limits: corev1.ResourceList{ - "cpu": *resource.NewMilliQuantity(cpuMillis, resource.DecimalSI), + "cpu": *resource.NewMilliQuantity(cpuMillis, resource.DecimalSI), "memory": *resource.NewScaledQuantity(memoryMB, resource.Mega), }, } @@ -30,7 +30,7 @@ func isResourceRequirementsNotSpecified(res *corev1.ResourceRequirements) bool { // Returns the default resources in case the given resources are not configured. func getResourcesOrDefault(res *corev1.ResourceRequirements, - defaultRes *corev1.ResourceRequirements) *corev1.ResourceRequirements { + defaultRes *corev1.ResourceRequirements) *corev1.ResourceRequirements { if !isResourceRequirementsNotSpecified(res) { return defaultRes } diff --git a/operator/pkg/serverconfig/configgen.go b/pkg/serverconfig/configgen.go similarity index 100% rename from operator/pkg/serverconfig/configgen.go rename to pkg/serverconfig/configgen.go diff --git a/operator/pkg/serverconfig/configgen_test.go b/pkg/serverconfig/configgen_test.go similarity index 100% rename from operator/pkg/serverconfig/configgen_test.go rename to pkg/serverconfig/configgen_test.go diff --git a/operator/pkg/utils/crypto.go b/pkg/utils/crypto.go similarity index 100% rename from operator/pkg/utils/crypto.go rename to pkg/utils/crypto.go index aa2bce80..bbd80aab 100644 --- a/operator/pkg/utils/crypto.go +++ b/pkg/utils/crypto.go @@ -15,7 +15,6 @@ import ( "time" ) - func setupKey() (*big.Int, time.Time, *rsa.PrivateKey, string, time.Time, error) { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) var serialNumber *big.Int @@ -105,6 +104,7 @@ func GenerateJKS(ca *corev1.Secret, podname, dcname string) (jksblob []byte, err } var derBytes []byte ca_cert_bytes, ca_certificate, ca_key, err := prepare_ca(ca) + if derBytes, err = x509.CreateCertificate(rand.Reader, &newCert, ca_certificate, &priv.PublicKey, ca_key); err == nil { asn1_bytes, err := rsa2pkcs8(priv) buffer := bytes.NewBufferString("") diff --git a/operator/pkg/utils/crypto_test.go b/pkg/utils/crypto_test.go similarity index 100% rename from operator/pkg/utils/crypto_test.go rename to pkg/utils/crypto_test.go diff --git a/operator/pkg/utils/hash_annotation.go b/pkg/utils/hash_annotation.go similarity index 100% rename from operator/pkg/utils/hash_annotation.go rename to pkg/utils/hash_annotation.go diff --git a/operator/pkg/utils/hash_annotation_test.go b/pkg/utils/hash_annotation_test.go similarity index 99% rename from operator/pkg/utils/hash_annotation_test.go rename to pkg/utils/hash_annotation_test.go index 6e60407f..44602c93 100644 --- a/operator/pkg/utils/hash_annotation_test.go +++ b/pkg/utils/hash_annotation_test.go @@ -1,11 +1,10 @@ package utils import ( - "testing" appsv1 "k8s.io/api/apps/v1" + "testing" ) - func Test_deepHashString(t *testing.T) { t.Run("test hash behavior", func(t *testing.T) { @@ -40,4 +39,4 @@ func Test_deepHashString(t *testing.T) { t.Errorf("deepHash should have produced the same hash %s %s", hash4, hash5) } }) -} \ No newline at end of file +} diff --git a/operator/pkg/utils/k8s_utils.go b/pkg/utils/k8s_utils.go similarity index 50% rename from operator/pkg/utils/k8s_utils.go rename to pkg/utils/k8s_utils.go index 9f095cb2..d4c676af 100644 --- a/operator/pkg/utils/k8s_utils.go +++ b/pkg/utils/k8s_utils.go @@ -1,8 +1,15 @@ package utils import ( + "fmt" + "io/ioutil" + "os" + "strings" + corev1 "k8s.io/api/core/v1" - volumeutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + logf "sigs.k8s.io/controller-runtime/pkg/log" ) // @@ -78,17 +85,16 @@ func FilterNodesWithTaintKeyValueEffect(nodes []*corev1.Node, taintKey, value st }) } - // -// k8s Pod helper functions +// k8s Pod helper functions // func IsPodUnschedulable(pod *corev1.Pod) bool { for _, condition := range pod.Status.Conditions { - if condition.Reason == corev1.PodReasonUnschedulable && + if condition.Reason == corev1.PodReasonUnschedulable && condition.Type == corev1.PodScheduled && condition.Status == corev1.ConditionFalse { - return true - } + return true + } } return false } @@ -110,7 +116,7 @@ func GetPodNodeNameSet(pods []*corev1.Pod) StringSet { return names } -func FilterPodsWithFn(pods []*corev1.Pod, fn func(*corev1.Pod)bool) []*corev1.Pod { +func FilterPodsWithFn(pods []*corev1.Pod, fn func(*corev1.Pod) bool) []*corev1.Pod { result := []*corev1.Pod{} for _, pod := range pods { if fn(pod) { @@ -166,6 +172,108 @@ func GetPVCSelectedNodeName(pvc *corev1.PersistentVolumeClaim) string { if annos == nil { annos = map[string]string{} } - pvcNode := annos[volumeutil.AnnSelectedNode] + pvcNode := annos["volume.kubernetes.io/selected-node"] return pvcNode } + +// +// Migrated from operator-sdk, these are internal in newer versions +// + +// ForceRunModeEnv indicates if the operator should be forced to run in either local +// or cluster mode (currently only used for local mode) +var ForceRunModeEnv = "OSDK_FORCE_RUN_MODE" + +type RunModeType string + +const ( + LocalRunMode RunModeType = "local" + ClusterRunMode RunModeType = "cluster" +) + +var log = logf.Log.WithName("k8sutil") + +const ( + // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE + // which is the namespace where the watch activity happens. + // this value is empty if the operator is running with clusterScope. + WatchNamespaceEnvVar = "WATCH_NAMESPACE" +) + +// GetWatchNamespace returns the namespace the operator should be watching for changes +func GetWatchNamespace() (string, error) { + ns, found := os.LookupEnv(WatchNamespaceEnvVar) + if !found { + return "", fmt.Errorf("%s must be set", WatchNamespaceEnvVar) + } + return ns, nil +} + +// ErrNoNamespace indicates that a namespace could not be found for the current +// environment +var ErrNoNamespace = fmt.Errorf("namespace not found for current environment") + +// ErrRunLocal indicates that the operator is set to run in local mode (this error +// is returned by functions that only work on operators running in cluster mode) +var ErrRunLocal = fmt.Errorf("operator run mode forced to local") + +// GetOperatorNamespace returns the namespace the operator should be running in. +func GetOperatorNamespace() (string, error) { + if isRunModeLocal() { + return "", ErrRunLocal + } + nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + if err != nil { + if os.IsNotExist(err) { + return "", ErrNoNamespace + } + return "", err + } + ns := strings.TrimSpace(string(nsBytes)) + log.V(1).Info("Found namespace", "Namespace", ns) + return ns, nil +} + +func isRunModeLocal() bool { + return os.Getenv(ForceRunModeEnv) == string(LocalRunMode) +} + +// GetGVKsFromAddToScheme takes in the runtime scheme and filters out all generic apimachinery meta types. +// It returns just the GVK specific to this scheme. +func GetGVKsFromAddToScheme(addToSchemeFunc func(*runtime.Scheme) error) ([]schema.GroupVersionKind, error) { + s := runtime.NewScheme() + err := addToSchemeFunc(s) + if err != nil { + return nil, err + } + schemeAllKnownTypes := s.AllKnownTypes() + ownGVKs := []schema.GroupVersionKind{} + for gvk := range schemeAllKnownTypes { + if !isKubeMetaKind(gvk.Kind) { + ownGVKs = append(ownGVKs, gvk) + } + } + + return ownGVKs, nil +} + +func isKubeMetaKind(kind string) bool { + if strings.HasSuffix(kind, "List") || + kind == "PatchOptions" || + kind == "GetOptions" || + kind == "DeleteOptions" || + kind == "ExportOptions" || + kind == "APIVersions" || + kind == "APIGroupList" || + kind == "APIResourceList" || + kind == "UpdateOptions" || + kind == "CreateOptions" || + kind == "Status" || + kind == "WatchEvent" || + kind == "ListOptions" || + kind == "APIGroup" { + return true + } + + return false +} diff --git a/operator/pkg/utils/utilities.go b/pkg/utils/utilities.go similarity index 99% rename from operator/pkg/utils/utilities.go rename to pkg/utils/utilities.go index 6344618e..811c357a 100644 --- a/operator/pkg/utils/utilities.go +++ b/pkg/utils/utilities.go @@ -4,10 +4,10 @@ package utils import ( + "math" "os" - "strings" "reflect" - "math" + "strings" ) func IsPSPEnabled() bool { @@ -19,7 +19,7 @@ func RangeInt(min, max, step int) []int { size := int(math.Ceil(float64((max - min)) / float64(step))) l := make([]int, size) for i := 0; i < size; i++ { - l[i] = min + i * step + l[i] = min + i*step } return l } @@ -128,4 +128,4 @@ func AppendValuesToStringArrayIfNotPresent(a []string, values ...string) []strin } } return a -} \ No newline at end of file +} diff --git a/operator/pkg/utils/utilities_test.go b/pkg/utils/utilities_test.go similarity index 92% rename from operator/pkg/utils/utilities_test.go rename to pkg/utils/utilities_test.go index 3b45b343..abced352 100644 --- a/operator/pkg/utils/utilities_test.go +++ b/pkg/utils/utilities_test.go @@ -26,35 +26,35 @@ func Test_ElementsMatch(t *testing.T) { var bNil []int = nil assert.True(t, ElementsMatch( - []foo{{1,2}, {3,4}, {5,6}}, - []foo{{1,2}, {3,4}, {5,6}})) + []foo{{1, 2}, {3, 4}, {5, 6}}, + []foo{{1, 2}, {3, 4}, {5, 6}})) assert.True(t, ElementsMatch( - []foo{{1,2}, {3,4}, {5,6}}, - []foo{{5,6}, {1,2}, {3,4}})) + []foo{{1, 2}, {3, 4}, {5, 6}}, + []foo{{5, 6}, {1, 2}, {3, 4}})) assert.True(t, ElementsMatch( aNil, bNil)) assert.False(t, ElementsMatch( - []foo{{1,2}, {3,4}, {5,6}}, - []foo{{5,6}, {1,2}})) + []foo{{1, 2}, {3, 4}, {5, 6}}, + []foo{{5, 6}, {1, 2}})) assert.False(t, ElementsMatch( - []foo{{1,2}, {1,2}}, - []foo{{5,6}, {1,2}})) + []foo{{1, 2}, {1, 2}}, + []foo{{5, 6}, {1, 2}})) assert.False(t, ElementsMatch( - []foo{{5,6}, {1,2}}, - []foo{{1,2}, {1,2}})) + []foo{{5, 6}, {1, 2}}, + []foo{{1, 2}, {1, 2}})) assert.False(t, ElementsMatch( aNil, - []foo{{1,2}, {1,2}})) + []foo{{1, 2}, {1, 2}})) assert.False(t, ElementsMatch( - []foo{{5,6}, {1,2}}, + []foo{{5, 6}, {1, 2}}, bNil)) } @@ -170,21 +170,20 @@ func Test_mergeMap(t *testing.T) { }, sources: []map[string]string{ { - "foo": "qux", + "foo": "qux", "waldo": "fred", - }, { - "foo": "quux", + "foo": "quux", "quuz": "flob", }, }, }, want: map[string]string{ - "foo": "quux", - "baz": "foobar", + "foo": "quux", + "baz": "foobar", "waldo": "fred", - "quuz": "flob", + "quuz": "flob", }, }, } diff --git a/tests/add_racks/add_racks_suite_test.go b/tests/add_racks/add_racks_suite_test.go index b43c1446..9e90b3e3 100644 --- a/tests/add_racks/add_racks_suite_test.go +++ b/tests/add_racks/add_racks_suite_test.go @@ -12,17 +12,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Add racks" - namespace = "test-add-racks" - dcName = "dc2" - dcYaml = "../testdata/default-single-rack-single-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Add racks" + namespace = "test-add-racks" + dcName = "dc2" + dcYaml = "../testdata/default-single-rack-single-node-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +31,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +41,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("racks can be added if the size is increased accordingly", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/additional_seeds/additional_seeds_suite_test.go b/tests/additional_seeds/additional_seeds_suite_test.go index 64200f30..ea06dcc6 100644 --- a/tests/additional_seeds/additional_seeds_suite_test.go +++ b/tests/additional_seeds/additional_seeds_suite_test.go @@ -17,6 +17,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -24,7 +25,6 @@ var ( namespace = "test-additional-seeds" dcName = "dc1" dcYaml = "../testdata/additional-seeds-two-rack-four-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) additionalSeedServiceResource = "services/cluster1-dc1-additional-seed-service" @@ -39,6 +39,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -272,13 +273,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 2 racks/4 nodes" diff --git a/tests/additional_serviceoptions/additional_service_opts_suite_test.go b/tests/additional_serviceoptions/additional_service_opts_suite_test.go index f4b8b956..c509f339 100644 --- a/tests/additional_serviceoptions/additional_service_opts_suite_test.go +++ b/tests/additional_serviceoptions/additional_service_opts_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can create a datacenter where services have additional properties", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/1 node" + step := "creating a datacenter resource with 1 rack/1 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/additional_volumes/additional_volumes_suite_test.go b/tests/additional_volumes/additional_volumes_suite_test.go index 39a534e7..f59f1bbf 100644 --- a/tests/additional_volumes/additional_volumes_suite_test.go +++ b/tests/additional_volumes/additional_volumes_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,16 +42,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can create a datacenter where nodes use additional volumes", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/1 node" + step := "creating a datacenter resource with 1 rack/1 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/bring_up_graph/bring_up_graph_suite_test.go b/tests/bring_up_graph/bring_up_graph_suite_test.go index 1a048272..a50c69b4 100644 --- a/tests/bring_up_graph/bring_up_graph_suite_test.go +++ b/tests/bring_up_graph/bring_up_graph_suite_test.go @@ -12,16 +12,15 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Bring Up Graph" - namespace = "test-bring-up-graph" - dcName = "dc1" - dcYaml = "../testdata/graph-dc.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Bring Up Graph" + namespace = "test-bring-up-graph" + dcName = "dc1" + dcYaml = "../testdata/graph-dc.yaml" + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -33,6 +32,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +42,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator bring up a graph node", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with graph" + step := "creating a datacenter resource with graph" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/bring_up_solr/bring_up_solr_suite_test.go b/tests/bring_up_solr/bring_up_solr_suite_test.go index 8dd1a5df..7dac53b1 100644 --- a/tests/bring_up_solr/bring_up_solr_suite_test.go +++ b/tests/bring_up_solr/bring_up_solr_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator bring up a solr node", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with solr" + step := "creating a datacenter resource with solr" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/bring_up_spark/bring_up_spark_suite_test.go b/tests/bring_up_spark/bring_up_spark_suite_test.go index 78b4ce23..68130412 100644 --- a/tests/bring_up_spark/bring_up_spark_suite_test.go +++ b/tests/bring_up_spark/bring_up_spark_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator bring up a spark node", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with spark" + step := "creating a datacenter resource with spark" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/canary_upgrade/canary_upgrade_test.go b/tests/canary_upgrade/canary_upgrade_test.go index ef0f96de..7ec0f661 100644 --- a/tests/canary_upgrade/canary_upgrade_test.go +++ b/tests/canary_upgrade/canary_upgrade_test.go @@ -14,18 +14,18 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" - "github.com/k8ssandra/cass-operator/operator/pkg/images" + "github.com/k8ssandra/cass-operator/pkg/images" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "OSS test canary upgrade" - namespace = "test-canary-upgrade" - dcName = "dc1" - dcYaml = "../testdata/oss-upgrade-dc.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "OSS test canary upgrade" + namespace = "test-canary-upgrade" + dcName = "dc1" + dcYaml = "../testdata/oss-upgrade-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -34,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -43,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can perform a canary upgrade", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter" + step := "creating a datacenter" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/cluster_wide_install/cluster_wide_install_suite_test.go b/tests/cluster_wide_install/cluster_wide_install_suite_test.go index 8f409f96..2f9b98cb 100644 --- a/tests/cluster_wide_install/cluster_wide_install_suite_test.go +++ b/tests/cluster_wide_install/cluster_wide_install_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) // Note: the cass-operator itself will be installed in the test-cluster-wide-install namespace @@ -42,6 +43,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(opNamespace) }) RegisterFailHandler(Fail) @@ -51,15 +53,20 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can monitor multiple namespaces", func() { + // Workaround for kustomize reorder bug By("creating a namespace for the cass-operator") err := kubectl.CreateNamespace(opNamespace).ExecV() Expect(err).ToNot(HaveOccurred()) - var overrides = map[string]string{ - "clusterWideInstall": "true", - } - chartPath := "../../charts/cass-operator-chart" - ginkgo_util.HelmInstallWithOverrides(chartPath, ns.Namespace, overrides) + By("deploy cass-operator with kustomize") + err = kustomize.DeployDir(opNamespace, "cluster_wide_install") + Expect(err).ToNot(HaveOccurred()) + + // var overrides = map[string]string{ + // "clusterWideInstall": "true", + // } + // chartPath := "../../charts/cass-operator-chart" + // ginkgo_util.HelmInstallWithOverrides(chartPath, ns.Namespace, overrides) ns.WaitForOperatorReady() diff --git a/tests/cluster_wide_install/kustomization.yaml b/tests/cluster_wide_install/kustomization.yaml new file mode 100644 index 00000000..2a2e35eb --- /dev/null +++ b/tests/cluster_wide_install/kustomization.yaml @@ -0,0 +1,54 @@ +# Set WATCH_NAMESPACE to "" in the deployment to provide cluster-wide install +# Modify Role to ClusteRole +# Modify RoleBinding to ClusterRoleBinding and kind to ClusterRole +namespace: test-cluster-wide-install + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +patchesJson6902: +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: Role + name: manager-role + patch: |- + - op: replace + path: /kind + value: ClusterRole + - op: replace + path: /metadata/name + value: cass-operator-manager-crrole +- target: + group: rbac.authorization.k8s.io + version: v1 + kind: RoleBinding + name: manager-rolebinding + patch: |- + - op: replace + path: /kind + value: ClusterRoleBinding + - op: replace + path: /roleRef/kind + value: ClusterRole + - op: replace + path: /roleRef/name + value: cass-operator-manager-crrole + - op: replace + path: /subjects/0/name + value: cass-operator-controller-manager + - op: add + path: /subjects/0/namespace + value: test-cluster-wide-install +- target: + group: apps + version: v1 + name: controller-manager + kind: Deployment + patch: |- + - op: remove + path: /spec/template/spec/containers/0/env/0/valueFrom + - op: add + path: /spec/template/spec/containers/0/env/0/value + value: "" +resources: +- ../../config/default diff --git a/tests/config_change/config_change_suite_test.go b/tests/config_change/config_change_suite_test.go index 3ffb7242..238632d7 100644 --- a/tests/config_change/config_change_suite_test.go +++ b/tests/config_change/config_change_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can scale up a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/config_change_condition/config_change_condition_suite_test.go b/tests/config_change_condition/config_change_condition_suite_test.go index 5b2669d3..06b587d4 100644 --- a/tests/config_change_condition/config_change_condition_suite_test.go +++ b/tests/config_change_condition/config_change_condition_suite_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,16 +42,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the Updating condition is set for config updates", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 racks/2 nodes" + step := "creating a datacenter resource with 1 racks/2 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/config_secret/config_secret_suite_test.go b/tests/config_secret/config_secret_suite_test.go index 1920784b..4576c4fc 100644 --- a/tests/config_secret/config_secret_suite_test.go +++ b/tests/config_secret/config_secret_suite_test.go @@ -2,10 +2,12 @@ package config_secret import ( "fmt" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - corev1 "k8s.io/api/core/v1" "testing" + api "github.com/k8ssandra/cass-operator/api/v1beta1" + "github.com/k8ssandra/cass-operator/tests/kustomize" + corev1 "k8s.io/api/core/v1" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -14,17 +16,14 @@ import ( ) var ( - testName = "Config change rollout with config secret" - namespace = "test-config-change-rollout-secret" - dcName = "dc1" - dcYaml = "../testdata/cluster-with-config-secret.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - secretName = "test-config" - secretYaml = "../testdata/test-config-secret.yaml" + testName = "Config change rollout with config secret" + namespace = "test-config-change-rollout-secret" + dcName = "dc1" + dcYaml = "../testdata/cluster-with-config-secret.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + secretYaml = "../testdata/test-config-secret.yaml" updatedSecretYaml = "../testdata/updated-test-config-secret.yaml" - secretResource = fmt.Sprintf("secret/%s", secretName) - ns = ginkgo_util.NewWrapper(testName, namespace) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -36,6 +35,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -45,12 +45,10 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("cassandra configuration can be applied with a secret", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - By("setting up cass-operator resources via helm chart") - ns.HelmInstall("../../charts/cass-operator-chart") ns.WaitForOperatorReady() step := "creating config secret" @@ -66,7 +64,7 @@ var _ = Describe(testName, func() { k = kubectl.ApplyFiles(updatedSecretYaml) ns.ExecAndLog(step, k) - ns.WaitForDatacenterOperatorProgress(dcName, "Updating", 30) + ns.WaitForDatacenterOperatorProgress(dcName, "Updating", 60) ns.WaitForDatacenterConditionWithTimeout(dcName, string(api.DatacenterReady), string(corev1.ConditionTrue), 450) step = "checking cassandra.yaml" diff --git a/tests/delete_node_lost_readiness/delete_node_lost_readiness_suite_test.go b/tests/delete_node_lost_readiness/delete_node_lost_readiness_suite_test.go index 2d8a2621..36bc2623 100644 --- a/tests/delete_node_lost_readiness/delete_node_lost_readiness_suite_test.go +++ b/tests/delete_node_lost_readiness/delete_node_lost_readiness_suite_test.go @@ -12,17 +12,16 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Delete Node that lost readiness and isn't becoming ready" - namespace = "test-delete-node-lost-readiness" - dcName = "dc1" - dcYaml = "../testdata/default-three-rack-three-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Delete Node that lost readiness and isn't becoming ready" + namespace = "test-delete-node-lost-readiness" + dcName = "dc1" + dcYaml = "../testdata/default-three-rack-three-node-dc.yaml" + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +30,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,16 +40,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can detect a node that lost readiness and is hanging, and delete the pod", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/delete_node_terminated_container/delete_node_terminate_container_suite_test.go b/tests/delete_node_terminated_container/delete_node_terminate_container_suite_test.go index da67a870..f275efda 100644 --- a/tests/delete_node_terminated_container/delete_node_terminate_container_suite_test.go +++ b/tests/delete_node_terminated_container/delete_node_terminate_container_suite_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can detect a node where Cassandra container terminated, restarted, and is hanging, and delete the pod", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/1 node" + step := "creating a datacenter resource with 1 rack/1 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/helm_chart_imagepullsecrets/helm_chart_imagepullsecrets_suite_test.go b/tests/helm_chart_imagepullsecrets/helm_chart_imagepullsecrets_suite_test.go deleted file mode 100644 index ca55e04f..00000000 --- a/tests/helm_chart_imagepullsecrets/helm_chart_imagepullsecrets_suite_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package helm_chart_imagepullsecrets - -import ( - "fmt" - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" - "github.com/k8ssandra/cass-operator/mage/kubectl" -) - -var ( - testName = "Helm Chart imagePullSecrets" - opNamespace = "test-helm-chart-imagepullsecrets" - dc1Name = "dc2" - dc1Yaml = "../testdata/default-single-rack-single-node-dc.yaml" - ns = ginkgo_util.NewWrapper(testName, opNamespace) -) - -func TestLifecycle(t *testing.T) { - // Only run this test if docker creds are defined - if kubectl.DockerCredentialsDefined() { - AfterSuite(func() { - logPath := fmt.Sprintf("%s/aftersuite", ns.LogDir) - err := kubectl.DumpAllLogs(logPath).ExecV() - if err != nil { - fmt.Printf("\n\tError during dumping logs: %s\n\n", err.Error()) - } - fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) - ns.Terminate() - }) - - RegisterFailHandler(Fail) - RunSpecs(t, testName) - } -} - -var _ = Describe(testName, func() { - Context("when in a new cluster", func() { - Specify("the operator can be correctly installed with imagePullSecrets", func() { - - By("creating a namespace for the cass-operator") - err := kubectl.CreateNamespace(opNamespace).ExecV() - Expect(err).ToNot(HaveOccurred()) - - step := "setting up cass-operator resources via helm chart" - - ns.HelmInstall("../../charts/cass-operator-chart") - - ns.WaitForOperatorReady() - - // Create a small cass cluster to verify cass-operator is functional - step = "creating first datacenter resource" - k := kubectl.ApplyFiles(dc1Yaml) - ns.ExecAndLog(step, k) - - ns.WaitForDatacenterReady(dc1Name) - }) - }) -}) diff --git a/tests/host_network/host_network_suite_test.go b/tests/host_network/host_network_suite_test.go index 3f626967..a5506ae0 100644 --- a/tests/host_network/host_network_suite_test.go +++ b/tests/host_network/host_network_suite_test.go @@ -12,16 +12,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Host Network" - namespace = "test-host-network" - dcName = "dc1" - dcYaml = "../testdata/host-network-dc.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Host Network" + namespace = "test-host-network" + dcName = "dc1" + dcYaml = "../testdata/host-network-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -43,13 +45,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 3 racks/3 nodes" diff --git a/tests/internode-encryption-generated/internode_secret_generated_test.go b/tests/internode-encryption-generated/internode_secret_generated_test.go index ab0eb06f..b86ede4e 100644 --- a/tests/internode-encryption-generated/internode_secret_generated_test.go +++ b/tests/internode-encryption-generated/internode_secret_generated_test.go @@ -7,12 +7,12 @@ import ( "fmt" "testing" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -35,6 +35,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -47,13 +48,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 1 racks/2 nodes" diff --git a/tests/kustomize/deploy.go b/tests/kustomize/deploy.go new file mode 100644 index 00000000..0d088973 --- /dev/null +++ b/tests/kustomize/deploy.go @@ -0,0 +1,52 @@ +package kustomize + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "path/filepath" +) + +func Deploy(namespace string) error { + return DeployDir(namespace, "kustomize") +} + +func Undeploy(namespace string) error { + return UndeployDir(namespace, "kustomize") +} + +func DeployDir(namespace, testDir string) error { + return runMake(namespace, "deploy-test", testDir) +} + +func UndeployDir(namespace, testDir string) error { + return runMake(namespace, "undeploy-test", testDir) +} + +func runMake(namespace, command, dir string) error { + ns := fmt.Sprintf("NAMESPACE=%s", namespace) + kustDir := fmt.Sprintf("TEST_DIR=%s", dir) + deploy := exec.Command("make", ns, command, kustDir) + var out bytes.Buffer + deploy.Stdout = &out + + path, err := os.Getwd() + if err != nil { + return err + } + + makeDir, err := os.Open(filepath.Join(path, "..", "..")) + if err != nil { + return err + } + + deploy.Dir = makeDir.Name() + + err = deploy.Run() + if err != nil { + return err + } + + return nil +} diff --git a/tests/kustomize/kustomization.yaml b/tests/kustomize/kustomization.yaml new file mode 100644 index 00000000..5ea9e6ca --- /dev/null +++ b/tests/kustomize/kustomization.yaml @@ -0,0 +1,7 @@ +# This is the default kustomize template for tests. +namespace: kustomize + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../config/default diff --git a/tests/multi_cluster_management/multi_cluster_management_suite_test.go b/tests/multi_cluster_management/multi_cluster_management_suite_test.go index 74af63db..e26493fd 100644 --- a/tests/multi_cluster_management/multi_cluster_management_suite_test.go +++ b/tests/multi_cluster_management/multi_cluster_management_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -37,6 +38,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -46,14 +48,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator manages multiple clusters in the same namespace", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/no_infinite_reconcile/no_infinite_reconcile_suite_test.go b/tests/no_infinite_reconcile/no_infinite_reconcile_suite_test.go index 18eb77d1..401e6c6b 100644 --- a/tests/no_infinite_reconcile/no_infinite_reconcile_suite_test.go +++ b/tests/no_infinite_reconcile/no_infinite_reconcile_suite_test.go @@ -12,16 +12,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "No Infinite Reconcile" - namespace = "test-no-infinite-reconcile" - dcName = "dc1" - dcYaml = "../testdata/default-three-rack-three-node-dc.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "No Infinite Reconcile" + namespace = "test-no-infinite-reconcile" + dcName = "dc1" + dcYaml = "../testdata/default-three-rack-three-node-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -43,13 +45,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 3 racks/3 nodes" diff --git a/tests/node_replace/node_replace_suite_test.go b/tests/node_replace/node_replace_suite_test.go index 9793179f..dc7dc7c9 100644 --- a/tests/node_replace/node_replace_suite_test.go +++ b/tests/node_replace/node_replace_suite_test.go @@ -17,6 +17,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -26,9 +27,7 @@ var ( podNames = []string{"cluster1-dc1-r1-sts-0", "cluster1-dc1-r2-sts-0", "cluster1-dc1-r3-sts-0"} podNameToReplace = podNames[2] dcYaml = "../testdata/default-three-rack-three-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) ns = ginkgo_util.NewWrapper(testName, namespace) ) @@ -39,6 +38,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -102,13 +102,10 @@ var _ = Describe(testName, func() { var json string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 3 racks/3 nodes" diff --git a/tests/nodeport_service/nodeport_service_suite_test.go b/tests/nodeport_service/nodeport_service_suite_test.go index b637559a..69cafac5 100644 --- a/tests/nodeport_service/nodeport_service_suite_test.go +++ b/tests/nodeport_service/nodeport_service_suite_test.go @@ -15,6 +15,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -34,6 +35,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -81,13 +83,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with a nodeport service" diff --git a/tests/oss_test_all_the_things/oss_test_all_the_things_suite_test.go b/tests/oss_test_all_the_things/oss_test_all_the_things_suite_test.go index 290c48da..8bf85cb7 100644 --- a/tests/oss_test_all_the_things/oss_test_all_the_things_suite_test.go +++ b/tests/oss_test_all_the_things/oss_test_all_the_things_suite_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can scale up, stop, resume, and terminate a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/podspec_simple/podspec_simple_suite_test.go b/tests/podspec_simple/podspec_simple_suite_test.go index 99a1da97..f41e1674 100644 --- a/tests/podspec_simple/podspec_simple_suite_test.go +++ b/tests/podspec_simple/podspec_simple_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +42,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator supports user defined podspectemplate", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/psp_emm/psp_emm_suite_test.go b/tests/psp_emm/psp_emm_suite_test.go index f109d2f7..fbb48eb3 100644 --- a/tests/psp_emm/psp_emm_suite_test.go +++ b/tests/psp_emm/psp_emm_suite_test.go @@ -13,6 +13,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -38,6 +39,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(opNamespace) }) RegisterFailHandler(Fail) @@ -47,16 +49,16 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("when a node has an evacuate data taint, deletes pods and PVCs on that node", func() { - By("creating a namespace for the cass-operator") - err := kubectl.CreateNamespace(opNamespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(opNamespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") + // step := "setting up cass-operator resources via helm chart" + // ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") ns.WaitForOperatorReady() - step = "creating first datacenter resource" + step := "creating first datacenter resource" k := kubectl.ApplyFiles(dc1Yaml) ns.ExecAndLog(step, k) diff --git a/tests/psp_health/psp_health_suite_test.go b/tests/psp_health/psp_health_suite_test.go index e7b61f13..4bddab63 100644 --- a/tests/psp_health/psp_health_suite_test.go +++ b/tests/psp_health/psp_health_suite_test.go @@ -12,17 +12,18 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" "gopkg.in/yaml.v2" ) var ( - testName = "PSP Health" - namespace = "test-psp-health" - dcName = "dc2" - dcYaml = "../testdata/default-single-rack-2-node-dc.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "PSP Health" + namespace = "test-psp-health" + dcName = "dc2" + dcYaml = "../testdata/default-single-rack-2-node-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -51,7 +53,7 @@ func getPspInstanceHealth() (map[interface{}]interface{}, error) { return config, nil } -func getPath(obj interface{}, path... interface{}) interface{} { +func getPath(obj interface{}, path ...interface{}) interface{} { if len(path) == 0 { return obj } @@ -65,23 +67,27 @@ func getPath(obj interface{}, path... interface{}) interface{} { if ok { return getPath(l[path[0].(int)], path[1:]...) } - + return nil } var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator syncs PSP health status information", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") + // By("creating a namespace") + // err := kubectl.CreateNamespace(namespace).ExecV() + // Expect(err).ToNot(HaveOccurred()) + + // step := "setting up cass-operator resources via helm chart" + // ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/2 node" + step := "creating a datacenter resource with 1 rack/2 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) @@ -106,16 +112,15 @@ var _ = Describe(testName, func() { Expect( getPath(config, "status", "instancehealth", 0, "instance"), - ).To(Equal(dcName), "Expected instance name to be %s", dcName) + ).To(Equal(dcName), "Expected instance name to be %s", dcName) Expect( getPath(config, "status", "instancehealth", 0, "namespace"), - ).To(Equal(namespace), "Expected instance namespace to be %s", namespace) + ).To(Equal(namespace), "Expected instance namespace to be %s", namespace) Expect( getPath(config, "status", "instancehealth", 0, "health"), - ).To(Equal("green"), "Expected instance health value to be green") - + ).To(Equal("green"), "Expected instance health value to be green") // Check some labels and annotations // diff --git a/tests/psp_pvc_annotation/psp_pvc_annotation_suite_test.go b/tests/psp_pvc_annotation/psp_pvc_annotation_suite_test.go index 3e2f88fb..e54d228f 100644 --- a/tests/psp_pvc_annotation/psp_pvc_annotation_suite_test.go +++ b/tests/psp_pvc_annotation/psp_pvc_annotation_suite_test.go @@ -13,6 +13,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -38,6 +39,7 @@ func TestLifecycle(t *testing.T) { } fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(opNamespace) }) RegisterFailHandler(Fail) @@ -47,17 +49,16 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can respond to psp annotations on PVCs", func() { - - By("creating a namespace for the cass-operator") - err := kubectl.CreateNamespace(opNamespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(opNamespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") + // step := "setting up cass-operator resources via helm chart" + // ns.HelmInstallWithPSPEnabled("../../charts/cass-operator-chart") ns.WaitForOperatorReady() - step = "creating first datacenter resource" + step := "creating first datacenter resource" k := kubectl.ApplyFiles(dc1Yaml) ns.ExecAndLog(step, k) diff --git a/tests/rolling_restart/rolling_restart_suite_test.go b/tests/rolling_restart/rolling_restart_suite_test.go index 491873d8..1a51495e 100644 --- a/tests/rolling_restart/rolling_restart_suite_test.go +++ b/tests/rolling_restart/rolling_restart_suite_test.go @@ -14,16 +14,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Rolling Restart" - namespace = "test-rolling-restart" - dcName = "dc2" - dcYaml = "../testdata/default-single-rack-2-node-dc.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Rolling Restart" + namespace = "test-rolling-restart" + dcName = "dc2" + dcYaml = "../testdata/default-single-rack-2-node-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -32,6 +33,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -41,16 +43,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can perform a rolling restart", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/2 node" + step := "creating a datacenter resource with 1 rack/2 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/scale_down/scale_down_suite_test.go b/tests/scale_down/scale_down_suite_test.go index f954e52c..cd2d2ace 100644 --- a/tests/scale_down/scale_down_suite_test.go +++ b/tests/scale_down/scale_down_suite_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -32,6 +33,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -41,16 +43,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("a datacenter can be scaled down", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/4 nodes" + step := "creating a datacenter resource with 3 racks/4 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) @@ -71,7 +70,7 @@ var _ = Describe(testName, func() { k = kubectl.Get("pod"). WithLabel("cassandra.datastax.com/node-state=Decommissioning"). FormatOutput(json) - ns.WaitForOutputAndLog(step, k, podWithDecommissionedNode, 30) + ns.WaitForOutputAndLog(step, k, podWithDecommissionedNode, 90) ns.WaitForDatacenterOperatorProgress(dcName, "Updating", 30) ns.WaitForDatacenterCondition(dcName, "ScalingDown", string(corev1.ConditionFalse)) diff --git a/tests/scale_down_not_enough_space/scale_down_not_enough_space_suite_test.go b/tests/scale_down_not_enough_space/scale_down_not_enough_space_suite_test.go index 537aa3fe..b898edd9 100644 --- a/tests/scale_down_not_enough_space/scale_down_not_enough_space_suite_test.go +++ b/tests/scale_down_not_enough_space/scale_down_not_enough_space_suite_test.go @@ -13,9 +13,10 @@ import ( corev1 "k8s.io/api/core/v1" + "github.com/google/uuid" ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" - "github.com/google/uuid" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -34,6 +35,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -43,16 +45,12 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("scaling down fails when there is not enough space to absorb data", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/4 nodes" + step := "creating a datacenter resource with 3 racks/4 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/scale_down_unbalanced_racks/scale_down_unbalanced_racks_suite_test.go b/tests/scale_down_unbalanced_racks/scale_down_unbalanced_racks_suite_test.go index 154c3574..daae2639 100644 --- a/tests/scale_down_unbalanced_racks/scale_down_unbalanced_racks_suite_test.go +++ b/tests/scale_down_unbalanced_racks/scale_down_unbalanced_racks_suite_test.go @@ -15,6 +15,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("a datacenter can be scaled down with unbalanced racks", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 2 racks/4 nodes" + step := "creating a datacenter resource with 2 racks/4 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) @@ -78,7 +77,7 @@ var _ = Describe(testName, func() { k = kubectl.Get("pod"). WithFlag("field-selector", fmt.Sprintf("metadata.name=%s", extraPod)). FormatOutput(json) - ns.WaitForOutputAndLog(step, k, "true", 360) + ns.WaitForOutputAndLog(step, k, "true", 600) // The rack with an extra node should get a decommission request // first, despite being the last rack and the first rack also needing @@ -102,7 +101,7 @@ var _ = Describe(testName, func() { ensurePodGetsDecommissionedNext("cluster1-dc1-r1-sts-1", expectedRemainingPods) ns.WaitForDatacenterCondition(dcName, "ScalingDown", string(corev1.ConditionFalse)) - ns.WaitForDatacenterOperatorProgress(dcName, "Ready", 120) + ns.WaitForDatacenterOperatorProgress(dcName, "Ready", 180) step = "deleting the dc" k = kubectl.DeleteFromFiles(dcYaml) diff --git a/tests/scale_up/scale_up_suite_test.go b/tests/scale_up/scale_up_suite_test.go index eb47d89c..39aab28c 100644 --- a/tests/scale_up/scale_up_suite_test.go +++ b/tests/scale_up/scale_up_suite_test.go @@ -14,17 +14,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Scale up" - namespace = "test-scale-up" - dcName = "dc2" - dcYaml = "../testdata/default-single-rack-single-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Scale up" + namespace = "test-scale-up" + dcName = "dc2" + dcYaml = "../testdata/default-single-rack-single-node-dc.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -33,6 +33,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +43,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can scale up a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 1 rack/1 node" + step := "creating a datacenter resource with 1 rack/1 node" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/scale_up_stop_resume/scale_up_park_unpark_suite_test.go b/tests/scale_up_stop_resume/scale_up_park_unpark_suite_test.go index 551848bf..f657a7ce 100644 --- a/tests/scale_up_stop_resume/scale_up_park_unpark_suite_test.go +++ b/tests/scale_up_stop_resume/scale_up_park_unpark_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,16 +42,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can scale up, stop, resume, and terminate a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/seed_selection/seed_selection_suite_test.go b/tests/seed_selection/seed_selection_suite_test.go index 36a8cee9..f50527af 100644 --- a/tests/seed_selection/seed_selection_suite_test.go +++ b/tests/seed_selection/seed_selection_suite_test.go @@ -17,6 +17,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -37,6 +38,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -257,13 +259,10 @@ var _ = Describe(testName, func() { var json string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 3 racks/3 nodes" diff --git a/tests/smoke_test_dse/smoke_test_dse_suite_test.go b/tests/smoke_test_dse/smoke_test_dse_suite_test.go index 75a4997d..1e141bbd 100644 --- a/tests/smoke_test_dse/smoke_test_dse_suite_test.go +++ b/tests/smoke_test_dse/smoke_test_dse_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +42,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can stand up a one node cluster", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/smoke_test_oss/smoke_test_oss_suite_test.go b/tests/smoke_test_oss/smoke_test_oss_suite_test.go index cf81271e..39e04940 100644 --- a/tests/smoke_test_oss/smoke_test_oss_suite_test.go +++ b/tests/smoke_test_oss/smoke_test_oss_suite_test.go @@ -12,17 +12,16 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "Smoke test of basic functionality for one-node OSS Cassandra cluster." - namespace = "test-smoke-test-oss" - dcName = "dc2" - dcYaml = "../testdata/smoke-test-oss.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "Smoke test of basic functionality for one-node OSS Cassandra cluster." + namespace = "test-smoke-test-oss" + dcName = "dc2" + dcYaml = "../testdata/smoke-test-oss.yaml" + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +30,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +40,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can stand up a one node cluster", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/stop_resume/park_unpark_suite_test.go b/tests/stop_resume/park_unpark_suite_test.go index 5978d166..3178a434 100644 --- a/tests/stop_resume/park_unpark_suite_test.go +++ b/tests/stop_resume/park_unpark_suite_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can stop, resume, and terminate a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) @@ -63,7 +62,7 @@ var _ = Describe(testName, func() { ns.ExecAndLog(step, k) // Ensure conditions set correctly for stopped - ns.WaitForDatacenterCondition(dcName, "Stopped", string(corev1.ConditionTrue)) + ns.WaitForDatacenterCondition(dcName, "Stopped", string(corev1.ConditionTrue)) ns.WaitForDatacenterCondition(dcName, "Ready", string(corev1.ConditionFalse)) step = "checking the spec size hasn't changed" diff --git a/tests/stop_resume_scale_up/park_unpark_scale_up_suite_test.go b/tests/stop_resume_scale_up/park_unpark_scale_up_suite_test.go index 6e59fde4..35d23b25 100644 --- a/tests/stop_resume_scale_up/park_unpark_scale_up_suite_test.go +++ b/tests/stop_resume_scale_up/park_unpark_scale_up_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,16 +42,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can stop, resume, scale up, and terminate a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/superuser-secret-generated/superuser_secret_generated_test.go b/tests/superuser-secret-generated/superuser_secret_generated_test.go index 168d1a52..09475574 100644 --- a/tests/superuser-secret-generated/superuser_secret_generated_test.go +++ b/tests/superuser-secret-generated/superuser_secret_generated_test.go @@ -14,6 +14,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -36,6 +37,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -49,13 +51,10 @@ var _ = Describe(testName, func() { var json string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "creating a datacenter resource with 1 racks/2 nodes" diff --git a/tests/superuser-secret-provided/superuser_secret_provided_test.go b/tests/superuser-secret-provided/superuser_secret_provided_test.go index 9ca75c18..8300fddd 100644 --- a/tests/superuser-secret-provided/superuser_secret_provided_test.go +++ b/tests/superuser-secret-provided/superuser_secret_provided_test.go @@ -13,6 +13,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -44,6 +45,7 @@ func TestLifecycle(t *testing.T) { fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -56,13 +58,10 @@ var _ = Describe(testName, func() { var step string var k kubectl.KCmd - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step = "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() step = "create superuser secret" @@ -72,7 +71,7 @@ var _ = Describe(testName, func() { step = "create user secret" k = kubectl.CreateSecretLiteral("bobby-secret", bobbyuserName, bobbyuserPass) ns.ExecAndLog(step, k) - + step = "creating a datacenter resource with 1 racks/2 nodes" k = kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) @@ -144,8 +143,8 @@ var _ = Describe(testName, func() { step = "check annotations and labels removed" k = kubectl.Get("secret", superuserSecretName).FormatOutput(json) output := ns.OutputAndLog(step, k) - Expect(output).ToNot(ContainSubstring(labelAnnoPrefix), - "Secret %s should no longer have annotations or labels namespaced with %s", + Expect(output).ToNot(ContainSubstring(labelAnnoPrefix), + "Secret %s should no longer have annotations or labels namespaced with %s", superuserSecretName, labelAnnoPrefix) }) }) diff --git a/tests/terminate/terminate_suite_test.go b/tests/terminate/terminate_suite_test.go index 555ad6dd..91f6585b 100644 --- a/tests/terminate/terminate_suite_test.go +++ b/tests/terminate/terminate_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +42,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator destroys resources after the datacenter is deleted", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/test_bad_config_and_fix/test_bad_config_and_fix_suite_test.go b/tests/test_bad_config_and_fix/test_bad_config_and_fix_suite_test.go index 224402f3..4cdfdfc5 100644 --- a/tests/test_bad_config_and_fix/test_bad_config_and_fix_suite_test.go +++ b/tests/test_bad_config_and_fix/test_bad_config_and_fix_suite_test.go @@ -15,6 +15,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -33,6 +34,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -42,16 +44,13 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can scale up, stop, resume, and terminate a datacenter", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() - step = "creating a datacenter resource with 3 racks/3 nodes" + step := "creating a datacenter resource with 3 racks/3 nodes" k := kubectl.ApplyFiles(dcYaml) ns.ExecAndLog(step, k) diff --git a/tests/test_mtls_mgmt_api/test_mtls_mgmt_api_suite_test.go b/tests/test_mtls_mgmt_api/test_mtls_mgmt_api_suite_test.go index 8660dafe..675f5813 100644 --- a/tests/test_mtls_mgmt_api/test_mtls_mgmt_api_suite_test.go +++ b/tests/test_mtls_mgmt_api/test_mtls_mgmt_api_suite_test.go @@ -12,17 +12,17 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( - testName = "test mtls protecting mgmt api" - namespace = "test-mtls-for-mgmt-api" - dcName = "dc1" - dcYaml = "../testdata/oss-one-node-dc-with-mtls.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) + testName = "test mtls protecting mgmt api" + namespace = "test-mtls-for-mgmt-api" + dcName = "dc1" + dcYaml = "../testdata/oss-one-node-dc-with-mtls.yaml" + dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) + dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) + ns = ginkgo_util.NewWrapper(testName, namespace) ) func TestLifecycle(t *testing.T) { @@ -31,6 +31,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,17 +41,14 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator can start, scale up, and terminate a datacenter where the mgmt api is behind mtls", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - ns.WaitForOperatorReady() // jam in secrets - step = "creating mtls secrets" + step := "creating mtls secrets" k := kubectl.ApplyFiles( "../testdata/mtls-certs-server.yaml", "../testdata/mtls-certs-client.yaml", diff --git a/tests/timeout_prestop_termination/timeout_prestop_termination_suite_test.go b/tests/timeout_prestop_termination/timeout_prestop_termination_suite_test.go index a873318e..642e6239 100644 --- a/tests/timeout_prestop_termination/timeout_prestop_termination_suite_test.go +++ b/tests/timeout_prestop_termination/timeout_prestop_termination_suite_test.go @@ -16,6 +16,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -35,6 +36,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -44,14 +46,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the operator times out cluster termination after 120 seconds", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tests/upgrade_operator/upgrade_operator_suite_test.go b/tests/upgrade_operator/upgrade_operator_suite_test.go index b634fc95..d1bdc392 100644 --- a/tests/upgrade_operator/upgrade_operator_suite_test.go +++ b/tests/upgrade_operator/upgrade_operator_suite_test.go @@ -11,11 +11,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - cfgutil "github.com/k8ssandra/cass-operator/mage/config" ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" - helm_util "github.com/k8ssandra/cass-operator/mage/helm" "github.com/k8ssandra/cass-operator/mage/kubectl" - mageutil "github.com/k8ssandra/cass-operator/mage/util" ) var ( @@ -26,8 +23,6 @@ var ( dcYaml = "../testdata/operator-1.1.0-oss-dc.yaml" podName = fmt.Sprintf("cluster1-%s-r1-sts-0", dcName) podNameJson = "jsonpath={.items[*].metadata.name}" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) ns = ginkgo_util.NewWrapper(testName, namespace) ) @@ -46,16 +41,18 @@ func TestLifecycle(t *testing.T) { func InstallOldOperator() { step := "install old Cass Operator v1.1.0" By(step) - err := helm_util.Install(oldOperatorChart, "cass-operator", ns.Namespace, map[string]string{}) - mageutil.PanicOnError(err) + panic("NotImplemented") + // err := helm_util.Install(oldOperatorChart, "cass-operator", ns.Namespace, map[string]string{}) + // mageutil.PanicOnError(err) } func UpgradeOperator() { step := "upgrade Cass Operator" By(step) - var overrides = map[string]string{"image": cfgutil.GetOperatorImage()} - err := helm_util.Upgrade("../../charts/cass-operator-chart", "cass-operator", ns.Namespace, overrides) - mageutil.PanicOnError(err) + panic("NotImplemented") + // var overrides = map[string]string{"image": cfgutil.GetOperatorImage()} + // err := helm_util.Upgrade("../../charts/cass-operator-chart", "cass-operator", ns.Namespace, overrides) + // mageutil.PanicOnError(err) } var _ = Describe(testName, func() { diff --git a/tests/webhook_validation/webhook_validation_suite_test.go b/tests/webhook_validation/webhook_validation_suite_test.go index 3e7a2978..cdcbcd8e 100644 --- a/tests/webhook_validation/webhook_validation_suite_test.go +++ b/tests/webhook_validation/webhook_validation_suite_test.go @@ -12,6 +12,7 @@ import ( ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" "github.com/k8ssandra/cass-operator/mage/kubectl" + "github.com/k8ssandra/cass-operator/tests/kustomize" ) var ( @@ -31,6 +32,7 @@ func TestLifecycle(t *testing.T) { kubectl.DumpAllLogs(logPath).ExecV() fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) ns.Terminate() + kustomize.Undeploy(namespace) }) RegisterFailHandler(Fail) @@ -40,14 +42,11 @@ func TestLifecycle(t *testing.T) { var _ = Describe(testName, func() { Context("when in a new cluster", func() { Specify("the webhook disallows invalid updates", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() + By("deploy cass-operator with kustomize") + err := kustomize.Deploy(namespace) Expect(err).ToNot(HaveOccurred()) - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - step = "waiting for the operator to become ready" + step := "waiting for the operator to become ready" json := "jsonpath={.items[0].status.containerStatuses[0].ready}" k := kubectl.Get("pods"). WithLabel("name=cass-operator"). diff --git a/tools/k8s-code-generator/Dockerfile b/tools/k8s-code-generator/Dockerfile deleted file mode 100644 index fbc3e9fa..00000000 --- a/tools/k8s-code-generator/Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -# We use the K8s code-generator to generate client boilerplate for our operator. -# More information can be found at: https://github.com/kubernetes/code-generator -FROM golang:1.16-stretch - -ENV CGO_ENABLED=0 -ENV GOPROXY=https://proxy.golang.org,direct -ENV GOPATH=/go -ENV GO111MODULE=on - -# Assume that when this image gets run, the operator code directory -# is mounted to /go/src/github.com/k8ssandra/cass-operator/operator -ENV OPERATOR_DIR=/go/src/github.com/k8ssandra/cass-operator/operator - -# We download a version of the code-generator that matches the build-arg CODEGEN_VERSION. -# For regular use, we would use the version here that is specified in the operator's go.mod file -ARG CODEGEN_VERSION -ENV CODEGEN_BASEPATH=/go/pkg/mod/k8s.io/code-generator@${CODEGEN_VERSION} - -RUN go get -d k8s.io/code-generator@${CODEGEN_VERSION} - -# Copy the downloaded code-generator directory into a new path -# that conforms to the old GOPATH style. The code-generator version -# we use does not currently support go module directory layouts -WORKDIR $GOPATH/src/k8s.io -RUN cp -r $CODEGEN_BASEPATH "code-generator" - -# Install the various code-generators that we might use -WORKDIR $GOPATH/src/k8s.io/code-generator -RUN go install ./cmd/client-gen -RUN go install ./cmd/lister-gen -RUN go install ./cmd/informer-gen - -# The code-generator wants to be executed while your working directory -# is set to your repo location, in the GOPATH style. -WORKDIR $GOPATH/src/github.com/k8ssandra/cass-operator/operator - - -# We don't want newly generated files to be owned by root -# and we will most likely be running this image as another user. -# To make sure our user can run the code-generators, we have -# to make some permission changes -RUN chmod -R 777 /go -RUN mkdir -p /.cache/go-build -RUN chmod -R 777 /.cache - - -# To make running this as simple a possible, we mark the generate script -# as the entrypoint so that we only need to specify the args to it when running. -# -# For example, you could run this image with: -# docker run --rm -t \ -# -v /home/chris/go/src/github.com/datastax/cass-operator/operator:/go/src/github.com/datastax/cass-operator/operator operator-gen-client \ -# client \ -# github.com/datastax/cass-operator/operator/pkg/generated \ -# github.com/datastax/cass-operator/operator/pkg/apis \ -# cassandra:v1beta1 -ENTRYPOINT ["/go/src/k8s.io/code-generator/generate-groups.sh"] diff --git a/tools/operator-sdk/Dockerfile b/tools/operator-sdk/Dockerfile index b624bc60..1656df7c 100644 --- a/tools/operator-sdk/Dockerfile +++ b/tools/operator-sdk/Dockerfile @@ -16,8 +16,8 @@ FROM golang:1.16-stretch as install-operator-sdk # inside the container. Something like... # docker run -v /Users/jim/datastax/cass-operator:/go/src/github.com/datastax/cass-operator ... -ENV OP_SDK_VERSION=v0.17.0 -ENV GOPROXY=https://proxy.golang.org,direct +ENV OP_SDK_VERSION=v0.18.2 +ENV GOPROXY=https://proxy.golang.org WORKDIR /usr/bin @@ -81,7 +81,7 @@ RUN GO111MODULE=on operator-sdk generate csv --verbose # So we copy the specific version that this operator-sdk pulled down and move it # into the required path. WORKDIR $GOPATH/src/k8s.io -RUN cp -r "/go/pkg/mod/k8s.io/code-generator@v0.17.4" "code-generator" +RUN cp -r "/go/pkg/mod/k8s.io/code-generator@v0.18.2" "code-generator" WORKDIR $GOPATH/src/k8s.io/code-generator RUN chmod 700 generate-groups.sh diff --git a/update-kubernetes.sh b/update-kubernetes.sh new file mode 100755 index 00000000..fe07feaa --- /dev/null +++ b/update-kubernetes.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -euo pipefail + +VERSION=${1#"v"} +if [ -z "$VERSION" ]; then + echo "Must specify version!" + exit 1 +fi +MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' +)) +for MOD in "${MODS[@]}"; do + V=$( + go mod download -json "${MOD}@kubernetes-${VERSION}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + go mod edit "-replace=${MOD}=${MOD}@${V}" +done +go get "k8s.io/kubernetes@v${VERSION}"