From b7738ef0d29743d1eb5f6c16fb80ad7a1a6d1386 Mon Sep 17 00:00:00 2001 From: Serguei Bezverkhi Date: Sat, 24 Mar 2018 09:05:46 -0400 Subject: [PATCH 1/3] vendor files --- vendor/github.com/golang/mock/.gitignore | 17 + vendor/github.com/golang/mock/.travis.yml | 13 + vendor/github.com/golang/mock/AUTHORS | 12 + vendor/github.com/golang/mock/CONTRIBUTORS | 37 + vendor/github.com/golang/mock/LICENSE | 202 ++ vendor/github.com/golang/mock/README.md | 86 + .../github.com/golang/mock/ci/check_go_fmt.sh | 12 + .../golang/mock/ci/check_go_generate.sh | 25 + vendor/github.com/golang/mock/gomock/call.go | 258 +++ .../golang/mock/gomock/call_test.go | 47 + .../github.com/golang/mock/gomock/callset.go | 76 + .../golang/mock/gomock/controller.go | 183 ++ .../golang/mock/gomock/controller_test.go | 475 ++++ .../github.com/golang/mock/gomock/matchers.go | 99 + .../golang/mock/gomock/matchers_test.go | 70 + .../mock/gomock/mock_matcher/mock_matcher.go | 56 + .../github.com/golang/mock/mockgen/mockgen.go | 442 ++++ .../golang/mock/mockgen/model/model.go | 431 ++++ .../github.com/golang/mock/mockgen/parse.go | 447 ++++ .../github.com/golang/mock/mockgen/reflect.go | 163 ++ .../mockgen/tests/unexported_method/README.md | 1 + .../tests/unexported_method/bugreport.go | 15 + .../tests/unexported_method/bugreport_mock.go | 44 + .../tests/unexported_method/bugreport_test.go | 17 + .../github.com/golang/mock/sample/README.md | 16 + .../golang/mock/sample/imp1/imp1.go | 17 + .../golang/mock/sample/imp2/imp2.go | 3 + .../golang/mock/sample/imp3/imp3.go | 3 + .../golang/mock/sample/imp4/imp4.go | 3 + .../golang/mock/sample/mock_user/mock_user.go | 383 ++++ vendor/github.com/golang/mock/sample/user.go | 114 + .../golang/mock/sample/user_test.go | 122 ++ .../github.com/gregjones/httpcache/README.md | 2 +- .../kubernetes-csi/csi-test/.gitignore | 12 + .../kubernetes-csi/csi-test/.travis.yml | 9 + .../kubernetes-csi/csi-test/Gopkg.lock | 193 ++ .../kubernetes-csi/csi-test/Gopkg.toml | 54 + .../kubernetes-csi/csi-test/LICENSE | 201 ++ .../kubernetes-csi/csi-test/README.md | 16 + .../csi-test/cmd/csi-sanity/Makefile | 64 + .../csi-test/cmd/csi-sanity/README.md | 34 + .../csi-test/cmd/csi-sanity/sanity_test.go | 54 + .../csi-test/code-of-conduct.md | 3 + .../kubernetes-csi/csi-test/driver/driver.go | 117 + .../csi-test/driver/driver.mock.go | 302 +++ .../kubernetes-csi/csi-test/driver/mock.go | 83 + .../kubernetes-csi/csi-test/hack/e2e.sh | 34 + .../kubernetes-csi/csi-test/mock/AUTHORS | 2 + .../kubernetes-csi/csi-test/mock/README.md | 2 + .../kubernetes-csi/csi-test/mock/main.go | 82 + .../csi-test/mock/service/controller.go | 330 +++ .../csi-test/mock/service/identity.go | 45 + .../csi-test/mock/service/node.go | 135 ++ .../csi-test/mock/service/service.go | 111 + .../csi-test/pkg/sanity/README.md | 25 + .../csi-test/pkg/sanity/controller.go | 808 +++++++ .../csi-test/pkg/sanity/identity.go | 55 + .../csi-test/pkg/sanity/node.go | 388 ++++ .../csi-test/pkg/sanity/sanity.go | 80 + .../kubernetes-csi/csi-test/test/co_test.go | 105 + .../csi-test/test/driver_test.go | 127 ++ .../kubernetes-csi/csi-test/utils/grpcutil.go | 59 + .../csi-test/utils/safegoroutinetester.go | 40 + .../flex/pkg/volume/provision.go | 2 +- .../external-storage/glide.lock | 95 +- .../external-storage/glide.yaml | 12 +- .../external-storage/gluster/README.md | 2 + .../deploy/glusterblk-provisioner-pod.yaml | 11 + .../block/deploy/glusterblk-provisioner.pod | 13 - .../glusterfile-provisioner.go | 18 +- .../deploy/glusterfile-provisioner-pod.yaml | 11 + .../file/deploy/glusterfs-provisioner.pod | 13 - .../deploy/kubernetes/auth/clusterrole.yaml | 2 +- .../kubernetes/auth/clusterrolebinding.yaml | 2 +- .../github.com/modern-go/concurrent/README.md | 40 +- .../concurrent/unbounded_executor.go | 23 +- .../concurrent/unbounded_executor_test.go | 4 +- .../x/crypto/acme/autocert/renewal.go | 4 +- vendor/golang.org/x/crypto/argon2/argon2.go | 14 +- .../x/crypto/ripemd160/ripemd160_test.go | 18 +- .../x/crypto/ripemd160/ripemd160block.go | 64 +- vendor/golang.org/x/crypto/sha3/shake.go | 2 +- .../golang.org/x/crypto/ssh/terminal/util.go | 4 +- .../x/crypto/ssh/terminal/util_solaris.go | 40 +- .../x/crypto/ssh/terminal/util_windows.go | 4 +- .../x/net/dns/dnsmessage/example_test.go | 8 +- .../x/net/http2/h2demo/service.yaml | 1 + vendor/golang.org/x/net/route/syscall.go | 2 +- vendor/golang.org/x/net/trace/trace.go | 59 +- .../golang.org/x/sys/plan9/syscall_plan9.go | 10 +- .../x/sys/unix/syscall_linux_gccgo.go | 21 + .../x/sys/unix/syscall_linux_test.go | 4 + vendor/golang.org/x/sys/unix/syscall_unix.go | 10 +- .../cloud/dialogflow/v2beta1/context.pb.go | 98 +- .../cloud/dialogflow/v2beta1/intent.pb.go | 321 +-- .../cloud/dialogflow/v2beta1/session.pb.go | 214 +- .../v2beta1/session_entity_type.pb.go | 107 +- .../texttospeech/v1beta1/cloud_tts.pb.go | 672 ++++++ .../cloud/vision/v1p2beta1/geometry.pb.go | 183 ++ .../vision/v1p2beta1/image_annotator.pb.go | 1933 +++++++++++++++++ .../vision/v1p2beta1/text_annotation.pb.go | 593 +++++ .../vision/v1p2beta1/web_detection.pb.go | 278 +++ .../googleapis/monitoring/v3/alert.pb.go | 904 ++++++++ .../monitoring/v3/alert_service.pb.go | 527 +++++ .../googleapis/monitoring/v3/common.pb.go | 350 +-- .../googleapis/monitoring/v3/group.pb.go | 6 +- .../monitoring/v3/group_service.pb.go | 30 +- .../googleapis/monitoring/v3/metric.pb.go | 8 +- .../monitoring/v3/metric_service.pb.go | 48 +- .../monitoring/v3/mutation_record.pb.go | 67 + .../monitoring/v3/notification.pb.go | 313 +++ .../monitoring/v3/notification_service.pb.go | 1035 +++++++++ .../googleapis/monitoring/v3/uptime.pb.go | 24 +- .../monitoring/v3/uptime_service.pb.go | 36 +- vendor/k8s.io/kubernetes/CHANGELOG-1.9.md | 150 +- vendor/k8s.io/kubernetes/Godeps/Godeps.json | 22 +- .../kubernetes/api/openapi-spec/swagger.json | 2 +- .../build/build-image/cross/Dockerfile | 2 +- .../build/build-image/cross/VERSION | 2 +- vendor/k8s.io/kubernetes/build/root/WORKSPACE | 24 +- .../cluster/addons/dashboard/OWNERS | 6 + .../dashboard/dashboard-controller.yaml | 2 +- .../addons/dashboard/dashboard-rbac.yaml | 8 +- .../addons/dashboard/dashboard-secret.yaml | 11 + .../kubernetes/cluster/gce/config-default.sh | 5 + .../kubernetes/cluster/gce/config-test.sh | 5 + .../gce/container-linux/configure-helper.sh | 2 +- .../gce/container-linux/master-helper.sh | 9 +- .../cluster/gce/gci/configure-helper.sh | 2 +- .../cluster/gce/gci/master-helper.sh | 9 +- .../kubernetes/cluster/gce/upgrade-aliases.sh | 171 ++ .../kubernetes/cluster/images/etcd/Dockerfile | 2 +- .../kubernetes/cluster/images/etcd/Makefile | 134 +- .../kubernetes/cluster/images/etcd/README.md | 8 + .../cluster/images/etcd/migrate-if-needed.sh | 172 +- .../cluster/images/etcd/start-stop-etcd.sh | 68 + .../cluster/saltbase/salt/etcd/etcd.manifest | 3 + vendor/k8s.io/kubernetes/hack/lib/golang.sh | 2 +- vendor/k8s.io/kubernetes/hack/lib/util.sh | 8 + vendor/k8s.io/kubernetes/hack/update-bazel.sh | 3 +- .../pkg/apis/core/validation/validation.go | 6 +- .../apis/core/validation/validation_test.go | 62 + .../pkg/cloudprovider/providers/azure/BUILD | 1 + .../azure/azure_blobDiskController.go | 2 +- .../providers/azure/azure_instances.go | 6 +- .../providers/azure/azure_loadbalancer.go | 6 +- .../providers/azure/azure_storage.go | 81 +- .../providers/azure/azure_storageaccount.go | 24 +- .../providers/azure/azure_util.go | 15 +- .../providers/azure/azure_util_test.go | 72 + .../providers/gce/gce_instances.go | 11 +- .../providers/openstack/openstack.go | 15 +- .../providers/openstack/openstack_routes.go | 11 +- .../pkg/cloudprovider/providers/vsphere/BUILD | 1 - .../providers/vsphere/nodemanager.go | 11 +- .../providers/vsphere/vsphere.go | 51 +- .../providers/vsphere/vsphere_util.go | 76 +- .../pkg/controller/deployment/recreate.go | 15 +- .../controller/deployment/recreate_test.go | 130 +- .../pkg/controller/node/ipam/sync/sync.go | 8 +- .../controller/node/ipam/sync/sync_test.go | 18 +- .../kubernetes/pkg/features/kube_features.go | 16 + .../cm/container_manager_linux_test.go | 12 + .../pkg/kubelet/container/helpers.go | 2 +- .../container/testing/fake_runtime_helper.go | 4 +- .../k8s.io/kubernetes/pkg/kubelet/kubelet.go | 7 +- .../kubernetes/pkg/kubelet/kubelet_pods.go | 80 +- .../pkg/kubelet/kubelet_pods_test.go | 62 +- .../kuberuntime/kuberuntime_container.go | 18 +- .../kuberuntime/kuberuntime_container_test.go | 8 +- .../kuberuntime/kuberuntime_manager_test.go | 2 +- .../k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go | 2 +- .../kubernetes/pkg/kubelet/util/util.go | 13 + .../pkg/kubelet/util/util_unsupported.go | 9 + .../volumemanager/reconciler/reconciler.go | 2 +- .../kubelet/winstats/perfcounter_nodestats.go | 50 +- .../kubernetes/pkg/master/tunneler/ssh.go | 7 +- vendor/k8s.io/kubernetes/pkg/util/mount/BUILD | 12 +- .../kubernetes/pkg/util/mount/exec_mount.go | 13 + .../pkg/util/mount/exec_mount_test.go | 12 + .../pkg/util/mount/exec_mount_unsupported.go | 13 + .../k8s.io/kubernetes/pkg/util/mount/fake.go | 11 + .../k8s.io/kubernetes/pkg/util/mount/mount.go | 61 +- .../kubernetes/pkg/util/mount/mount_linux.go | 445 ++++ .../pkg/util/mount/mount_linux_test.go | 1206 ++++++++++ .../pkg/util/mount/mount_unsupported.go | 13 + .../pkg/util/mount/mount_windows.go | 239 +- .../pkg/util/mount/mount_windows_test.go | 414 ++++ .../pkg/util/mount/nsenter_mount.go | 48 + .../pkg/util/mount/nsenter_mount_test.go | 126 +- .../util/mount/nsenter_mount_unsupported.go | 13 + .../pkg/util/removeall/removeall_test.go | 12 + .../pkg/volume/azure_dd/azure_common.go | 9 +- .../pkg/volume/azure_file/azure_provision.go | 4 +- .../pkg/volume/configmap/configmap.go | 3 + .../pkg/volume/downwardapi/downwardapi.go | 3 + .../pkg/volume/host_path/host_path_test.go | 12 + .../pkg/volume/portworx/portworx_util.go | 24 +- .../pkg/volume/projected/projected.go | 3 + .../kubernetes/pkg/volume/secret/secret.go | 3 + .../k8s.io/kubernetes/pkg/volume/util/BUILD | 3 + .../pkg/volume/util/nested_volumes.go | 99 + .../pkg/volume/util/nested_volumes_test.go | 233 ++ .../operationexecutor/operation_executor.go | 16 +- .../operation_executor_test.go | 4 +- .../operationexecutor/operation_generator.go | 14 +- .../pkg/scheduler/core/scheduling_queue.go | 172 +- .../scheduler/core/scheduling_queue_test.go | 206 +- .../plugin/pkg/scheduler/factory/factory.go | 2 +- .../pkg/server/storage/storage_factory.go | 6 +- .../test/e2e/common/downwardapi_volume.go | 42 +- .../kubernetes/test/e2e/common/projected.go | 36 +- .../kubernetes/test/e2e/framework/util.go | 8 +- .../k8s.io/kubernetes/test/e2e/storage/BUILD | 2 + .../kubernetes/test/e2e/storage/subpath.go | 742 +++++++ vendor/k8s.io/kubernetes/test/images/Makefile | 2 +- 216 files changed, 20407 insertions(+), 1348 deletions(-) create mode 100644 vendor/github.com/golang/mock/.gitignore create mode 100644 vendor/github.com/golang/mock/.travis.yml create mode 100644 vendor/github.com/golang/mock/AUTHORS create mode 100644 vendor/github.com/golang/mock/CONTRIBUTORS create mode 100644 vendor/github.com/golang/mock/LICENSE create mode 100644 vendor/github.com/golang/mock/README.md create mode 100755 vendor/github.com/golang/mock/ci/check_go_fmt.sh create mode 100755 vendor/github.com/golang/mock/ci/check_go_generate.sh create mode 100644 vendor/github.com/golang/mock/gomock/call.go create mode 100644 vendor/github.com/golang/mock/gomock/call_test.go create mode 100644 vendor/github.com/golang/mock/gomock/callset.go create mode 100644 vendor/github.com/golang/mock/gomock/controller.go create mode 100644 vendor/github.com/golang/mock/gomock/controller_test.go create mode 100644 vendor/github.com/golang/mock/gomock/matchers.go create mode 100644 vendor/github.com/golang/mock/gomock/matchers_test.go create mode 100644 vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go create mode 100644 vendor/github.com/golang/mock/mockgen/mockgen.go create mode 100644 vendor/github.com/golang/mock/mockgen/model/model.go create mode 100644 vendor/github.com/golang/mock/mockgen/parse.go create mode 100644 vendor/github.com/golang/mock/mockgen/reflect.go create mode 100644 vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md create mode 100644 vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go create mode 100644 vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go create mode 100644 vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go create mode 100644 vendor/github.com/golang/mock/sample/README.md create mode 100644 vendor/github.com/golang/mock/sample/imp1/imp1.go create mode 100644 vendor/github.com/golang/mock/sample/imp2/imp2.go create mode 100644 vendor/github.com/golang/mock/sample/imp3/imp3.go create mode 100644 vendor/github.com/golang/mock/sample/imp4/imp4.go create mode 100644 vendor/github.com/golang/mock/sample/mock_user/mock_user.go create mode 100644 vendor/github.com/golang/mock/sample/user.go create mode 100644 vendor/github.com/golang/mock/sample/user_test.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/.gitignore create mode 100644 vendor/github.com/kubernetes-csi/csi-test/.travis.yml create mode 100644 vendor/github.com/kubernetes-csi/csi-test/Gopkg.lock create mode 100644 vendor/github.com/kubernetes-csi/csi-test/Gopkg.toml create mode 100644 vendor/github.com/kubernetes-csi/csi-test/LICENSE create mode 100644 vendor/github.com/kubernetes-csi/csi-test/README.md create mode 100644 vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/Makefile create mode 100644 vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/README.md create mode 100644 vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/sanity_test.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/code-of-conduct.md create mode 100644 vendor/github.com/kubernetes-csi/csi-test/driver/driver.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/driver/driver.mock.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/driver/mock.go create mode 100755 vendor/github.com/kubernetes-csi/csi-test/hack/e2e.sh create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/AUTHORS create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/README.md create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/main.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/service/controller.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/service/identity.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/service/node.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/mock/service/service.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/README.md create mode 100644 vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/controller.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/identity.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/node.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/sanity.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/test/co_test.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/test/driver_test.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/utils/grpcutil.go create mode 100644 vendor/github.com/kubernetes-csi/csi-test/utils/safegoroutinetester.go create mode 100644 vendor/github.com/kubernetes-incubator/external-storage/gluster/README.md create mode 100644 vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner-pod.yaml delete mode 100644 vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner.pod create mode 100644 vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfile-provisioner-pod.yaml delete mode 100644 vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfs-provisioner.pod create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go create mode 100644 vendor/google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1/cloud_tts.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/geometry.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/image_annotator.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/text_annotation.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/web_detection.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go create mode 100644 vendor/k8s.io/kubernetes/cluster/addons/dashboard/OWNERS create mode 100755 vendor/k8s.io/kubernetes/cluster/gce/upgrade-aliases.sh create mode 100755 vendor/k8s.io/kubernetes/cluster/images/etcd/start-stop-etcd.sh create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes.go create mode 100644 vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes_test.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go diff --git a/vendor/github.com/golang/mock/.gitignore b/vendor/github.com/golang/mock/.gitignore new file mode 100644 index 0000000000..4eb2f79509 --- /dev/null +++ b/vendor/github.com/golang/mock/.gitignore @@ -0,0 +1,17 @@ +# Object files and binaries from go. +*.[568] + +# Library files. +*.a + +# Any file prefixed by an underscore. +*/_* + +# Vim temporary files. +.*.swp + +# The mockgen binary. +mockgen/mockgen + +# A binary produced by gotest. +#gomock/[568]\.out diff --git a/vendor/github.com/golang/mock/.travis.yml b/vendor/github.com/golang/mock/.travis.yml new file mode 100644 index 0000000000..543ce129bf --- /dev/null +++ b/vendor/github.com/golang/mock/.travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + # we intend to support only the latest version and perhaps the previous one + - 1.7 + - 1.8 + +script: + - go build ./... + - go install github.com/golang/mock/mockgen + - ./ci/check_go_fmt.sh + - ./ci/check_go_generate.sh + - go test -v ./... diff --git a/vendor/github.com/golang/mock/AUTHORS b/vendor/github.com/golang/mock/AUTHORS new file mode 100644 index 0000000000..660b8ccc8a --- /dev/null +++ b/vendor/github.com/golang/mock/AUTHORS @@ -0,0 +1,12 @@ +# This is the official list of GoMock authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +Alex Reece +Google Inc. diff --git a/vendor/github.com/golang/mock/CONTRIBUTORS b/vendor/github.com/golang/mock/CONTRIBUTORS new file mode 100644 index 0000000000..def849cab1 --- /dev/null +++ b/vendor/github.com/golang/mock/CONTRIBUTORS @@ -0,0 +1,37 @@ +# This is the official list of people who can contribute (and typically +# have contributed) code to the gomock repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# The submission process automatically checks to make sure +# that people submitting code are listed in this file (by email address). +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Name +# +# An entry with two email addresses specifies that the +# first address should be used in the submit logs and +# that the second address should be recognized as the +# same person when interacting with Rietveld. + +# Please keep the list sorted. + +Aaron Jacobs +Alex Reece +David Symonds +Ryan Barrett diff --git a/vendor/github.com/golang/mock/LICENSE b/vendor/github.com/golang/mock/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/github.com/golang/mock/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/golang/mock/README.md b/vendor/github.com/golang/mock/README.md new file mode 100644 index 0000000000..daf4f975d2 --- /dev/null +++ b/vendor/github.com/golang/mock/README.md @@ -0,0 +1,86 @@ +gomock [![Build Status](https://travis-ci.org/golang/mock.svg?branch=master)](https://travis-ci.org/golang/mock) +====== + +GoMock is a mocking framework for the [Go programming language][golang]. It +integrates well with Go's built-in `testing` package, but can be used in other +contexts too. + + +Installation +------------ + +Once you have [installed Go][golang-install], run these commands +to install the `gomock` package and the `mockgen` tool: + + go get github.com/golang/mock/gomock + go get github.com/golang/mock/mockgen + + +Documentation +------------- + +After installing, you can use `go doc` to get documentation: + + go doc github.com/golang/mock/gomock + +Alternatively, there is an online reference for the package hosted on GoPkgDoc +[here][gomock-ref]. + + +Running mockgen +--------------- + +`mockgen` has two modes of operation: source and reflect. +Source mode generates mock interfaces from a source file. +It is enabled by using the -source flag. Other flags that +may be useful in this mode are -imports and -aux_files. + +Example: + + mockgen -source=foo.go [other options] + +Reflect mode generates mock interfaces by building a program +that uses reflection to understand interfaces. It is enabled +by passing two non-flag arguments: an import path, and a +comma-separated list of symbols. + +Example: + + mockgen database/sql/driver Conn,Driver + +The `mockgen` command is used to generate source code for a mock +class given a Go source file containing interfaces to be mocked. +It supports the following flags: + + * `-source`: A file containing interfaces to be mocked. + + * `-destination`: A file to which to write the resulting source code. If you + don't set this, the code is printed to standard output. + + * `-package`: The package to use for the resulting mock class + source code. If you don't set this, the package name is `mock_` concatenated + with the package of the input file. + + * `-imports`: A list of explicit imports that should be used in the resulting + source code, specified as a comma-separated list of elements of the form + `foo=bar/baz`, where `bar/baz` is the package being imported and `foo` is + the identifier to use for the package in the generated source code. + + * `-aux_files`: A list of additional files that should be consulted to + resolve e.g. embedded interfaces defined in a different file. This is + specified as a comma-separated list of elements of the form + `foo=bar/baz.go`, where `bar/baz.go` is the source file and `foo` is the + package name of that file used by the -source file. + +* `-build_flags`: (reflect mode only) Flags passed verbatim to `go build`. + +For an example of the use of `mockgen`, see the `sample/` directory. In simple +cases, you will need only the `-source` flag. + + +TODO: Brief overview of how to create mock objects and set up expectations, and +an example. + +[golang]: http://golang.org/ +[golang-install]: http://golang.org/doc/install.html#releases +[gomock-ref]: http://godoc.org/github.com/golang/mock/gomock diff --git a/vendor/github.com/golang/mock/ci/check_go_fmt.sh b/vendor/github.com/golang/mock/ci/check_go_fmt.sh new file mode 100755 index 0000000000..ae4028ac25 --- /dev/null +++ b/vendor/github.com/golang/mock/ci/check_go_fmt.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# This script is used by the CI to check if the code is gofmt formatted. + +set -euo pipefail + +GOFMT_DIFF=$(IFS=$'\n'; gofmt -d $( find . -type f -name '*.go' ) ) +if [[ -n "${GOFMT_DIFF}" ]]; then + echo "${GOFMT_DIFF}" + echo + echo "The go source files aren't gofmt formatted." + exit 1 +fi diff --git a/vendor/github.com/golang/mock/ci/check_go_generate.sh b/vendor/github.com/golang/mock/ci/check_go_generate.sh new file mode 100755 index 0000000000..a0212e28a3 --- /dev/null +++ b/vendor/github.com/golang/mock/ci/check_go_generate.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# This script is used by the CI to check if 'go generate ./...' is up to date. +# +# Note: If the generated files aren't up to date then this script updates +# them despite printing an error message so running it the second time +# might not print any errors. This isn't very useful locally during development +# but it works well with the CI that downloads a fresh version of the repo +# each time before executing this script. + +set -euo pipefail + +TEMP_DIR=$( mktemp -d ) +function cleanup() { + rm -rf "${TEMP_DIR}" +} +trap cleanup EXIT + +cp -r . "${TEMP_DIR}/" +go generate ./... +if ! diff -r . "${TEMP_DIR}"; then + echo + echo "The generated files aren't up to date." + echo "Update them with the 'go generate ./...' command." + exit 1 +fi diff --git a/vendor/github.com/golang/mock/gomock/call.go b/vendor/github.com/golang/mock/gomock/call.go new file mode 100644 index 0000000000..cc8dfffeb6 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/call.go @@ -0,0 +1,258 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +import ( + "fmt" + "reflect" + "strings" +) + +// Call represents an expected call to a mock. +type Call struct { + t TestReporter // for triggering test failures on invalid call setup + + receiver interface{} // the receiver of the method call + method string // the name of the method + methodType reflect.Type // the type of the method + args []Matcher // the args + rets []interface{} // the return values (if any) + + preReqs []*Call // prerequisite calls + + // Expectations + minCalls, maxCalls int + + numCalls int // actual number made + + // Actions + doFunc reflect.Value + setArgs map[int]reflect.Value +} + +// AnyTimes allows the expectation to be called 0 or more times +func (c *Call) AnyTimes() *Call { + c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity + return c +} + +// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also +// sets the maximum number of calls to infinity. +func (c *Call) MinTimes(n int) *Call { + c.minCalls = n + if c.maxCalls == 1 { + c.maxCalls = 1e8 + } + return c +} + +// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also +// sets the minimum number of calls to 0. +func (c *Call) MaxTimes(n int) *Call { + c.maxCalls = n + if c.minCalls == 1 { + c.minCalls = 0 + } + return c +} + +// Do declares the action to run when the call is matched. +// It takes an interface{} argument to support n-arity functions. +func (c *Call) Do(f interface{}) *Call { + // TODO: Check arity and types here, rather than dying badly elsewhere. + c.doFunc = reflect.ValueOf(f) + return c +} + +func (c *Call) Return(rets ...interface{}) *Call { + mt := c.methodType + if len(rets) != mt.NumOut() { + c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d", + c.receiver, c.method, len(rets), mt.NumOut()) + } + for i, ret := range rets { + if got, want := reflect.TypeOf(ret), mt.Out(i); got == want { + // Identical types; nothing to do. + } else if got == nil { + // Nil needs special handling. + switch want.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + // ok + default: + c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable", + i, c.receiver, c.method, want) + } + } else if got.AssignableTo(want) { + // Assignable type relation. Make the assignment now so that the generated code + // can return the values with a type assertion. + v := reflect.New(want).Elem() + v.Set(reflect.ValueOf(ret)) + rets[i] = v.Interface() + } else { + c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v", + i, c.receiver, c.method, got, want) + } + } + + c.rets = rets + return c +} + +func (c *Call) Times(n int) *Call { + c.minCalls, c.maxCalls = n, n + return c +} + +// SetArg declares an action that will set the nth argument's value, +// indirected through a pointer. +func (c *Call) SetArg(n int, value interface{}) *Call { + if c.setArgs == nil { + c.setArgs = make(map[int]reflect.Value) + } + mt := c.methodType + // TODO: This will break on variadic methods. + // We will need to check those at invocation time. + if n < 0 || n >= mt.NumIn() { + c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn()) + } + // Permit setting argument through an interface. + // In the interface case, we don't (nay, can't) check the type here. + at := mt.In(n) + switch at.Kind() { + case reflect.Ptr: + dt := at.Elem() + if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) { + c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt) + } + case reflect.Interface: + // nothing to do + default: + c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at) + } + c.setArgs[n] = reflect.ValueOf(value) + return c +} + +// isPreReq returns true if other is a direct or indirect prerequisite to c. +func (c *Call) isPreReq(other *Call) bool { + for _, preReq := range c.preReqs { + if other == preReq || preReq.isPreReq(other) { + return true + } + } + return false +} + +// After declares that the call may only match after preReq has been exhausted. +func (c *Call) After(preReq *Call) *Call { + if c == preReq { + c.t.Fatalf("A call isn't allowed to be it's own prerequisite") + } + if preReq.isPreReq(c) { + c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq) + } + + c.preReqs = append(c.preReqs, preReq) + return c +} + +// Returns true iff the minimum number of calls have been made. +func (c *Call) satisfied() bool { + return c.numCalls >= c.minCalls +} + +// Returns true iff the maximum number of calls have been made. +func (c *Call) exhausted() bool { + return c.numCalls >= c.maxCalls +} + +func (c *Call) String() string { + args := make([]string, len(c.args)) + for i, arg := range c.args { + args[i] = arg.String() + } + arguments := strings.Join(args, ", ") + return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments) +} + +// Tests if the given call matches the expected call. +func (c *Call) matches(args []interface{}) bool { + if len(args) != len(c.args) { + return false + } + for i, m := range c.args { + if !m.Matches(args[i]) { + return false + } + } + + // Check that all prerequisite calls have been satisfied. + for _, preReqCall := range c.preReqs { + if !preReqCall.satisfied() { + return false + } + } + + return true +} + +// dropPrereqs tells the expected Call to not re-check prerequite calls any +// longer, and to return its current set. +func (c *Call) dropPrereqs() (preReqs []*Call) { + preReqs = c.preReqs + c.preReqs = nil + return +} + +func (c *Call) call(args []interface{}) (rets []interface{}, action func()) { + c.numCalls++ + + // Actions + if c.doFunc.IsValid() { + doArgs := make([]reflect.Value, len(args)) + ft := c.doFunc.Type() + for i := 0; i < len(args); i++ { + if args[i] != nil { + doArgs[i] = reflect.ValueOf(args[i]) + } else { + // Use the zero value for the arg. + doArgs[i] = reflect.Zero(ft.In(i)) + } + } + action = func() { c.doFunc.Call(doArgs) } + } + for n, v := range c.setArgs { + reflect.ValueOf(args[n]).Elem().Set(v) + } + + rets = c.rets + if rets == nil { + // Synthesize the zero value for each of the return args' types. + mt := c.methodType + rets = make([]interface{}, mt.NumOut()) + for i := 0; i < mt.NumOut(); i++ { + rets[i] = reflect.Zero(mt.Out(i)).Interface() + } + } + + return +} + +// InOrder declares that the given calls should occur in order. +func InOrder(calls ...*Call) { + for i := 1; i < len(calls); i++ { + calls[i].After(calls[i-1]) + } +} diff --git a/vendor/github.com/golang/mock/gomock/call_test.go b/vendor/github.com/golang/mock/gomock/call_test.go new file mode 100644 index 0000000000..3ae7263cb6 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/call_test.go @@ -0,0 +1,47 @@ +package gomock + +import "testing" + +type mockTestReporter struct { + errorCalls int + fatalCalls int +} + +func (o *mockTestReporter) Errorf(format string, args ...interface{}) { + o.errorCalls++ +} + +func (o *mockTestReporter) Fatalf(format string, args ...interface{}) { + o.fatalCalls++ +} + +func TestCall_After(t *testing.T) { + t.Run("SelfPrereqCallsFatalf", func(t *testing.T) { + tr1 := &mockTestReporter{} + + c := &Call{t: tr1} + c.After(c) + + if tr1.fatalCalls != 1 { + t.Errorf("number of fatal calls == %v, want 1", tr1.fatalCalls) + } + }) + + t.Run("LoopInCallOrderCallsFatalf", func(t *testing.T) { + tr1 := &mockTestReporter{} + tr2 := &mockTestReporter{} + + c1 := &Call{t: tr1} + c2 := &Call{t: tr2} + c1.After(c2) + c2.After(c1) + + if tr1.errorCalls != 0 || tr1.fatalCalls != 0 { + t.Error("unexpected errors") + } + + if tr2.fatalCalls != 1 { + t.Errorf("number of fatal calls == %v, want 1", tr2.fatalCalls) + } + }) +} diff --git a/vendor/github.com/golang/mock/gomock/callset.go b/vendor/github.com/golang/mock/gomock/callset.go new file mode 100644 index 0000000000..1b7de4c0b3 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/callset.go @@ -0,0 +1,76 @@ +// Copyright 2011 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +// callSet represents a set of expected calls, indexed by receiver and method +// name. +type callSet map[interface{}]map[string][]*Call + +// Add adds a new expected call. +func (cs callSet) Add(call *Call) { + methodMap, ok := cs[call.receiver] + if !ok { + methodMap = make(map[string][]*Call) + cs[call.receiver] = methodMap + } + methodMap[call.method] = append(methodMap[call.method], call) +} + +// Remove removes an expected call. +func (cs callSet) Remove(call *Call) { + methodMap, ok := cs[call.receiver] + if !ok { + return + } + sl := methodMap[call.method] + for i, c := range sl { + if c == call { + // quick removal; we don't need to maintain call order + if len(sl) > 1 { + sl[i] = sl[len(sl)-1] + } + methodMap[call.method] = sl[:len(sl)-1] + break + } + } +} + +// FindMatch searches for a matching call. Returns nil if no call matched. +func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) *Call { + methodMap, ok := cs[receiver] + if !ok { + return nil + } + calls, ok := methodMap[method] + if !ok { + return nil + } + + // Search through the unordered set of calls expected on a method on a + // receiver. + for _, call := range calls { + // A call should not normally still be here if exhausted, + // but it can happen if, for instance, .Times(0) was used. + // Pretend the call doesn't match. + if call.exhausted() { + continue + } + if call.matches(args) { + return call + } + } + + return nil +} diff --git a/vendor/github.com/golang/mock/gomock/controller.go b/vendor/github.com/golang/mock/gomock/controller.go new file mode 100644 index 0000000000..6bff78d1dc --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/controller.go @@ -0,0 +1,183 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// GoMock - a mock framework for Go. +// +// Standard usage: +// (1) Define an interface that you wish to mock. +// type MyInterface interface { +// SomeMethod(x int64, y string) +// } +// (2) Use mockgen to generate a mock from the interface. +// (3) Use the mock in a test: +// func TestMyThing(t *testing.T) { +// mockCtrl := gomock.NewController(t) +// defer mockCtrl.Finish() +// +// mockObj := something.NewMockMyInterface(mockCtrl) +// mockObj.EXPECT().SomeMethod(4, "blah") +// // pass mockObj to a real object and play with it. +// } +// +// By default, expected calls are not enforced to run in any particular order. +// Call order dependency can be enforced by use of InOrder and/or Call.After. +// Call.After can create more varied call order dependencies, but InOrder is +// often more convenient. +// +// The following examples create equivalent call order dependencies. +// +// Example of using Call.After to chain expected call order: +// +// firstCall := mockObj.EXPECT().SomeMethod(1, "first") +// secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall) +// mockObj.EXPECT().SomeMethod(3, "third").After(secondCall) +// +// Example of using InOrder to declare expected call order: +// +// gomock.InOrder( +// mockObj.EXPECT().SomeMethod(1, "first"), +// mockObj.EXPECT().SomeMethod(2, "second"), +// mockObj.EXPECT().SomeMethod(3, "third"), +// ) +// +// TODO: +// - Handle different argument/return types (e.g. ..., chan, map, interface). +package gomock + +import ( + "fmt" + "reflect" + "sync" +) + +// A TestReporter is something that can be used to report test failures. +// It is satisfied by the standard library's *testing.T. +type TestReporter interface { + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) +} + +// A Controller represents the top-level control of a mock ecosystem. +// It defines the scope and lifetime of mock objects, as well as their expectations. +// It is safe to call Controller's methods from multiple goroutines. +type Controller struct { + mu sync.Mutex + t TestReporter + expectedCalls callSet +} + +func NewController(t TestReporter) *Controller { + return &Controller{ + t: t, + expectedCalls: make(callSet), + } +} + +func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call { + recv := reflect.ValueOf(receiver) + for i := 0; i < recv.Type().NumMethod(); i++ { + if recv.Type().Method(i).Name == method { + return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...) + } + } + ctrl.t.Fatalf("gomock: failed finding method %s on %T", method, receiver) + // In case t.Fatalf does not panic. + panic(fmt.Sprintf("gomock: failed finding method %s on %T", method, receiver)) +} + +func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { + // TODO: check arity, types. + margs := make([]Matcher, len(args)) + for i, arg := range args { + if m, ok := arg.(Matcher); ok { + margs[i] = m + } else if arg == nil { + // Handle nil specially so that passing a nil interface value + // will match the typed nils of concrete args. + margs[i] = Nil() + } else { + margs[i] = Eq(arg) + } + } + + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + + call := &Call{t: ctrl.t, receiver: receiver, method: method, methodType: methodType, args: margs, minCalls: 1, maxCalls: 1} + + ctrl.expectedCalls.Add(call) + return call +} + +func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} { + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + + expected := ctrl.expectedCalls.FindMatch(receiver, method, args) + if expected == nil { + ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args) + } + + // Two things happen here: + // * the matching call no longer needs to check prerequite calls, + // * and the prerequite calls are no longer expected, so remove them. + preReqCalls := expected.dropPrereqs() + for _, preReqCall := range preReqCalls { + ctrl.expectedCalls.Remove(preReqCall) + } + + rets, action := expected.call(args) + if expected.exhausted() { + ctrl.expectedCalls.Remove(expected) + } + + // Don't hold the lock while doing the call's action (if any) + // so that actions may execute concurrently. + // We use the deferred Unlock to capture any panics that happen above; + // here we add a deferred Lock to balance it. + ctrl.mu.Unlock() + defer ctrl.mu.Lock() + if action != nil { + action() + } + + return rets +} + +func (ctrl *Controller) Finish() { + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + + // If we're currently panicking, probably because this is a deferred call, + // pass through the panic. + if err := recover(); err != nil { + panic(err) + } + + // Check that all remaining expected calls are satisfied. + failures := false + for _, methodMap := range ctrl.expectedCalls { + for _, calls := range methodMap { + for _, call := range calls { + if !call.satisfied() { + ctrl.t.Errorf("missing call(s) to %v", call) + failures = true + } + } + } + } + if failures { + ctrl.t.Fatalf("aborting test due to missing call(s)") + } +} diff --git a/vendor/github.com/golang/mock/gomock/controller_test.go b/vendor/github.com/golang/mock/gomock/controller_test.go new file mode 100644 index 0000000000..57f79572c3 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/controller_test.go @@ -0,0 +1,475 @@ +// Copyright 2011 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/golang/mock/gomock" +) + +type ErrorReporter struct { + t *testing.T + log []string + failed bool + fatalToken struct{} +} + +func NewErrorReporter(t *testing.T) *ErrorReporter { + return &ErrorReporter{t: t} +} + +func (e *ErrorReporter) reportLog() { + for _, entry := range e.log { + e.t.Log(entry) + } +} + +func (e *ErrorReporter) assertPass(msg string) { + if e.failed { + e.t.Errorf("Expected pass, but got failure(s): %s", msg) + e.reportLog() + } +} + +func (e *ErrorReporter) assertFail(msg string) { + if !e.failed { + e.t.Errorf("Expected failure, but got pass: %s", msg) + } +} + +// Use to check that code triggers a fatal test failure. +func (e *ErrorReporter) assertFatal(fn func()) { + defer func() { + err := recover() + if err == nil { + var actual string + if e.failed { + actual = "non-fatal failure" + } else { + actual = "pass" + } + e.t.Error("Expected fatal failure, but got a", actual) + } else if token, ok := err.(*struct{}); ok && token == &e.fatalToken { + // This is okay - the panic is from Fatalf(). + return + } else { + // Some other panic. + panic(err) + } + }() + + fn() +} + +// recoverUnexpectedFatal can be used as a deferred call in test cases to +// recover from and display a call to ErrorReporter.Fatalf(). +func (e *ErrorReporter) recoverUnexpectedFatal() { + err := recover() + if err == nil { + // No panic. + } else if token, ok := err.(*struct{}); ok && token == &e.fatalToken { + // Unexpected fatal error happened. + e.t.Error("Got unexpected fatal error(s). All errors up to this point:") + e.reportLog() + return + } else { + // Some other panic. + panic(err) + } +} + +func (e *ErrorReporter) Logf(format string, args ...interface{}) { + e.log = append(e.log, fmt.Sprintf(format, args...)) +} + +func (e *ErrorReporter) Errorf(format string, args ...interface{}) { + e.Logf(format, args...) + e.failed = true +} + +func (e *ErrorReporter) Fatalf(format string, args ...interface{}) { + e.Logf(format, args...) + e.failed = true + panic(&e.fatalToken) +} + +// A type purely for use as a receiver in testing the Controller. +type Subject struct{} + +func (s *Subject) FooMethod(arg string) int { + return 0 +} + +func (s *Subject) BarMethod(arg string) int { + return 0 +} + +func assertEqual(t *testing.T, expected interface{}, actual interface{}) { + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Expected %+v, but got %+v", expected, actual) + } +} + +func createFixtures(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller) { + // reporter acts as a testing.T-like object that we pass to the + // Controller. We use it to test that the mock considered tests + // successful or failed. + reporter = NewErrorReporter(t) + ctrl = gomock.NewController(reporter) + return +} + +func TestNoCalls(t *testing.T) { + reporter, ctrl := createFixtures(t) + ctrl.Finish() + reporter.assertPass("No calls expected or made.") +} + +func TestExpectedMethodCall(t *testing.T) { + reporter, ctrl := createFixtures(t) + subject := new(Subject) + + ctrl.RecordCall(subject, "FooMethod", "argument") + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Finish() + + reporter.assertPass("Expected method call made.") +} + +func TestUnexpectedMethodCall(t *testing.T) { + reporter, ctrl := createFixtures(t) + subject := new(Subject) + + reporter.assertFatal(func() { + ctrl.Call(subject, "FooMethod", "argument") + }) + + ctrl.Finish() +} + +func TestRepeatedCall(t *testing.T) { + reporter, ctrl := createFixtures(t) + subject := new(Subject) + + ctrl.RecordCall(subject, "FooMethod", "argument").Times(3) + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Call(subject, "FooMethod", "argument") + reporter.assertPass("After expected repeated method calls.") + reporter.assertFatal(func() { + ctrl.Call(subject, "FooMethod", "argument") + }) + ctrl.Finish() + reporter.assertFail("After calling one too many times.") +} + +func TestUnexpectedArgCount(t *testing.T) { + reporter, ctrl := createFixtures(t) + defer reporter.recoverUnexpectedFatal() + subject := new(Subject) + + ctrl.RecordCall(subject, "FooMethod", "argument") + reporter.assertFatal(func() { + // This call is made with the wrong number of arguments... + ctrl.Call(subject, "FooMethod", "argument", "extra_argument") + }) + reporter.assertFatal(func() { + // ... so is this. + ctrl.Call(subject, "FooMethod") + }) + reporter.assertFatal(func() { + // The expected call wasn't made. + ctrl.Finish() + }) +} + +func TestAnyTimes(t *testing.T) { + reporter, ctrl := createFixtures(t) + subject := new(Subject) + + ctrl.RecordCall(subject, "FooMethod", "argument").AnyTimes() + for i := 0; i < 100; i++ { + ctrl.Call(subject, "FooMethod", "argument") + } + reporter.assertPass("After 100 method calls.") + ctrl.Finish() +} + +func TestMinTimes1(t *testing.T) { + // It fails if there are no calls + reporter, ctrl := createFixtures(t) + subject := new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) + reporter.assertFatal(func() { + ctrl.Finish() + }) + + // It succeeds if there is one call + reporter, ctrl = createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Finish() + + // It succeeds if there are many calls + reporter, ctrl = createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) + for i := 0; i < 100; i++ { + ctrl.Call(subject, "FooMethod", "argument") + } + ctrl.Finish() +} + +func TestMaxTimes1(t *testing.T) { + // It succeeds if there are no calls + _, ctrl := createFixtures(t) + subject := new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) + ctrl.Finish() + + // It succeeds if there is one call + _, ctrl = createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Finish() + + //It fails if there are more + reporter, ctrl := createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) + ctrl.Call(subject, "FooMethod", "argument") + reporter.assertFatal(func() { + ctrl.Call(subject, "FooMethod", "argument") + }) + ctrl.Finish() +} + +func TestMinMaxTimes(t *testing.T) { + // It fails if there are less calls than specified + reporter, ctrl := createFixtures(t) + subject := new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2) + ctrl.Call(subject, "FooMethod", "argument") + reporter.assertFatal(func() { + ctrl.Finish() + }) + + // It fails if there are more calls than specified + reporter, ctrl = createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2) + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Call(subject, "FooMethod", "argument") + reporter.assertFatal(func() { + ctrl.Call(subject, "FooMethod", "argument") + }) + + // It succeeds if there is just the right number of calls + reporter, ctrl = createFixtures(t) + subject = new(Subject) + ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(2).MinTimes(2) + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Call(subject, "FooMethod", "argument") + ctrl.Finish() +} + +func TestDo(t *testing.T) { + _, ctrl := createFixtures(t) + subject := new(Subject) + + doCalled := false + var argument string + ctrl.RecordCall(subject, "FooMethod", "argument").Do( + func(arg string) { + doCalled = true + argument = arg + }) + if doCalled { + t.Error("Do() callback called too early.") + } + + ctrl.Call(subject, "FooMethod", "argument") + + if !doCalled { + t.Error("Do() callback not called.") + } + if "argument" != argument { + t.Error("Do callback received wrong argument.") + } + + ctrl.Finish() +} + +func TestReturn(t *testing.T) { + _, ctrl := createFixtures(t) + subject := new(Subject) + + // Unspecified return should produce "zero" result. + ctrl.RecordCall(subject, "FooMethod", "zero") + ctrl.RecordCall(subject, "FooMethod", "five").Return(5) + + assertEqual( + t, + []interface{}{0}, + ctrl.Call(subject, "FooMethod", "zero")) + + assertEqual( + t, + []interface{}{5}, + ctrl.Call(subject, "FooMethod", "five")) + ctrl.Finish() +} + +func TestUnorderedCalls(t *testing.T) { + reporter, ctrl := createFixtures(t) + defer reporter.recoverUnexpectedFatal() + subjectTwo := new(Subject) + subjectOne := new(Subject) + + ctrl.RecordCall(subjectOne, "FooMethod", "1") + ctrl.RecordCall(subjectOne, "BarMethod", "2") + ctrl.RecordCall(subjectTwo, "FooMethod", "3") + ctrl.RecordCall(subjectTwo, "BarMethod", "4") + + // Make the calls in a different order, which should be fine. + ctrl.Call(subjectOne, "BarMethod", "2") + ctrl.Call(subjectTwo, "FooMethod", "3") + ctrl.Call(subjectTwo, "BarMethod", "4") + ctrl.Call(subjectOne, "FooMethod", "1") + + reporter.assertPass("After making all calls in different order") + + ctrl.Finish() + + reporter.assertPass("After finish") +} + +func commonTestOrderedCalls(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller, subjectOne, subjectTwo *Subject) { + reporter, ctrl = createFixtures(t) + + subjectOne = new(Subject) + subjectTwo = new(Subject) + + gomock.InOrder( + ctrl.RecordCall(subjectOne, "FooMethod", "1").AnyTimes(), + ctrl.RecordCall(subjectTwo, "FooMethod", "2"), + ctrl.RecordCall(subjectTwo, "BarMethod", "3"), + ) + + return +} + +func TestOrderedCallsCorrect(t *testing.T) { + reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) + + ctrl.Call(subjectOne, "FooMethod", "1") + ctrl.Call(subjectTwo, "FooMethod", "2") + ctrl.Call(subjectTwo, "BarMethod", "3") + + ctrl.Finish() + + reporter.assertPass("After finish") +} + +func TestOrderedCallsInCorrect(t *testing.T) { + reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) + + ctrl.Call(subjectOne, "FooMethod", "1") + reporter.assertFatal(func() { + ctrl.Call(subjectTwo, "BarMethod", "3") + }) +} + +// Test that calls that are prerequites to other calls but have maxCalls > +// minCalls are removed from the expected call set. +func TestOrderedCallsWithPreReqMaxUnbounded(t *testing.T) { + reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) + + // Initially we should be able to call FooMethod("1") as many times as we + // want. + ctrl.Call(subjectOne, "FooMethod", "1") + ctrl.Call(subjectOne, "FooMethod", "1") + + // But calling something that has it as a prerequite should remove it from + // the expected call set. This allows tests to ensure that FooMethod("1") is + // *not* called after FooMethod("2"). + ctrl.Call(subjectTwo, "FooMethod", "2") + + // Therefore this call should fail: + reporter.assertFatal(func() { + ctrl.Call(subjectOne, "FooMethod", "1") + }) +} + +func TestCallAfterLoopPanic(t *testing.T) { + _, ctrl := createFixtures(t) + + subject := new(Subject) + + firstCall := ctrl.RecordCall(subject, "FooMethod", "1") + secondCall := ctrl.RecordCall(subject, "FooMethod", "2") + thirdCall := ctrl.RecordCall(subject, "FooMethod", "3") + + gomock.InOrder(firstCall, secondCall, thirdCall) + + defer func() { + err := recover() + if err == nil { + t.Error("Call.After creation of dependency loop did not panic.") + } + }() + + // This should panic due to dependency loop. + firstCall.After(thirdCall) +} + +func TestPanicOverridesExpectationChecks(t *testing.T) { + ctrl := gomock.NewController(t) + reporter := NewErrorReporter(t) + + reporter.assertFatal(func() { + ctrl.RecordCall(new(Subject), "FooMethod", "1") + defer ctrl.Finish() + reporter.Fatalf("Intentional panic") + }) +} + +func TestSetArgWithBadType(t *testing.T) { + rep, ctrl := createFixtures(t) + defer ctrl.Finish() + + s := new(Subject) + // This should catch a type error: + rep.assertFatal(func() { + ctrl.RecordCall(s, "FooMethod", "1").SetArg(0, "blah") + }) + ctrl.Call(s, "FooMethod", "1") +} + +func TestTimes0(t *testing.T) { + rep, ctrl := createFixtures(t) + defer ctrl.Finish() + + s := new(Subject) + ctrl.RecordCall(s, "FooMethod", "arg").Times(0) + rep.assertFatal(func() { + ctrl.Call(s, "FooMethod", "arg") + }) +} diff --git a/vendor/github.com/golang/mock/gomock/matchers.go b/vendor/github.com/golang/mock/gomock/matchers.go new file mode 100644 index 0000000000..e8b1ddccf0 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/matchers.go @@ -0,0 +1,99 @@ +//go:generate mockgen -destination mock_matcher/mock_matcher.go github.com/golang/mock/gomock Matcher + +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +import ( + "fmt" + "reflect" +) + +// A Matcher is a representation of a class of values. +// It is used to represent the valid or expected arguments to a mocked method. +type Matcher interface { + // Matches returns whether x is a match. + Matches(x interface{}) bool + + // String describes what the matcher matches. + String() string +} + +type anyMatcher struct{} + +func (anyMatcher) Matches(x interface{}) bool { + return true +} + +func (anyMatcher) String() string { + return "is anything" +} + +type eqMatcher struct { + x interface{} +} + +func (e eqMatcher) Matches(x interface{}) bool { + return reflect.DeepEqual(e.x, x) +} + +func (e eqMatcher) String() string { + return fmt.Sprintf("is equal to %v", e.x) +} + +type nilMatcher struct{} + +func (nilMatcher) Matches(x interface{}) bool { + if x == nil { + return true + } + + v := reflect.ValueOf(x) + switch v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, + reflect.Ptr, reflect.Slice: + return v.IsNil() + } + + return false +} + +func (nilMatcher) String() string { + return "is nil" +} + +type notMatcher struct { + m Matcher +} + +func (n notMatcher) Matches(x interface{}) bool { + return !n.m.Matches(x) +} + +func (n notMatcher) String() string { + // TODO: Improve this if we add a NotString method to the Matcher interface. + return "not(" + n.m.String() + ")" +} + +// Constructors +func Any() Matcher { return anyMatcher{} } +func Eq(x interface{}) Matcher { return eqMatcher{x} } +func Nil() Matcher { return nilMatcher{} } +func Not(x interface{}) Matcher { + if m, ok := x.(Matcher); ok { + return notMatcher{m} + } + return notMatcher{Eq(x)} +} diff --git a/vendor/github.com/golang/mock/gomock/matchers_test.go b/vendor/github.com/golang/mock/gomock/matchers_test.go new file mode 100644 index 0000000000..29b97fb9c8 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/matchers_test.go @@ -0,0 +1,70 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock_test + +import ( + "errors" + "testing" + + "github.com/golang/mock/gomock" + mock_matcher "github.com/golang/mock/gomock/mock_matcher" +) + +func TestMatchers(t *testing.T) { + type e interface{} + type testCase struct { + matcher gomock.Matcher + yes, no []e + } + tests := []testCase{ + testCase{gomock.Any(), []e{3, nil, "foo"}, nil}, + testCase{gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}}, + testCase{gomock.Nil(), + []e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)}, + []e{"", 0, make(chan bool), errors.New("err"), new(int)}}, + testCase{gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}}, + } + for i, test := range tests { + for _, x := range test.yes { + if !test.matcher.Matches(x) { + t.Errorf(`test %d: "%v %s" should be true.`, i, x, test.matcher) + } + } + for _, x := range test.no { + if test.matcher.Matches(x) { + t.Errorf(`test %d: "%v %s" should be false.`, i, x, test.matcher) + } + } + } +} + +// A more thorough test of notMatcher +func TestNotMatcher(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockMatcher := mock_matcher.NewMockMatcher(ctrl) + notMatcher := gomock.Not(mockMatcher) + + mockMatcher.EXPECT().Matches(4).Return(true) + if match := notMatcher.Matches(4); match { + t.Errorf("notMatcher should not match 4") + } + + mockMatcher.EXPECT().Matches(5).Return(false) + if match := notMatcher.Matches(5); !match { + t.Errorf("notMatcher should match 5") + } +} diff --git a/vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go b/vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go new file mode 100644 index 0000000000..d0bf885fb6 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go @@ -0,0 +1,56 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/golang/mock/gomock (interfaces: Matcher) + +package mock_gomock + +import ( + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockMatcher is a mock of Matcher interface +type MockMatcher struct { + ctrl *gomock.Controller + recorder *MockMatcherMockRecorder +} + +// MockMatcherMockRecorder is the mock recorder for MockMatcher +type MockMatcherMockRecorder struct { + mock *MockMatcher +} + +// NewMockMatcher creates a new mock instance +func NewMockMatcher(ctrl *gomock.Controller) *MockMatcher { + mock := &MockMatcher{ctrl: ctrl} + mock.recorder = &MockMatcherMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *MockMatcher) EXPECT() *MockMatcherMockRecorder { + return _m.recorder +} + +// Matches mocks base method +func (_m *MockMatcher) Matches(_param0 interface{}) bool { + ret := _m.ctrl.Call(_m, "Matches", _param0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Matches indicates an expected call of Matches +func (_mr *MockMatcherMockRecorder) Matches(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Matches", reflect.TypeOf((*MockMatcher)(nil).Matches), arg0) +} + +// String mocks base method +func (_m *MockMatcher) String() string { + ret := _m.ctrl.Call(_m, "String") + ret0, _ := ret[0].(string) + return ret0 +} + +// String indicates an expected call of String +func (_mr *MockMatcherMockRecorder) String() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "String", reflect.TypeOf((*MockMatcher)(nil).String)) +} diff --git a/vendor/github.com/golang/mock/mockgen/mockgen.go b/vendor/github.com/golang/mock/mockgen/mockgen.go new file mode 100644 index 0000000000..3b08c1411a --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/mockgen.go @@ -0,0 +1,442 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// MockGen generates mock implementations of Go interfaces. +package main + +// TODO: This does not support recursive embedded interfaces. +// TODO: This does not support embedding package-local interfaces in a separate file. + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "go/token" + "io" + "log" + "os" + "path" + "sort" + "strconv" + "strings" + "unicode" + + "github.com/golang/mock/mockgen/model" +) + +const ( + gomockImportPath = "github.com/golang/mock/gomock" +) + +var ( + source = flag.String("source", "", "(source mode) Input Go source file; enables source mode.") + destination = flag.String("destination", "", "Output file; defaults to stdout.") + packageOut = flag.String("package", "", "Package of the generated code; defaults to the package of the input with a 'mock_' prefix.") + selfPackage = flag.String("self_package", "", "If set, the package this mock will be part of.") + + debugParser = flag.Bool("debug_parser", false, "Print out parser results only.") +) + +func main() { + flag.Usage = usage + flag.Parse() + + var pkg *model.Package + var err error + if *source != "" { + pkg, err = ParseFile(*source) + } else { + if flag.NArg() != 2 { + usage() + log.Fatal("Expected exactly two arguments") + } + pkg, err = Reflect(flag.Arg(0), strings.Split(flag.Arg(1), ",")) + } + if err != nil { + log.Fatalf("Loading input failed: %v", err) + } + + if *debugParser { + pkg.Print(os.Stdout) + return + } + + dst := os.Stdout + if len(*destination) > 0 { + f, err := os.Create(*destination) + if err != nil { + log.Fatalf("Failed opening destination file: %v", err) + } + defer f.Close() + dst = f + } + + packageName := *packageOut + if packageName == "" { + // pkg.Name in reflect mode is the base name of the import path, + // which might have characters that are illegal to have in package names. + packageName = "mock_" + sanitize(pkg.Name) + } + + g := new(generator) + if *source != "" { + g.filename = *source + } else { + g.srcPackage = flag.Arg(0) + g.srcInterfaces = flag.Arg(1) + } + if err := g.Generate(pkg, packageName); err != nil { + log.Fatalf("Failed generating mock: %v", err) + } + if _, err := dst.Write(g.Output()); err != nil { + log.Fatalf("Failed writing to destination: %v", err) + } +} + +func usage() { + io.WriteString(os.Stderr, usageText) + flag.PrintDefaults() +} + +const usageText = `mockgen has two modes of operation: source and reflect. + +Source mode generates mock interfaces from a source file. +It is enabled by using the -source flag. Other flags that +may be useful in this mode are -imports and -aux_files. +Example: + mockgen -source=foo.go [other options] + +Reflect mode generates mock interfaces by building a program +that uses reflection to understand interfaces. It is enabled +by passing two non-flag arguments: an import path, and a +comma-separated list of symbols. +Example: + mockgen database/sql/driver Conn,Driver + +` + +type generator struct { + buf bytes.Buffer + indent string + + filename string // may be empty + srcPackage, srcInterfaces string // may be empty + + packageMap map[string]string // map from import path to package name +} + +func (g *generator) p(format string, args ...interface{}) { + fmt.Fprintf(&g.buf, g.indent+format+"\n", args...) +} + +func (g *generator) in() { + g.indent += "\t" +} + +func (g *generator) out() { + if len(g.indent) > 0 { + g.indent = g.indent[0 : len(g.indent)-1] + } +} + +func removeDot(s string) string { + if len(s) > 0 && s[len(s)-1] == '.' { + return s[0 : len(s)-1] + } + return s +} + +// sanitize cleans up a string to make a suitable package name. +func sanitize(s string) string { + t := "" + for _, r := range s { + if t == "" { + if unicode.IsLetter(r) || r == '_' { + t += string(r) + continue + } + } else { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { + t += string(r) + continue + } + } + t += "_" + } + if t == "_" { + t = "x" + } + return t +} + +func (g *generator) Generate(pkg *model.Package, pkgName string) error { + g.p("// Code generated by MockGen. DO NOT EDIT.") + if g.filename != "" { + g.p("// Source: %v", g.filename) + } else { + g.p("// Source: %v (interfaces: %v)", g.srcPackage, g.srcInterfaces) + } + g.p("") + + // Get all required imports, and generate unique names for them all. + im := pkg.Imports() + im[gomockImportPath] = true + im["reflect"] = true + + // Sort keys to make import alias generation predictable + sorted_paths := make([]string, len(im), len(im)) + x := 0 + for pth := range im { + sorted_paths[x] = pth + x++ + } + sort.Strings(sorted_paths) + + g.packageMap = make(map[string]string, len(im)) + localNames := make(map[string]bool, len(im)) + for _, pth := range sorted_paths { + base := sanitize(path.Base(pth)) + + // Local names for an imported package can usually be the basename of the import path. + // A couple of situations don't permit that, such as duplicate local names + // (e.g. importing "html/template" and "text/template"), or where the basename is + // a keyword (e.g. "foo/case"). + // try base0, base1, ... + pkgName := base + i := 0 + for localNames[pkgName] || token.Lookup(pkgName).IsKeyword() { + pkgName = base + strconv.Itoa(i) + i++ + } + + g.packageMap[pth] = pkgName + localNames[pkgName] = true + } + + g.p("package %v", pkgName) + g.p("") + g.p("import (") + g.in() + for path, pkg := range g.packageMap { + if path == *selfPackage { + continue + } + g.p("%v %q", pkg, path) + } + for _, path := range pkg.DotImports { + g.p(". %q", path) + } + g.out() + g.p(")") + + for _, intf := range pkg.Interfaces { + if err := g.GenerateMockInterface(intf); err != nil { + return err + } + } + + return nil +} + +// The name of the mock type to use for the given interface identifier. +func mockName(typeName string) string { + return "Mock" + typeName +} + +func (g *generator) GenerateMockInterface(intf *model.Interface) error { + mockType := mockName(intf.Name) + + g.p("") + g.p("// %v is a mock of %v interface", mockType, intf.Name) + g.p("type %v struct {", mockType) + g.in() + g.p("ctrl *gomock.Controller") + g.p("recorder *%vMockRecorder", mockType) + g.out() + g.p("}") + g.p("") + + g.p("// %vMockRecorder is the mock recorder for %v", mockType, mockType) + g.p("type %vMockRecorder struct {", mockType) + g.in() + g.p("mock *%v", mockType) + g.out() + g.p("}") + g.p("") + + // TODO: Re-enable this if we can import the interface reliably. + //g.p("// Verify that the mock satisfies the interface at compile time.") + //g.p("var _ %v = (*%v)(nil)", typeName, mockType) + //g.p("") + + g.p("// New%v creates a new mock instance", mockType) + g.p("func New%v(ctrl *gomock.Controller) *%v {", mockType, mockType) + g.in() + g.p("mock := &%v{ctrl: ctrl}", mockType) + g.p("mock.recorder = &%vMockRecorder{mock}", mockType) + g.p("return mock") + g.out() + g.p("}") + g.p("") + + // XXX: possible name collision here if someone has EXPECT in their interface. + g.p("// EXPECT returns an object that allows the caller to indicate expected use") + g.p("func (_m *%v) EXPECT() *%vMockRecorder {", mockType, mockType) + g.in() + g.p("return _m.recorder") + g.out() + g.p("}") + + g.GenerateMockMethods(mockType, intf, *selfPackage) + + return nil +} + +func (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride string) { + for _, m := range intf.Methods { + g.p("") + g.GenerateMockMethod(mockType, m, pkgOverride) + g.p("") + g.GenerateMockRecorderMethod(mockType, m) + } +} + +// GenerateMockMethod generates a mock method implementation. +// If non-empty, pkgOverride is the package in which unqualified types reside. +func (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride string) error { + args := make([]string, len(m.In)) + argNames := make([]string, len(m.In)) + for i, p := range m.In { + name := p.Name + if name == "" { + name = fmt.Sprintf("_param%d", i) + } + ts := p.Type.String(g.packageMap, pkgOverride) + args[i] = name + " " + ts + argNames[i] = name + } + if m.Variadic != nil { + name := m.Variadic.Name + if name == "" { + name = fmt.Sprintf("_param%d", len(m.In)) + } + ts := m.Variadic.Type.String(g.packageMap, pkgOverride) + args = append(args, name+" ..."+ts) + argNames = append(argNames, name) + } + argString := strings.Join(args, ", ") + + rets := make([]string, len(m.Out)) + for i, p := range m.Out { + rets[i] = p.Type.String(g.packageMap, pkgOverride) + } + retString := strings.Join(rets, ", ") + if len(rets) > 1 { + retString = "(" + retString + ")" + } + if retString != "" { + retString = " " + retString + } + + g.p("// %v mocks base method", m.Name) + g.p("func (_m *%v) %v(%v)%v {", mockType, m.Name, argString, retString) + g.in() + + callArgs := strings.Join(argNames, ", ") + if callArgs != "" { + callArgs = ", " + callArgs + } + if m.Variadic != nil { + // Non-trivial. The generated code must build a []interface{}, + // but the variadic argument may be any type. + g.p("_s := []interface{}{%s}", strings.Join(argNames[:len(argNames)-1], ", ")) + g.p("for _, _x := range %s {", argNames[len(argNames)-1]) + g.in() + g.p("_s = append(_s, _x)") + g.out() + g.p("}") + callArgs = ", _s..." + } + if len(m.Out) == 0 { + g.p(`_m.ctrl.Call(_m, "%v"%v)`, m.Name, callArgs) + } else { + g.p(`ret := _m.ctrl.Call(_m, "%v"%v)`, m.Name, callArgs) + + // Go does not allow "naked" type assertions on nil values, so we use the two-value form here. + // The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T. + // Happily, this coincides with the semantics we want here. + retNames := make([]string, len(rets)) + for i, t := range rets { + retNames[i] = fmt.Sprintf("ret%d", i) + g.p("%s, _ := ret[%d].(%s)", retNames[i], i, t) + } + g.p("return " + strings.Join(retNames, ", ")) + } + + g.out() + g.p("}") + return nil +} + +func (g *generator) GenerateMockRecorderMethod(mockType string, m *model.Method) error { + nargs := len(m.In) + args := make([]string, nargs) + for i := 0; i < nargs; i++ { + args[i] = "arg" + strconv.Itoa(i) + } + argString := strings.Join(args, ", ") + if nargs > 0 { + argString += " interface{}" + } + if m.Variadic != nil { + if nargs > 0 { + argString += ", " + } + argString += fmt.Sprintf("arg%d ...interface{}", nargs) + } + + g.p("// %v indicates an expected call of %v", m.Name, m.Name) + g.p("func (_mr *%vMockRecorder) %v(%v) *gomock.Call {", mockType, m.Name, argString) + g.in() + + callArgs := strings.Join(args, ", ") + if nargs > 0 { + callArgs = ", " + callArgs + } + if m.Variadic != nil { + if nargs == 0 { + // Easy: just use ... to push the arguments through. + callArgs = ", arg0..." + } else { + // Hard: create a temporary slice. + g.p("_s := append([]interface{}{%s}, arg%d...)", strings.Join(args, ", "), nargs) + callArgs = ", _s..." + } + } + g.p(`return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "%s", reflect.TypeOf((*%s)(nil).%s)%s)`, m.Name, mockType, m.Name, callArgs) + + g.out() + g.p("}") + return nil +} + +// Output returns the generator's output, formatted in the standard Go style. +func (g *generator) Output() []byte { + src, err := format.Source(g.buf.Bytes()) + if err != nil { + log.Fatalf("Failed to format generated source code: %s\n%s", err, g.buf.String()) + } + return src +} diff --git a/vendor/github.com/golang/mock/mockgen/model/model.go b/vendor/github.com/golang/mock/mockgen/model/model.go new file mode 100644 index 0000000000..0e69d66e66 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/model/model.go @@ -0,0 +1,431 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package model contains the data model necessary for generating mock implementations. +package model + +import ( + "encoding/gob" + "fmt" + "io" + "reflect" + "strings" +) + +// Package is a Go package. It may be a subset. +type Package struct { + Name string + Interfaces []*Interface + DotImports []string +} + +func (pkg *Package) Print(w io.Writer) { + fmt.Fprintf(w, "package %s\n", pkg.Name) + for _, intf := range pkg.Interfaces { + intf.Print(w) + } +} + +// Imports returns the imports needed by the Package as a set of import paths. +func (pkg *Package) Imports() map[string]bool { + im := make(map[string]bool) + for _, intf := range pkg.Interfaces { + intf.addImports(im) + } + return im +} + +// Interface is a Go interface. +type Interface struct { + Name string + Methods []*Method +} + +func (intf *Interface) Print(w io.Writer) { + fmt.Fprintf(w, "interface %s\n", intf.Name) + for _, m := range intf.Methods { + m.Print(w) + } +} + +func (intf *Interface) addImports(im map[string]bool) { + for _, m := range intf.Methods { + m.addImports(im) + } +} + +// Method is a single method of an interface. +type Method struct { + Name string + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +func (m *Method) Print(w io.Writer) { + fmt.Fprintf(w, " - method %s\n", m.Name) + if len(m.In) > 0 { + fmt.Fprintf(w, " in:\n") + for _, p := range m.In { + p.Print(w) + } + } + if m.Variadic != nil { + fmt.Fprintf(w, " ...:\n") + m.Variadic.Print(w) + } + if len(m.Out) > 0 { + fmt.Fprintf(w, " out:\n") + for _, p := range m.Out { + p.Print(w) + } + } +} + +func (m *Method) addImports(im map[string]bool) { + for _, p := range m.In { + p.Type.addImports(im) + } + if m.Variadic != nil { + m.Variadic.Type.addImports(im) + } + for _, p := range m.Out { + p.Type.addImports(im) + } +} + +// Parameter is an argument or return parameter of a method. +type Parameter struct { + Name string // may be empty + Type Type +} + +func (p *Parameter) Print(w io.Writer) { + n := p.Name + if n == "" { + n = `""` + } + fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, "")) +} + +// Type is a Go type. +type Type interface { + String(pm map[string]string, pkgOverride string) string + addImports(im map[string]bool) +} + +func init() { + gob.Register(&ArrayType{}) + gob.Register(&ChanType{}) + gob.Register(&FuncType{}) + gob.Register(&MapType{}) + gob.Register(&NamedType{}) + gob.Register(&PointerType{}) + gob.Register(PredeclaredType("")) +} + +// ArrayType is an array or slice type. +type ArrayType struct { + Len int // -1 for slices, >= 0 for arrays + Type Type +} + +func (at *ArrayType) String(pm map[string]string, pkgOverride string) string { + s := "[]" + if at.Len > -1 { + s = fmt.Sprintf("[%d]", at.Len) + } + return s + at.Type.String(pm, pkgOverride) +} + +func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) } + +// ChanType is a channel type. +type ChanType struct { + Dir ChanDir // 0, 1 or 2 + Type Type +} + +func (ct *ChanType) String(pm map[string]string, pkgOverride string) string { + s := ct.Type.String(pm, pkgOverride) + if ct.Dir == RecvDir { + return "<-chan " + s + } + if ct.Dir == SendDir { + return "chan<- " + s + } + return "chan " + s +} + +func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) } + +// ChanDir is a channel direction. +type ChanDir int + +const ( + RecvDir ChanDir = 1 + SendDir ChanDir = 2 +) + +// FuncType is a function type. +type FuncType struct { + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +func (ft *FuncType) String(pm map[string]string, pkgOverride string) string { + args := make([]string, len(ft.In)) + for i, p := range ft.In { + args[i] = p.Type.String(pm, pkgOverride) + } + if ft.Variadic != nil { + args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride)) + } + rets := make([]string, len(ft.Out)) + for i, p := range ft.Out { + rets[i] = p.Type.String(pm, pkgOverride) + } + retString := strings.Join(rets, ", ") + if nOut := len(ft.Out); nOut == 1 { + retString = " " + retString + } else if nOut > 1 { + retString = " (" + retString + ")" + } + return "func(" + strings.Join(args, ", ") + ")" + retString +} + +func (ft *FuncType) addImports(im map[string]bool) { + for _, p := range ft.In { + p.Type.addImports(im) + } + if ft.Variadic != nil { + ft.Variadic.Type.addImports(im) + } + for _, p := range ft.Out { + p.Type.addImports(im) + } +} + +// MapType is a map type. +type MapType struct { + Key, Value Type +} + +func (mt *MapType) String(pm map[string]string, pkgOverride string) string { + return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride) +} + +func (mt *MapType) addImports(im map[string]bool) { + mt.Key.addImports(im) + mt.Value.addImports(im) +} + +// NamedType is an exported type in a package. +type NamedType struct { + Package string // may be empty + Type string // TODO: should this be typed Type? +} + +func (nt *NamedType) String(pm map[string]string, pkgOverride string) string { + // TODO: is this right? + if pkgOverride == nt.Package { + return nt.Type + } + return pm[nt.Package] + "." + nt.Type +} +func (nt *NamedType) addImports(im map[string]bool) { + if nt.Package != "" { + im[nt.Package] = true + } +} + +// PointerType is a pointer to another type. +type PointerType struct { + Type Type +} + +func (pt *PointerType) String(pm map[string]string, pkgOverride string) string { + return "*" + pt.Type.String(pm, pkgOverride) +} +func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) } + +// PredeclaredType is a predeclared type such as "int". +type PredeclaredType string + +func (pt PredeclaredType) String(pm map[string]string, pkgOverride string) string { return string(pt) } +func (pt PredeclaredType) addImports(im map[string]bool) {} + +// The following code is intended to be called by the program generated by ../reflect.go. + +func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) { + if it.Kind() != reflect.Interface { + return nil, fmt.Errorf("%v is not an interface", it) + } + intf := &Interface{} + + for i := 0; i < it.NumMethod(); i++ { + mt := it.Method(i) + // TODO: need to skip unexported methods? or just raise an error? + m := &Method{ + Name: mt.Name, + } + + var err error + m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type) + if err != nil { + return nil, err + } + + intf.Methods = append(intf.Methods, m) + } + + return intf, nil +} + +// t's Kind must be a reflect.Func. +func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { + nin := t.NumIn() + if t.IsVariadic() { + nin-- + } + var p *Parameter + for i := 0; i < nin; i++ { + p, err = parameterFromType(t.In(i)) + if err != nil { + return + } + in = append(in, p) + } + if t.IsVariadic() { + p, err = parameterFromType(t.In(nin).Elem()) + if err != nil { + return + } + variadic = p + } + for i := 0; i < t.NumOut(); i++ { + p, err = parameterFromType(t.Out(i)) + if err != nil { + return + } + out = append(out, p) + } + return +} + +func parameterFromType(t reflect.Type) (*Parameter, error) { + tt, err := typeFromType(t) + if err != nil { + return nil, err + } + return &Parameter{Type: tt}, nil +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +var byteType = reflect.TypeOf(byte(0)) + +func typeFromType(t reflect.Type) (Type, error) { + // Hack workaround for https://golang.org/issue/3853. + // This explicit check should not be necessary. + if t == byteType { + return PredeclaredType("byte"), nil + } + + if imp := t.PkgPath(); imp != "" { + return &NamedType{ + Package: imp, + Type: t.Name(), + }, nil + } + + // only unnamed or predeclared types after here + + // Lots of types have element types. Let's do the parsing and error checking for all of them. + var elemType Type + switch t.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice: + var err error + elemType, err = typeFromType(t.Elem()) + if err != nil { + return nil, err + } + } + + switch t.Kind() { + case reflect.Array: + return &ArrayType{ + Len: t.Len(), + Type: elemType, + }, nil + case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String: + return PredeclaredType(t.Kind().String()), nil + case reflect.Chan: + var dir ChanDir + switch t.ChanDir() { + case reflect.RecvDir: + dir = RecvDir + case reflect.SendDir: + dir = SendDir + } + return &ChanType{ + Dir: dir, + Type: elemType, + }, nil + case reflect.Func: + in, variadic, out, err := funcArgsFromType(t) + if err != nil { + return nil, err + } + return &FuncType{ + In: in, + Out: out, + Variadic: variadic, + }, nil + case reflect.Interface: + // Two special interfaces. + if t.NumMethod() == 0 { + return PredeclaredType("interface{}"), nil + } + if t == errorType { + return PredeclaredType("error"), nil + } + case reflect.Map: + kt, err := typeFromType(t.Key()) + if err != nil { + return nil, err + } + return &MapType{ + Key: kt, + Value: elemType, + }, nil + case reflect.Ptr: + return &PointerType{ + Type: elemType, + }, nil + case reflect.Slice: + return &ArrayType{ + Len: -1, + Type: elemType, + }, nil + case reflect.Struct: + if t.NumField() == 0 { + return PredeclaredType("struct{}"), nil + } + } + + // TODO: Struct, UnsafePointer + return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind()) +} diff --git a/vendor/github.com/golang/mock/mockgen/parse.go b/vendor/github.com/golang/mock/mockgen/parse.go new file mode 100644 index 0000000000..5615d4b337 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/parse.go @@ -0,0 +1,447 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// This file contains the model construction by parsing source files. + +import ( + "flag" + "fmt" + "go/ast" + "go/parser" + "go/token" + "log" + "path" + "strconv" + "strings" + + "github.com/golang/mock/mockgen/model" +) + +var ( + imports = flag.String("imports", "", "(source mode) Comma-separated name=path pairs of explicit imports to use.") + auxFiles = flag.String("aux_files", "", "(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.") +) + +// TODO: simplify error reporting + +func ParseFile(source string) (*model.Package, error) { + fs := token.NewFileSet() + file, err := parser.ParseFile(fs, source, nil, 0) + if err != nil { + return nil, fmt.Errorf("failed parsing source file %v: %v", source, err) + } + + p := &fileParser{ + fileSet: fs, + imports: make(map[string]string), + auxInterfaces: make(map[string]map[string]*ast.InterfaceType), + } + + // Handle -imports. + dotImports := make(map[string]bool) + if *imports != "" { + for _, kv := range strings.Split(*imports, ",") { + eq := strings.Index(kv, "=") + k, v := kv[:eq], kv[eq+1:] + if k == "." { + // TODO: Catch dupes? + dotImports[v] = true + } else { + // TODO: Catch dupes? + p.imports[k] = v + } + } + } + + // Handle -aux_files. + if err := p.parseAuxFiles(*auxFiles); err != nil { + return nil, err + } + p.addAuxInterfacesFromFile("", file) // this file + + pkg, err := p.parseFile(file) + if err != nil { + return nil, err + } + pkg.DotImports = make([]string, 0, len(dotImports)) + for path := range dotImports { + pkg.DotImports = append(pkg.DotImports, path) + } + return pkg, nil +} + +type fileParser struct { + fileSet *token.FileSet + imports map[string]string // package name => import path + + auxFiles []*ast.File + auxInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface +} + +func (p *fileParser) errorf(pos token.Pos, format string, args ...interface{}) error { + ps := p.fileSet.Position(pos) + format = "%s:%d:%d: " + format + args = append([]interface{}{ps.Filename, ps.Line, ps.Column}, args...) + return fmt.Errorf(format, args...) +} + +func (p *fileParser) parseAuxFiles(auxFiles string) error { + auxFiles = strings.TrimSpace(auxFiles) + if auxFiles == "" { + return nil + } + for _, kv := range strings.Split(auxFiles, ",") { + parts := strings.SplitN(kv, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("bad aux file spec: %v", kv) + } + file, err := parser.ParseFile(p.fileSet, parts[1], nil, 0) + if err != nil { + return err + } + p.auxFiles = append(p.auxFiles, file) + p.addAuxInterfacesFromFile(parts[0], file) + } + return nil +} + +func (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) { + if _, ok := p.auxInterfaces[pkg]; !ok { + p.auxInterfaces[pkg] = make(map[string]*ast.InterfaceType) + } + for ni := range iterInterfaces(file) { + p.auxInterfaces[pkg][ni.name.Name] = ni.it + } +} + +func (p *fileParser) parseFile(file *ast.File) (*model.Package, error) { + allImports := importsOfFile(file) + // Don't stomp imports provided by -imports. Those should take precedence. + for pkg, path := range allImports { + if _, ok := p.imports[pkg]; !ok { + p.imports[pkg] = path + } + } + // Add imports from auxiliary files, which might be needed for embedded interfaces. + // Don't stomp any other imports. + for _, f := range p.auxFiles { + for pkg, path := range importsOfFile(f) { + if _, ok := p.imports[pkg]; !ok { + p.imports[pkg] = path + } + } + } + + var is []*model.Interface + for ni := range iterInterfaces(file) { + i, err := p.parseInterface(ni.name.String(), "", ni.it) + if err != nil { + return nil, err + } + is = append(is, i) + } + return &model.Package{ + Name: file.Name.String(), + Interfaces: is, + }, nil +} + +func (p *fileParser) parseInterface(name, pkg string, it *ast.InterfaceType) (*model.Interface, error) { + intf := &model.Interface{Name: name} + for _, field := range it.Methods.List { + switch v := field.Type.(type) { + case *ast.FuncType: + if nn := len(field.Names); nn != 1 { + return nil, fmt.Errorf("expected one name for interface %v, got %d", intf.Name, nn) + } + m := &model.Method{ + Name: field.Names[0].String(), + } + var err error + m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v) + if err != nil { + return nil, err + } + intf.Methods = append(intf.Methods, m) + case *ast.Ident: + // Embedded interface in this package. + ei := p.auxInterfaces[""][v.String()] + if ei == nil { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s", v.String()) + } + eintf, err := p.parseInterface(v.String(), pkg, ei) + if err != nil { + return nil, err + } + // Copy the methods. + // TODO: apply shadowing rules. + for _, m := range eintf.Methods { + intf.Methods = append(intf.Methods, m) + } + case *ast.SelectorExpr: + // Embedded interface in another package. + fpkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() + ei := p.auxInterfaces[fpkg][sel] + if ei == nil { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", fpkg, sel) + } + epkg, ok := p.imports[fpkg] + if !ok { + return nil, p.errorf(v.X.Pos(), "unknown package %s", fpkg) + } + eintf, err := p.parseInterface(sel, epkg, ei) + if err != nil { + return nil, err + } + // Copy the methods. + // TODO: apply shadowing rules. + for _, m := range eintf.Methods { + intf.Methods = append(intf.Methods, m) + } + default: + return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) + } + } + return intf, nil +} + +func (p *fileParser) parseFunc(pkg string, f *ast.FuncType) (in []*model.Parameter, variadic *model.Parameter, out []*model.Parameter, err error) { + if f.Params != nil { + regParams := f.Params.List + if isVariadic(f) { + n := len(regParams) + varParams := regParams[n-1:] + regParams = regParams[:n-1] + vp, err := p.parseFieldList(pkg, varParams) + if err != nil { + return nil, nil, nil, p.errorf(varParams[0].Pos(), "failed parsing variadic argument: %v", err) + } + variadic = vp[0] + } + in, err = p.parseFieldList(pkg, regParams) + if err != nil { + return nil, nil, nil, p.errorf(f.Pos(), "failed parsing arguments: %v", err) + } + } + if f.Results != nil { + out, err = p.parseFieldList(pkg, f.Results.List) + if err != nil { + return nil, nil, nil, p.errorf(f.Pos(), "failed parsing returns: %v", err) + } + } + return +} + +func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field) ([]*model.Parameter, error) { + nf := 0 + for _, f := range fields { + nn := len(f.Names) + if nn == 0 { + nn = 1 // anonymous parameter + } + nf += nn + } + if nf == 0 { + return nil, nil + } + ps := make([]*model.Parameter, nf) + i := 0 // destination index + for _, f := range fields { + t, err := p.parseType(pkg, f.Type) + if err != nil { + return nil, err + } + + if len(f.Names) == 0 { + // anonymous arg + ps[i] = &model.Parameter{Type: t} + i++ + continue + } + for _, name := range f.Names { + ps[i] = &model.Parameter{Name: name.Name, Type: t} + i++ + } + } + return ps, nil +} + +func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) { + switch v := typ.(type) { + case *ast.ArrayType: + ln := -1 + if v.Len != nil { + x, err := strconv.Atoi(v.Len.(*ast.BasicLit).Value) + if err != nil { + return nil, p.errorf(v.Len.Pos(), "bad array size: %v", err) + } + ln = x + } + t, err := p.parseType(pkg, v.Elt) + if err != nil { + return nil, err + } + return &model.ArrayType{Len: ln, Type: t}, nil + case *ast.ChanType: + t, err := p.parseType(pkg, v.Value) + if err != nil { + return nil, err + } + var dir model.ChanDir + if v.Dir == ast.SEND { + dir = model.SendDir + } + if v.Dir == ast.RECV { + dir = model.RecvDir + } + return &model.ChanType{Dir: dir, Type: t}, nil + case *ast.Ellipsis: + // assume we're parsing a variadic argument + return p.parseType(pkg, v.Elt) + case *ast.FuncType: + in, variadic, out, err := p.parseFunc(pkg, v) + if err != nil { + return nil, err + } + return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil + case *ast.Ident: + if v.IsExported() { + // assume type in this package + return &model.NamedType{Package: pkg, Type: v.Name}, nil + } else { + // assume predeclared type + return model.PredeclaredType(v.Name), nil + } + case *ast.InterfaceType: + if v.Methods != nil && len(v.Methods.List) > 0 { + return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed interface types") + } + return model.PredeclaredType("interface{}"), nil + case *ast.MapType: + key, err := p.parseType(pkg, v.Key) + if err != nil { + return nil, err + } + value, err := p.parseType(pkg, v.Value) + if err != nil { + return nil, err + } + return &model.MapType{Key: key, Value: value}, nil + case *ast.SelectorExpr: + pkgName := v.X.(*ast.Ident).String() + pkg, ok := p.imports[pkgName] + if !ok { + return nil, p.errorf(v.Pos(), "unknown package %q", pkgName) + } + return &model.NamedType{Package: pkg, Type: v.Sel.String()}, nil + case *ast.StarExpr: + t, err := p.parseType(pkg, v.X) + if err != nil { + return nil, err + } + return &model.PointerType{Type: t}, nil + case *ast.StructType: + if v.Fields != nil && len(v.Fields.List) > 0 { + return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed struct types") + } + return model.PredeclaredType("struct{}"), nil + } + + return nil, fmt.Errorf("don't know how to parse type %T", typ) +} + +// importsOfFile returns a map of package name to import path +// of the imports in file. +func importsOfFile(file *ast.File) map[string]string { + /* We have to make guesses about some imports, because imports are not required + * to have names. Named imports are always certain. Unnamed imports are guessed + * to have a name of the last path component; if the last path component has dots, + * the first dot-delimited field is used as the name. + */ + + m := make(map[string]string) + for _, decl := range file.Decls { + gd, ok := decl.(*ast.GenDecl) + if !ok || gd.Tok != token.IMPORT { + continue + } + for _, spec := range gd.Specs { + is, ok := spec.(*ast.ImportSpec) + if !ok { + continue + } + pkg, importPath := "", string(is.Path.Value) + importPath = importPath[1 : len(importPath)-1] // remove quotes + + if is.Name != nil { + if is.Name.Name == "_" { + continue + } + pkg = removeDot(is.Name.Name) + } else { + _, last := path.Split(importPath) + pkg = strings.SplitN(last, ".", 2)[0] + } + if _, ok := m[pkg]; ok { + log.Fatalf("imported package collision: %q imported twice", pkg) + } + m[pkg] = importPath + } + } + return m +} + +type namedInterface struct { + name *ast.Ident + it *ast.InterfaceType +} + +// Create an iterator over all interfaces in file. +func iterInterfaces(file *ast.File) <-chan namedInterface { + ch := make(chan namedInterface) + go func() { + for _, decl := range file.Decls { + gd, ok := decl.(*ast.GenDecl) + if !ok || gd.Tok != token.TYPE { + continue + } + for _, spec := range gd.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + it, ok := ts.Type.(*ast.InterfaceType) + if !ok { + continue + } + + ch <- namedInterface{ts.Name, it} + } + } + close(ch) + }() + return ch +} + +// isVariadic returns whether the function is variadic. +func isVariadic(f *ast.FuncType) bool { + nargs := len(f.Params.List) + if nargs == 0 { + return false + } + _, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis) + return ok +} diff --git a/vendor/github.com/golang/mock/mockgen/reflect.go b/vendor/github.com/golang/mock/mockgen/reflect.go new file mode 100644 index 0000000000..4df9689fe7 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/reflect.go @@ -0,0 +1,163 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// This file contains the model construction by reflection. + +import ( + "bytes" + "encoding/gob" + "flag" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "text/template" + + "github.com/golang/mock/mockgen/model" +) + +var ( + progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout.") + execOnly = flag.String("exec_only", "", "(reflect mode) If set, execute this reflection program.") + buildFlags = flag.String("build_flags", "", "(reflect mode) Additional flags for go build.") +) + +func Reflect(importPath string, symbols []string) (*model.Package, error) { + // TODO: sanity check arguments + + progPath := *execOnly + if *execOnly == "" { + // We use TempDir instead of TempFile so we can control the filename. + tmpDir, err := ioutil.TempDir("", "gomock_reflect_") + if err != nil { + return nil, err + } + defer func() { os.RemoveAll(tmpDir) }() + const progSource = "prog.go" + var progBinary = "prog.bin" + if runtime.GOOS == "windows" { + // Windows won't execute a program unless it has a ".exe" suffix. + progBinary += ".exe" + } + + // Generate program. + var program bytes.Buffer + data := reflectData{ + ImportPath: importPath, + Symbols: symbols, + } + if err := reflectProgram.Execute(&program, &data); err != nil { + return nil, err + } + if *progOnly { + io.Copy(os.Stdout, &program) + os.Exit(0) + } + if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program.Bytes(), 0600); err != nil { + return nil, err + } + + cmdArgs := []string{} + cmdArgs = append(cmdArgs, "build") + if *buildFlags != "" { + cmdArgs = append(cmdArgs, *buildFlags) + } + cmdArgs = append(cmdArgs, "-o", progBinary, progSource) + + // Build the program. + cmd := exec.Command("go", cmdArgs...) + cmd.Dir = tmpDir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, err + } + progPath = filepath.Join(tmpDir, progBinary) + } + + // Run it. + cmd := exec.Command(progPath) + var stdout bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, err + } + + // Process output. + var pkg model.Package + if err := gob.NewDecoder(&stdout).Decode(&pkg); err != nil { + return nil, err + } + return &pkg, nil +} + +type reflectData struct { + ImportPath string + Symbols []string +} + +// This program reflects on an interface value, and prints the +// gob encoding of a model.Package to standard output. +// JSON doesn't work because of the model.Type interface. +var reflectProgram = template.Must(template.New("program").Parse(` +package main + +import ( + "encoding/gob" + "fmt" + "os" + "path" + "reflect" + + "github.com/golang/mock/mockgen/model" + + pkg_ {{printf "%q" .ImportPath}} +) + +func main() { + its := []struct{ + sym string + typ reflect.Type + }{ + {{range .Symbols}} + { {{printf "%q" .}}, reflect.TypeOf((*pkg_.{{.}})(nil)).Elem()}, + {{end}} + } + pkg := &model.Package{ + // NOTE: This behaves contrary to documented behaviour if the + // package name is not the final component of the import path. + // The reflect package doesn't expose the package name, though. + Name: path.Base({{printf "%q" .ImportPath}}), + } + + for _, it := range its { + intf, err := model.InterfaceFromInterfaceType(it.typ) + if err != nil { + fmt.Fprintf(os.Stderr, "Reflection: %v\n", err) + os.Exit(1) + } + intf.Name = it.sym + pkg.Interfaces = append(pkg.Interfaces, intf) + } + if err := gob.NewEncoder(os.Stdout).Encode(pkg); err != nil { + fmt.Fprintf(os.Stderr, "gob encode: %v\n", err) + os.Exit(1) + } +} +`)) diff --git a/vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md new file mode 100644 index 0000000000..87f91d4645 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/README.md @@ -0,0 +1 @@ +From #52, this tests an unexported method in the mocked interface. diff --git a/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go new file mode 100644 index 0000000000..91d5baf7b4 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport.go @@ -0,0 +1,15 @@ +//go:generate mockgen -destination bugreport_mock.go -package bugreport -source=bugreport.go Example + +package bugreport + +import "fmt" + +// Example is an interface with a non exported method +type Example interface { + someMethod(string) string +} + +// CallExample is a simple function that uses the interface +func CallExample(e Example) { + fmt.Println(e.someMethod("test")) +} diff --git a/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go new file mode 100644 index 0000000000..f1a16d813a --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_mock.go @@ -0,0 +1,44 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: bugreport.go + +package bugreport + +import ( + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockExample is a mock of Example interface +type MockExample struct { + ctrl *gomock.Controller + recorder *MockExampleMockRecorder +} + +// MockExampleMockRecorder is the mock recorder for MockExample +type MockExampleMockRecorder struct { + mock *MockExample +} + +// NewMockExample creates a new mock instance +func NewMockExample(ctrl *gomock.Controller) *MockExample { + mock := &MockExample{ctrl: ctrl} + mock.recorder = &MockExampleMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *MockExample) EXPECT() *MockExampleMockRecorder { + return _m.recorder +} + +// someMethod mocks base method +func (_m *MockExample) someMethod(_param0 string) string { + ret := _m.ctrl.Call(_m, "someMethod", _param0) + ret0, _ := ret[0].(string) + return ret0 +} + +// someMethod indicates an expected call of someMethod +func (_mr *MockExampleMockRecorder) someMethod(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "someMethod", reflect.TypeOf((*MockExample)(nil).someMethod), arg0) +} diff --git a/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go new file mode 100644 index 0000000000..d428fb4c49 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/tests/unexported_method/bugreport_test.go @@ -0,0 +1,17 @@ +package bugreport + +import ( + "testing" + + "github.com/golang/mock/gomock" +) + +func TestCallExample(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + e := NewMockExample(ctrl) + e.EXPECT().someMethod(gomock.Any()).Return("it works!") + + CallExample(e) +} diff --git a/vendor/github.com/golang/mock/sample/README.md b/vendor/github.com/golang/mock/sample/README.md new file mode 100644 index 0000000000..7180204f56 --- /dev/null +++ b/vendor/github.com/golang/mock/sample/README.md @@ -0,0 +1,16 @@ +This directory contains an example of a package containing a non-trivial +interface that can be mocked with GoMock. The interesting files are: + + * `user.go`: Source code for the sample package, containing interfaces to be + mocked. This file depends on the packages named imp[1-4] for various things. + + * `user_test.go`: A test for the sample package, in which mocks of the + interfaces from `user.go` are used. This demonstrates how to create mock + objects, set up expectations, and so on. + + * `mock_user/mock_user.go`: The generated mock code. See ../update_mocks.sh + for the command used to generate it. + +To run the test, + + go test github.com/golang/mock/sample diff --git a/vendor/github.com/golang/mock/sample/imp1/imp1.go b/vendor/github.com/golang/mock/sample/imp1/imp1.go new file mode 100644 index 0000000000..ef9d01449e --- /dev/null +++ b/vendor/github.com/golang/mock/sample/imp1/imp1.go @@ -0,0 +1,17 @@ +package imp1 + +import "bufio" + +type Imp1 struct{} + +type ImpT int + +type ForeignEmbedded interface { + // The return value here also makes sure that + // the generated mock picks up the "bufio" import. + ForeignEmbeddedMethod() *bufio.Reader + + // This method uses a type in this package, + // which should be qualified when this interface is embedded. + ImplicitPackage(s string, t ImpT, st []ImpT, pt *ImpT, ct chan ImpT) +} diff --git a/vendor/github.com/golang/mock/sample/imp2/imp2.go b/vendor/github.com/golang/mock/sample/imp2/imp2.go new file mode 100644 index 0000000000..53bee9adea --- /dev/null +++ b/vendor/github.com/golang/mock/sample/imp2/imp2.go @@ -0,0 +1,3 @@ +package imp2 + +type Imp2 struct{} diff --git a/vendor/github.com/golang/mock/sample/imp3/imp3.go b/vendor/github.com/golang/mock/sample/imp3/imp3.go new file mode 100644 index 0000000000..70f17c00f0 --- /dev/null +++ b/vendor/github.com/golang/mock/sample/imp3/imp3.go @@ -0,0 +1,3 @@ +package imp3 + +type Imp3 struct{} diff --git a/vendor/github.com/golang/mock/sample/imp4/imp4.go b/vendor/github.com/golang/mock/sample/imp4/imp4.go new file mode 100644 index 0000000000..30a70767eb --- /dev/null +++ b/vendor/github.com/golang/mock/sample/imp4/imp4.go @@ -0,0 +1,3 @@ +package imp_four + +type Imp4 struct{} diff --git a/vendor/github.com/golang/mock/sample/mock_user/mock_user.go b/vendor/github.com/golang/mock/sample/mock_user/mock_user.go new file mode 100644 index 0000000000..59602ef62a --- /dev/null +++ b/vendor/github.com/golang/mock/sample/mock_user/mock_user.go @@ -0,0 +1,383 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/golang/mock/sample (interfaces: Index,Embed,Embedded) + +package mock_sample + +import ( + bufio "bufio" + bytes "bytes" + gomock "github.com/golang/mock/gomock" + imp1 "github.com/golang/mock/sample/imp1" + imp2 "github.com/golang/mock/sample/imp2" + imp3 "github.com/golang/mock/sample/imp3" + imp4 "github.com/golang/mock/sample/imp4" + hash "hash" + template "html/template" + io "io" + http "net/http" + reflect "reflect" + template0 "text/template" +) + +// MockIndex is a mock of Index interface +type MockIndex struct { + ctrl *gomock.Controller + recorder *MockIndexMockRecorder +} + +// MockIndexMockRecorder is the mock recorder for MockIndex +type MockIndexMockRecorder struct { + mock *MockIndex +} + +// NewMockIndex creates a new mock instance +func NewMockIndex(ctrl *gomock.Controller) *MockIndex { + mock := &MockIndex{ctrl: ctrl} + mock.recorder = &MockIndexMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *MockIndex) EXPECT() *MockIndexMockRecorder { + return _m.recorder +} + +// Anon mocks base method +func (_m *MockIndex) Anon(_param0 string) { + _m.ctrl.Call(_m, "Anon", _param0) +} + +// Anon indicates an expected call of Anon +func (_mr *MockIndexMockRecorder) Anon(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Anon", reflect.TypeOf((*MockIndex)(nil).Anon), arg0) +} + +// Chan mocks base method +func (_m *MockIndex) Chan(_param0 chan int, _param1 chan<- hash.Hash) { + _m.ctrl.Call(_m, "Chan", _param0, _param1) +} + +// Chan indicates an expected call of Chan +func (_mr *MockIndexMockRecorder) Chan(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Chan", reflect.TypeOf((*MockIndex)(nil).Chan), arg0, arg1) +} + +// ConcreteRet mocks base method +func (_m *MockIndex) ConcreteRet() chan<- bool { + ret := _m.ctrl.Call(_m, "ConcreteRet") + ret0, _ := ret[0].(chan<- bool) + return ret0 +} + +// ConcreteRet indicates an expected call of ConcreteRet +func (_mr *MockIndexMockRecorder) ConcreteRet() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ConcreteRet", reflect.TypeOf((*MockIndex)(nil).ConcreteRet)) +} + +// Ellip mocks base method +func (_m *MockIndex) Ellip(_param0 string, _param1 ...interface{}) { + _s := []interface{}{_param0} + for _, _x := range _param1 { + _s = append(_s, _x) + } + _m.ctrl.Call(_m, "Ellip", _s...) +} + +// Ellip indicates an expected call of Ellip +func (_mr *MockIndexMockRecorder) Ellip(arg0 interface{}, arg1 ...interface{}) *gomock.Call { + _s := append([]interface{}{arg0}, arg1...) + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Ellip", reflect.TypeOf((*MockIndex)(nil).Ellip), _s...) +} + +// EllipOnly mocks base method +func (_m *MockIndex) EllipOnly(_param0 ...string) { + _s := []interface{}{} + for _, _x := range _param0 { + _s = append(_s, _x) + } + _m.ctrl.Call(_m, "EllipOnly", _s...) +} + +// EllipOnly indicates an expected call of EllipOnly +func (_mr *MockIndexMockRecorder) EllipOnly(arg0 ...interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EllipOnly", reflect.TypeOf((*MockIndex)(nil).EllipOnly), arg0...) +} + +// ForeignFour mocks base method +func (_m *MockIndex) ForeignFour(_param0 imp4.Imp4) { + _m.ctrl.Call(_m, "ForeignFour", _param0) +} + +// ForeignFour indicates an expected call of ForeignFour +func (_mr *MockIndexMockRecorder) ForeignFour(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignFour", reflect.TypeOf((*MockIndex)(nil).ForeignFour), arg0) +} + +// ForeignOne mocks base method +func (_m *MockIndex) ForeignOne(_param0 imp1.Imp1) { + _m.ctrl.Call(_m, "ForeignOne", _param0) +} + +// ForeignOne indicates an expected call of ForeignOne +func (_mr *MockIndexMockRecorder) ForeignOne(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignOne", reflect.TypeOf((*MockIndex)(nil).ForeignOne), arg0) +} + +// ForeignThree mocks base method +func (_m *MockIndex) ForeignThree(_param0 imp3.Imp3) { + _m.ctrl.Call(_m, "ForeignThree", _param0) +} + +// ForeignThree indicates an expected call of ForeignThree +func (_mr *MockIndexMockRecorder) ForeignThree(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignThree", reflect.TypeOf((*MockIndex)(nil).ForeignThree), arg0) +} + +// ForeignTwo mocks base method +func (_m *MockIndex) ForeignTwo(_param0 imp2.Imp2) { + _m.ctrl.Call(_m, "ForeignTwo", _param0) +} + +// ForeignTwo indicates an expected call of ForeignTwo +func (_mr *MockIndexMockRecorder) ForeignTwo(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignTwo", reflect.TypeOf((*MockIndex)(nil).ForeignTwo), arg0) +} + +// Func mocks base method +func (_m *MockIndex) Func(_param0 func(http.Request) (int, bool)) { + _m.ctrl.Call(_m, "Func", _param0) +} + +// Func indicates an expected call of Func +func (_mr *MockIndexMockRecorder) Func(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Func", reflect.TypeOf((*MockIndex)(nil).Func), arg0) +} + +// Get mocks base method +func (_m *MockIndex) Get(_param0 string) interface{} { + ret := _m.ctrl.Call(_m, "Get", _param0) + ret0, _ := ret[0].(interface{}) + return ret0 +} + +// Get indicates an expected call of Get +func (_mr *MockIndexMockRecorder) Get(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Get", reflect.TypeOf((*MockIndex)(nil).Get), arg0) +} + +// GetTwo mocks base method +func (_m *MockIndex) GetTwo(_param0 string, _param1 string) (interface{}, interface{}) { + ret := _m.ctrl.Call(_m, "GetTwo", _param0, _param1) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(interface{}) + return ret0, ret1 +} + +// GetTwo indicates an expected call of GetTwo +func (_mr *MockIndexMockRecorder) GetTwo(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "GetTwo", reflect.TypeOf((*MockIndex)(nil).GetTwo), arg0, arg1) +} + +// Map mocks base method +func (_m *MockIndex) Map(_param0 map[int]hash.Hash) { + _m.ctrl.Call(_m, "Map", _param0) +} + +// Map indicates an expected call of Map +func (_mr *MockIndexMockRecorder) Map(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Map", reflect.TypeOf((*MockIndex)(nil).Map), arg0) +} + +// NillableRet mocks base method +func (_m *MockIndex) NillableRet() error { + ret := _m.ctrl.Call(_m, "NillableRet") + ret0, _ := ret[0].(error) + return ret0 +} + +// NillableRet indicates an expected call of NillableRet +func (_mr *MockIndexMockRecorder) NillableRet() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "NillableRet", reflect.TypeOf((*MockIndex)(nil).NillableRet)) +} + +// Other mocks base method +func (_m *MockIndex) Other() hash.Hash { + ret := _m.ctrl.Call(_m, "Other") + ret0, _ := ret[0].(hash.Hash) + return ret0 +} + +// Other indicates an expected call of Other +func (_mr *MockIndexMockRecorder) Other() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Other", reflect.TypeOf((*MockIndex)(nil).Other)) +} + +// Ptr mocks base method +func (_m *MockIndex) Ptr(_param0 *int) { + _m.ctrl.Call(_m, "Ptr", _param0) +} + +// Ptr indicates an expected call of Ptr +func (_mr *MockIndexMockRecorder) Ptr(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Ptr", reflect.TypeOf((*MockIndex)(nil).Ptr), arg0) +} + +// Put mocks base method +func (_m *MockIndex) Put(_param0 string, _param1 interface{}) { + _m.ctrl.Call(_m, "Put", _param0, _param1) +} + +// Put indicates an expected call of Put +func (_mr *MockIndexMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Put", reflect.TypeOf((*MockIndex)(nil).Put), arg0, arg1) +} + +// Slice mocks base method +func (_m *MockIndex) Slice(_param0 []int, _param1 []byte) [3]int { + ret := _m.ctrl.Call(_m, "Slice", _param0, _param1) + ret0, _ := ret[0].([3]int) + return ret0 +} + +// Slice indicates an expected call of Slice +func (_mr *MockIndexMockRecorder) Slice(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Slice", reflect.TypeOf((*MockIndex)(nil).Slice), arg0, arg1) +} + +// Struct mocks base method +func (_m *MockIndex) Struct(_param0 struct{}) { + _m.ctrl.Call(_m, "Struct", _param0) +} + +// Struct indicates an expected call of Struct +func (_mr *MockIndexMockRecorder) Struct(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Struct", reflect.TypeOf((*MockIndex)(nil).Struct), arg0) +} + +// StructChan mocks base method +func (_m *MockIndex) StructChan(_param0 chan struct{}) { + _m.ctrl.Call(_m, "StructChan", _param0) +} + +// StructChan indicates an expected call of StructChan +func (_mr *MockIndexMockRecorder) StructChan(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "StructChan", reflect.TypeOf((*MockIndex)(nil).StructChan), arg0) +} + +// Summary mocks base method +func (_m *MockIndex) Summary(_param0 *bytes.Buffer, _param1 io.Writer) { + _m.ctrl.Call(_m, "Summary", _param0, _param1) +} + +// Summary indicates an expected call of Summary +func (_mr *MockIndexMockRecorder) Summary(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Summary", reflect.TypeOf((*MockIndex)(nil).Summary), arg0, arg1) +} + +// Templates mocks base method +func (_m *MockIndex) Templates(_param0 template.CSS, _param1 template0.FuncMap) { + _m.ctrl.Call(_m, "Templates", _param0, _param1) +} + +// Templates indicates an expected call of Templates +func (_mr *MockIndexMockRecorder) Templates(arg0, arg1 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Templates", reflect.TypeOf((*MockIndex)(nil).Templates), arg0, arg1) +} + +// MockEmbed is a mock of Embed interface +type MockEmbed struct { + ctrl *gomock.Controller + recorder *MockEmbedMockRecorder +} + +// MockEmbedMockRecorder is the mock recorder for MockEmbed +type MockEmbedMockRecorder struct { + mock *MockEmbed +} + +// NewMockEmbed creates a new mock instance +func NewMockEmbed(ctrl *gomock.Controller) *MockEmbed { + mock := &MockEmbed{ctrl: ctrl} + mock.recorder = &MockEmbedMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *MockEmbed) EXPECT() *MockEmbedMockRecorder { + return _m.recorder +} + +// EmbeddedMethod mocks base method +func (_m *MockEmbed) EmbeddedMethod() { + _m.ctrl.Call(_m, "EmbeddedMethod") +} + +// EmbeddedMethod indicates an expected call of EmbeddedMethod +func (_mr *MockEmbedMockRecorder) EmbeddedMethod() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).EmbeddedMethod)) +} + +// ForeignEmbeddedMethod mocks base method +func (_m *MockEmbed) ForeignEmbeddedMethod() *bufio.Reader { + ret := _m.ctrl.Call(_m, "ForeignEmbeddedMethod") + ret0, _ := ret[0].(*bufio.Reader) + return ret0 +} + +// ForeignEmbeddedMethod indicates an expected call of ForeignEmbeddedMethod +func (_mr *MockEmbedMockRecorder) ForeignEmbeddedMethod() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignEmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).ForeignEmbeddedMethod)) +} + +// ImplicitPackage mocks base method +func (_m *MockEmbed) ImplicitPackage(_param0 string, _param1 imp1.ImpT, _param2 []imp1.ImpT, _param3 *imp1.ImpT, _param4 chan imp1.ImpT) { + _m.ctrl.Call(_m, "ImplicitPackage", _param0, _param1, _param2, _param3, _param4) +} + +// ImplicitPackage indicates an expected call of ImplicitPackage +func (_mr *MockEmbedMockRecorder) ImplicitPackage(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ImplicitPackage", reflect.TypeOf((*MockEmbed)(nil).ImplicitPackage), arg0, arg1, arg2, arg3, arg4) +} + +// RegularMethod mocks base method +func (_m *MockEmbed) RegularMethod() { + _m.ctrl.Call(_m, "RegularMethod") +} + +// RegularMethod indicates an expected call of RegularMethod +func (_mr *MockEmbedMockRecorder) RegularMethod() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "RegularMethod", reflect.TypeOf((*MockEmbed)(nil).RegularMethod)) +} + +// MockEmbedded is a mock of Embedded interface +type MockEmbedded struct { + ctrl *gomock.Controller + recorder *MockEmbeddedMockRecorder +} + +// MockEmbeddedMockRecorder is the mock recorder for MockEmbedded +type MockEmbeddedMockRecorder struct { + mock *MockEmbedded +} + +// NewMockEmbedded creates a new mock instance +func NewMockEmbedded(ctrl *gomock.Controller) *MockEmbedded { + mock := &MockEmbedded{ctrl: ctrl} + mock.recorder = &MockEmbeddedMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *MockEmbedded) EXPECT() *MockEmbeddedMockRecorder { + return _m.recorder +} + +// EmbeddedMethod mocks base method +func (_m *MockEmbedded) EmbeddedMethod() { + _m.ctrl.Call(_m, "EmbeddedMethod") +} + +// EmbeddedMethod indicates an expected call of EmbeddedMethod +func (_mr *MockEmbeddedMockRecorder) EmbeddedMethod() *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbedded)(nil).EmbeddedMethod)) +} diff --git a/vendor/github.com/golang/mock/sample/user.go b/vendor/github.com/golang/mock/sample/user.go new file mode 100644 index 0000000000..0e4a8142d9 --- /dev/null +++ b/vendor/github.com/golang/mock/sample/user.go @@ -0,0 +1,114 @@ +//go:generate mockgen -destination mock_user/mock_user.go github.com/golang/mock/sample Index,Embed,Embedded + +// An example package with an interface. +package user + +// Random bunch of imports to test mockgen. +import "io" +import ( + btz "bytes" + "hash" + "log" + "net" + "net/http" + + // Two imports with the same base name. + t1 "html/template" + t2 "text/template" +) + +// Dependencies outside the standard library. +import ( + "github.com/golang/mock/sample/imp1" + renamed2 "github.com/golang/mock/sample/imp2" + . "github.com/golang/mock/sample/imp3" + "github.com/golang/mock/sample/imp4" // calls itself "imp_four" +) + +// A bizarre interface to test corner cases in mockgen. +// This would normally be in its own file or package, +// separate from the user of it (e.g. io.Reader). +type Index interface { + Get(key string) interface{} + GetTwo(key1, key2 string) (v1, v2 interface{}) + Put(key string, value interface{}) + + // Check that imports are handled correctly. + Summary(buf *btz.Buffer, w io.Writer) + Other() hash.Hash + Templates(a t1.CSS, b t2.FuncMap) + + // A method with an anonymous argument. + Anon(string) + + // Methods using foreign types outside the standard library. + ForeignOne(imp1.Imp1) + ForeignTwo(renamed2.Imp2) + ForeignThree(Imp3) + ForeignFour(imp_four.Imp4) + + // A method that returns a nillable type. + NillableRet() error + // A method that returns a non-interface type. + ConcreteRet() chan<- bool + + // Methods with an ellipsis argument. + Ellip(fmt string, args ...interface{}) + EllipOnly(...string) + + // A method with a pointer argument that we will set. + Ptr(arg *int) + + // A method with a slice argument and an array return. + Slice(a []int, b []byte) [3]int + + // A method with channel arguments. + Chan(a chan int, b chan<- hash.Hash) + + // A method with a function argument. + Func(f func(http.Request) (int, bool)) + + // A method with a map argument. + Map(a map[int]hash.Hash) + + // Methods with an unnamed empty struct argument. + Struct(a struct{}) // not so likely + StructChan(a chan struct{}) // a bit more common +} + +// An interface with an embedded interface. +type Embed interface { + RegularMethod() + Embedded + imp1.ForeignEmbedded +} + +type Embedded interface { + EmbeddedMethod() +} + +// some random use of another package that isn't needed by the interface. +var _ net.Addr + +// A function that we will test that uses the above interface. +// It takes a list of keys and values, and puts them in the index. +func Remember(index Index, keys []string, values []interface{}) { + for i, k := range keys { + index.Put(k, values[i]) + } + err := index.NillableRet() + if err != nil { + log.Fatalf("Woah! %v", err) + } + if len(keys) > 0 && keys[0] == "a" { + index.Ellip("%d", 0, 1, 1, 2, 3) + index.Ellip("%d", 1, 3, 6, 10, 15) + index.EllipOnly("arg") + } +} + +func GrabPointer(index Index) int { + var a int + index.Ptr(&a) + return a +} diff --git a/vendor/github.com/golang/mock/sample/user_test.go b/vendor/github.com/golang/mock/sample/user_test.go new file mode 100644 index 0000000000..c8c3864a32 --- /dev/null +++ b/vendor/github.com/golang/mock/sample/user_test.go @@ -0,0 +1,122 @@ +// A test that uses a mock. +package user_test + +import ( + "testing" + + "github.com/golang/mock/gomock" + "github.com/golang/mock/sample" + "github.com/golang/mock/sample/imp1" + mock_user "github.com/golang/mock/sample/mock_user" +) + +func TestRemember(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockIndex := mock_user.NewMockIndex(ctrl) + mockIndex.EXPECT().Put("a", 1) // literals work + mockIndex.EXPECT().Put("b", gomock.Eq(2)) // matchers work too + + // NillableRet returns error. Not declaring it should result in a nil return. + mockIndex.EXPECT().NillableRet() + // Calls that returns something assignable to the return type. + boolc := make(chan bool) + // In this case, "chan bool" is assignable to "chan<- bool". + mockIndex.EXPECT().ConcreteRet().Return(boolc) + // In this case, nil is assignable to "chan<- bool". + mockIndex.EXPECT().ConcreteRet().Return(nil) + + // Should be able to place expectations on variadic methods. + mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) // direct args + tri := []interface{}{1, 3, 6, 10, 15} + mockIndex.EXPECT().Ellip("%d", tri...) // args from slice + mockIndex.EXPECT().EllipOnly(gomock.Eq("arg")) + + user.Remember(mockIndex, []string{"a", "b"}, []interface{}{1, 2}) + // Check the ConcreteRet calls. + if c := mockIndex.ConcreteRet(); c != boolc { + t.Errorf("ConcreteRet: got %v, want %v", c, boolc) + } + if c := mockIndex.ConcreteRet(); c != nil { + t.Errorf("ConcreteRet: got %v, want nil", c) + } + + // Try one with an action. + calledString := "" + mockIndex.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(key string, _ interface{}) { + calledString = key + }) + mockIndex.EXPECT().NillableRet() + user.Remember(mockIndex, []string{"blah"}, []interface{}{7}) + if calledString != "blah" { + t.Fatalf(`Uh oh. %q != "blah"`, calledString) + } + + // Use Do with a nil arg. + mockIndex.EXPECT().Put("nil-key", gomock.Any()).Do(func(key string, value interface{}) { + if value != nil { + t.Errorf("Put did not pass through nil; got %v", value) + } + }) + mockIndex.EXPECT().NillableRet() + user.Remember(mockIndex, []string{"nil-key"}, []interface{}{nil}) +} + +func TestVariadicFunction(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockIndex := mock_user.NewMockIndex(ctrl) + m := mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) + m.Do(func(format string, nums ...int) { + sum := 0 + for _, value := range nums { + sum += value + } + if sum != 7 { + t.Errorf("Expected 7, got %d", sum) + } + }) + + mockIndex.Ellip("%d", 0, 1, 1, 2, 3) +} + +func TestGrabPointer(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockIndex := mock_user.NewMockIndex(ctrl) + mockIndex.EXPECT().Ptr(gomock.Any()).SetArg(0, 7) // set first argument to 7 + + i := user.GrabPointer(mockIndex) + if i != 7 { + t.Errorf("Expected 7, got %d", i) + } +} + +func TestEmbeddedInterface(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockEmbed := mock_user.NewMockEmbed(ctrl) + mockEmbed.EXPECT().RegularMethod() + mockEmbed.EXPECT().EmbeddedMethod() + mockEmbed.EXPECT().ForeignEmbeddedMethod() + + mockEmbed.RegularMethod() + mockEmbed.EmbeddedMethod() + var emb imp1.ForeignEmbedded = mockEmbed // also does interface check + emb.ForeignEmbeddedMethod() +} + +func TestExpectTrueNil(t *testing.T) { + // Make sure that passing "nil" to EXPECT (thus as a nil interface value), + // will correctly match a nil concrete type. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockIndex := mock_user.NewMockIndex(ctrl) + mockIndex.EXPECT().Ptr(nil) // this nil is a nil interface{} + mockIndex.Ptr(nil) // this nil is a nil *int +} diff --git a/vendor/github.com/gregjones/httpcache/README.md b/vendor/github.com/gregjones/httpcache/README.md index eb2eae8ede..09c9e7c173 100644 --- a/vendor/github.com/gregjones/httpcache/README.md +++ b/vendor/github.com/gregjones/httpcache/README.md @@ -3,7 +3,7 @@ httpcache [![Build Status](https://travis-ci.org/gregjones/httpcache.svg?branch=master)](https://travis-ci.org/gregjones/httpcache) [![GoDoc](https://godoc.org/github.com/gregjones/httpcache?status.svg)](https://godoc.org/github.com/gregjones/httpcache) -Package httpcache provides a http.RoundTripper implementation that works as a mostly RFC-compliant cache for http responses. +Package httpcache provides a http.RoundTripper implementation that works as a mostly [RFC 7234](https://tools.ietf.org/html/rfc7234) compliant cache for http responses. It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy). diff --git a/vendor/github.com/kubernetes-csi/csi-test/.gitignore b/vendor/github.com/kubernetes-csi/csi-test/.gitignore new file mode 100644 index 0000000000..5e8f082ffd --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out +cmd/csi-sanity/csi-sanity diff --git a/vendor/github.com/kubernetes-csi/csi-test/.travis.yml b/vendor/github.com/kubernetes-csi/csi-test/.travis.yml new file mode 100644 index 0000000000..414fa97b8c --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/.travis.yml @@ -0,0 +1,9 @@ +language: go +matrix: + include: + - go: 1.x +script: +- go fmt $(go list ./... | grep -v vendor) | wc -l | grep 0 +- go vet $(go list ./... | grep -v vendor) +- go test $(go list ./... | grep -v vendor | grep -v "cmd/csi-sanity") +- ./hack/e2e.sh diff --git a/vendor/github.com/kubernetes-csi/csi-test/Gopkg.lock b/vendor/github.com/kubernetes-csi/csi-test/Gopkg.lock new file mode 100644 index 0000000000..f9fb3006c7 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/Gopkg.lock @@ -0,0 +1,193 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/container-storage-interface/spec" + packages = ["lib/go/csi/v0"] + revision = "35d9f9d77954980e449e52c3f3e43c21bd8171f5" + version = "v0.2.0" + +[[projects]] + name = "github.com/golang/mock" + packages = ["gomock"] + revision = "13f360950a79f5864a972c786a10a50e44b69541" + version = "v1.0.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "protoc-gen-go/descriptor", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "925541529c1fa6821df4e44ce2723319eb2be768" + version = "v1.0.0" + +[[projects]] + name = "github.com/onsi/ginkgo" + packages = [ + ".", + "config", + "internal/codelocation", + "internal/containernode", + "internal/failer", + "internal/leafnodes", + "internal/remote", + "internal/spec", + "internal/spec_iterator", + "internal/specrunner", + "internal/suite", + "internal/testingtproxy", + "internal/writer", + "reporters", + "reporters/stenographer", + "reporters/stenographer/support/go-colorable", + "reporters/stenographer/support/go-isatty", + "types" + ] + revision = "9eda700730cba42af70d53180f9dcce9266bc2bc" + version = "v1.4.0" + +[[projects]] + name = "github.com/onsi/gomega" + packages = [ + ".", + "format", + "internal/assertion", + "internal/asyncassertion", + "internal/oraclematcher", + "internal/testingtsupport", + "matchers", + "matchers/support/goraph/bipartitegraph", + "matchers/support/goraph/edge", + "matchers/support/goraph/node", + "matchers/support/goraph/util", + "types" + ] + revision = "003f63b7f4cff3fc95357005358af2de0f5fe152" + version = "v1.3.0" + +[[projects]] + name = "github.com/sirupsen/logrus" + packages = ["."] + revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba" + version = "v1.0.4" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["ssh/terminal"] + revision = "91a49db82a88618983a78a06c1cbd4e00ab749ab" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "html", + "html/atom", + "html/charset", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "lex/httplex", + "trace" + ] + revision = "22ae77b79946ea320088417e4d50825671d82d57" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows" + ] + revision = "dd2ff4accc098aceecb86b36eaa7829b2a17b1c9" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "encoding", + "encoding/charmap", + "encoding/htmlindex", + "encoding/internal", + "encoding/internal/identifier", + "encoding/japanese", + "encoding/korean", + "encoding/simplifiedchinese", + "encoding/traditionalchinese", + "encoding/unicode", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "internal/utf8internal", + "language", + "runes", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "2c5e7ac708aaa719366570dd82bda44541ca2a63" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "encoding/proto", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "reflection", + "reflection/grpc_reflection_v1alpha", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap", + "transport" + ] + revision = "8e4536a86ab602859c20df5ebfd0bd4228d08655" + version = "v1.10.0" + +[[projects]] + name = "gopkg.in/yaml.v2" + packages = ["."] + revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5" + version = "v2.1.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "d953393850efa90c442b607a076291db1b050e1c9523ce86fefc85fda0443b8f" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/kubernetes-csi/csi-test/Gopkg.toml b/vendor/github.com/kubernetes-csi/csi-test/Gopkg.toml new file mode 100644 index 0000000000..ea61655a24 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/Gopkg.toml @@ -0,0 +1,54 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/container-storage-interface/spec" + version = "~0.2.0" + +[[constraint]] + name = "github.com/golang/mock" + version = "1.0.0" + +[[constraint]] + name = "github.com/onsi/ginkgo" + version = "1.4.0" + +[[constraint]] + name = "github.com/onsi/gomega" + version = "1.3.0" + +[[constraint]] + branch = "master" + name = "golang.org/x/net" + +[[constraint]] + name = "google.golang.org/grpc" + version = "1.9.2" + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/kubernetes-csi/csi-test/LICENSE b/vendor/github.com/kubernetes-csi/csi-test/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/vendor/github.com/kubernetes-csi/csi-test/README.md b/vendor/github.com/kubernetes-csi/csi-test/README.md new file mode 100644 index 0000000000..07178eeb18 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/README.md @@ -0,0 +1,16 @@ +[![Build Status](https://travis-ci.org/kubernetes-csi/csi-test.svg?branch=master)](https://travis-ci.org/kubernetes-csi/csi-test) +# csi-test +csi-test houses packages and libraries to help test CSI client and plugins. + +## For Container Orchestration Tests +CO developers can use this framework to create drivers based on the +[Golang mock](https://github.com/golang/mock) framework. Please see +[co_test.go](test/co_test.go) for an example. + +## For CSI Driver Tests +To test drivers please take a look at [pkg/sanity](https://github.com/kubernetes-csi/csi-test/tree/master/pkg/sanity) + +### Note + +* Master is for CSI v0.2.0. Please use the branch v0.1.0 for CSI v0.1.0 +* Only Golang 1.9+ supported. See [gRPC issue](https://github.com/grpc/grpc-go/issues/711#issuecomment-326626790) diff --git a/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/Makefile b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/Makefile new file mode 100644 index 0000000000..db9e6e7d32 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/Makefile @@ -0,0 +1,64 @@ +APP_NAME := csi-sanity +VER :=$(shell git describe) +RELEASEVER := $(shell git describe --abbrev=0) +BRANCH := $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) +SHA := $(shell git rev-parse --short HEAD) +ARCH := $(shell go env GOARCH) +GOOS := $(shell go env GOOS) +DIR=. + +ifdef APP_SUFFIX + VERSION = $(VER)-$(subst /,-,$(APP_SUFFIX)) +else +ifeq (master,$(BRANCH)) + VERSION = $(VER) +else + VERSION = $(VER)-$(BRANCH) +endif +endif + +LDFLAGS :=-ldflags "-w -X github.com/kubernetes-csi/csi-test/cmd/csi-sanity.VERSION=$(VERSION) -extldflags '-z relro -z now'" +PACKAGE :=$(DIR)/dist/$(APP_NAME)-$(RELEASEVER).$(GOOS).$(ARCH).tar.gz + +all: $(APP_NAME) + +$(APP_NAME): Makefile sanity_test.go + go test $(LDFLAGS) -c -o $(APP_NAME) + +install: $(APP_NAME) + cp $(APP_NAME) $(GOPATH)/bin + +clean: + rm -f csi-sanity + +dist-clean: + rm -rf $(DIR)/dist + +dist: clean $(PACKAGE) + +$(PACKAGE): $(APP_NAME) + @echo Packaging Binaries... + @mkdir -p tmp/$(APP_NAME) + @cp $(APP_NAME) tmp/$(APP_NAME)/ + @mkdir -p $(DIR)/dist/ + tar -czf $@ -C tmp $(APP_NAME); + @rm -rf tmp + @echo + @echo Package $@ saved in dist directory + +linux_amd64_dist: + GOOS=linux GOARCH=amd64 $(MAKE) dist + +linux_arm_dist: + GOOS=linux GOARCH=arm $(MAKE) dist + +linux_arm64_dist: + GOOS=linux GOARCH=arm64 $(MAKE) dist + +darwin_amd64_dist: + GOOS=darwin GOARCH=amd64 $(MAKE) dist + +release: dist-clean darwin_amd64_dist linux_arm_dist linux_amd64_dist linux_arm64_dist + +.PHONY: release darwin_amd64_dist linux_arm64_dist linux_amd64_dist \ + linux_arm_dist linux_amd64_dist clean dist-clean diff --git a/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/README.md b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/README.md new file mode 100644 index 0000000000..48127b0f2f --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/README.md @@ -0,0 +1,34 @@ +# Sanity Test Command Line Program +This is the command line program that tests a CSI driver using the [`sanity`](https://github.com/kubernetes-csi/csi-test/tree/master/pkg/sanity) package test suite. + +Example: + +``` +$ csi-sanity --csi.endpoint= +``` + +If you want to specify a mount point: + +``` +$ csi-sanity --csi.endpoint= --csi.mountpoint=/mnt +``` + +For verbose type: + +``` +$ csi-sanity --ginkgo.v --csi.endpoint= +``` + +### Help +The full Ginkgo and golang unit test parameters are available. Type + +``` +$ csi-sanity -h +``` + +to get more information + +### Download + +Please see the [Releases](https://github.com/kubernetes-csi/csi-test/releases) page +to download the latest version of `csi-sanity` diff --git a/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/sanity_test.go b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/sanity_test.go new file mode 100644 index 0000000000..5d2881542b --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/cmd/csi-sanity/sanity_test.go @@ -0,0 +1,54 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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 sanity + +import ( + "flag" + "fmt" + "os" + "testing" + + "github.com/kubernetes-csi/csi-test/pkg/sanity" +) + +const ( + prefix string = "csi." +) + +var ( + VERSION = "(dev)" + endpoint string + mountPoint string + version bool +) + +func init() { + flag.StringVar(&endpoint, prefix+"endpoint", "", "CSI endpoint") + flag.BoolVar(&version, prefix+"version", false, "Version of this program") + flag.StringVar(&mountPoint, prefix+"mountpoint", os.TempDir()+"/csi", "Mount point for NodePublish") + flag.Parse() +} + +func TestSanity(t *testing.T) { + if version { + fmt.Printf("Version = %s\n", VERSION) + return + } + if len(endpoint) == 0 { + t.Fatalf("--%sendpoint must be provided with an CSI endpoint", prefix) + } + sanity.Test(t, endpoint, mountPoint) +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/code-of-conduct.md b/vendor/github.com/kubernetes-csi/csi-test/code-of-conduct.md new file mode 100644 index 0000000000..0d15c00cf3 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/vendor/github.com/kubernetes-csi/csi-test/driver/driver.go b/vendor/github.com/kubernetes-csi/csi-test/driver/driver.go new file mode 100644 index 0000000000..235996b769 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/driver/driver.go @@ -0,0 +1,117 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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. +*/ + +//go:generate mockgen -package=driver -destination=driver.mock.go github.com/container-storage-interface/spec/lib/go/csi/v0 IdentityServer,ControllerServer,NodeServer + +package driver + +import ( + "net" + "sync" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +type CSIDriverServers struct { + Controller csi.ControllerServer + Identity csi.IdentityServer + Node csi.NodeServer +} + +type CSIDriver struct { + listener net.Listener + server *grpc.Server + servers *CSIDriverServers + wg sync.WaitGroup + running bool + lock sync.Mutex +} + +func NewCSIDriver(servers *CSIDriverServers) *CSIDriver { + return &CSIDriver{ + servers: servers, + } +} + +func (c *CSIDriver) goServe(started chan<- bool) { + c.wg.Add(1) + go func() { + defer c.wg.Done() + started <- true + err := c.server.Serve(c.listener) + if err != nil { + panic(err.Error()) + } + }() +} + +func (c *CSIDriver) Address() string { + return c.listener.Addr().String() +} +func (c *CSIDriver) Start(l net.Listener) error { + c.lock.Lock() + defer c.lock.Unlock() + + // Set listener + c.listener = l + + // Create a new grpc server + c.server = grpc.NewServer() + + // Register Mock servers + if c.servers.Controller != nil { + csi.RegisterControllerServer(c.server, c.servers.Controller) + } + if c.servers.Identity != nil { + csi.RegisterIdentityServer(c.server, c.servers.Identity) + } + if c.servers.Node != nil { + csi.RegisterNodeServer(c.server, c.servers.Node) + } + reflection.Register(c.server) + + // Start listening for requests + waitForServer := make(chan bool) + c.goServe(waitForServer) + <-waitForServer + c.running = true + return nil +} + +func (c *CSIDriver) Stop() { + c.lock.Lock() + defer c.lock.Unlock() + + if !c.running { + return + } + + c.server.Stop() + c.wg.Wait() +} + +func (c *CSIDriver) Close() { + c.server.Stop() +} + +func (c *CSIDriver) IsRunning() bool { + c.lock.Lock() + defer c.lock.Unlock() + + return c.running +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/driver/driver.mock.go b/vendor/github.com/kubernetes-csi/csi-test/driver/driver.mock.go new file mode 100644 index 0000000000..78c6a8ad71 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/driver/driver.mock.go @@ -0,0 +1,302 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/container-storage-interface/spec/lib/go/csi/v0 (interfaces: IdentityServer,ControllerServer,NodeServer) + +// Package driver is a generated GoMock package. +package driver + +import ( + context "context" + v0 "github.com/container-storage-interface/spec/lib/go/csi/v0" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockIdentityServer is a mock of IdentityServer interface +type MockIdentityServer struct { + ctrl *gomock.Controller + recorder *MockIdentityServerMockRecorder +} + +// MockIdentityServerMockRecorder is the mock recorder for MockIdentityServer +type MockIdentityServerMockRecorder struct { + mock *MockIdentityServer +} + +// NewMockIdentityServer creates a new mock instance +func NewMockIdentityServer(ctrl *gomock.Controller) *MockIdentityServer { + mock := &MockIdentityServer{ctrl: ctrl} + mock.recorder = &MockIdentityServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockIdentityServer) EXPECT() *MockIdentityServerMockRecorder { + return m.recorder +} + +// GetPluginCapabilities mocks base method +func (m *MockIdentityServer) GetPluginCapabilities(arg0 context.Context, arg1 *v0.GetPluginCapabilitiesRequest) (*v0.GetPluginCapabilitiesResponse, error) { + ret := m.ctrl.Call(m, "GetPluginCapabilities", arg0, arg1) + ret0, _ := ret[0].(*v0.GetPluginCapabilitiesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPluginCapabilities indicates an expected call of GetPluginCapabilities +func (mr *MockIdentityServerMockRecorder) GetPluginCapabilities(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginCapabilities", reflect.TypeOf((*MockIdentityServer)(nil).GetPluginCapabilities), arg0, arg1) +} + +// GetPluginInfo mocks base method +func (m *MockIdentityServer) GetPluginInfo(arg0 context.Context, arg1 *v0.GetPluginInfoRequest) (*v0.GetPluginInfoResponse, error) { + ret := m.ctrl.Call(m, "GetPluginInfo", arg0, arg1) + ret0, _ := ret[0].(*v0.GetPluginInfoResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPluginInfo indicates an expected call of GetPluginInfo +func (mr *MockIdentityServerMockRecorder) GetPluginInfo(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginInfo", reflect.TypeOf((*MockIdentityServer)(nil).GetPluginInfo), arg0, arg1) +} + +// Probe mocks base method +func (m *MockIdentityServer) Probe(arg0 context.Context, arg1 *v0.ProbeRequest) (*v0.ProbeResponse, error) { + ret := m.ctrl.Call(m, "Probe", arg0, arg1) + ret0, _ := ret[0].(*v0.ProbeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Probe indicates an expected call of Probe +func (mr *MockIdentityServerMockRecorder) Probe(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Probe", reflect.TypeOf((*MockIdentityServer)(nil).Probe), arg0, arg1) +} + +// MockControllerServer is a mock of ControllerServer interface +type MockControllerServer struct { + ctrl *gomock.Controller + recorder *MockControllerServerMockRecorder +} + +// MockControllerServerMockRecorder is the mock recorder for MockControllerServer +type MockControllerServerMockRecorder struct { + mock *MockControllerServer +} + +// NewMockControllerServer creates a new mock instance +func NewMockControllerServer(ctrl *gomock.Controller) *MockControllerServer { + mock := &MockControllerServer{ctrl: ctrl} + mock.recorder = &MockControllerServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockControllerServer) EXPECT() *MockControllerServerMockRecorder { + return m.recorder +} + +// ControllerGetCapabilities mocks base method +func (m *MockControllerServer) ControllerGetCapabilities(arg0 context.Context, arg1 *v0.ControllerGetCapabilitiesRequest) (*v0.ControllerGetCapabilitiesResponse, error) { + ret := m.ctrl.Call(m, "ControllerGetCapabilities", arg0, arg1) + ret0, _ := ret[0].(*v0.ControllerGetCapabilitiesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ControllerGetCapabilities indicates an expected call of ControllerGetCapabilities +func (mr *MockControllerServerMockRecorder) ControllerGetCapabilities(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ControllerGetCapabilities", reflect.TypeOf((*MockControllerServer)(nil).ControllerGetCapabilities), arg0, arg1) +} + +// ControllerPublishVolume mocks base method +func (m *MockControllerServer) ControllerPublishVolume(arg0 context.Context, arg1 *v0.ControllerPublishVolumeRequest) (*v0.ControllerPublishVolumeResponse, error) { + ret := m.ctrl.Call(m, "ControllerPublishVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.ControllerPublishVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ControllerPublishVolume indicates an expected call of ControllerPublishVolume +func (mr *MockControllerServerMockRecorder) ControllerPublishVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ControllerPublishVolume", reflect.TypeOf((*MockControllerServer)(nil).ControllerPublishVolume), arg0, arg1) +} + +// ControllerUnpublishVolume mocks base method +func (m *MockControllerServer) ControllerUnpublishVolume(arg0 context.Context, arg1 *v0.ControllerUnpublishVolumeRequest) (*v0.ControllerUnpublishVolumeResponse, error) { + ret := m.ctrl.Call(m, "ControllerUnpublishVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.ControllerUnpublishVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ControllerUnpublishVolume indicates an expected call of ControllerUnpublishVolume +func (mr *MockControllerServerMockRecorder) ControllerUnpublishVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ControllerUnpublishVolume", reflect.TypeOf((*MockControllerServer)(nil).ControllerUnpublishVolume), arg0, arg1) +} + +// CreateVolume mocks base method +func (m *MockControllerServer) CreateVolume(arg0 context.Context, arg1 *v0.CreateVolumeRequest) (*v0.CreateVolumeResponse, error) { + ret := m.ctrl.Call(m, "CreateVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.CreateVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateVolume indicates an expected call of CreateVolume +func (mr *MockControllerServerMockRecorder) CreateVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateVolume", reflect.TypeOf((*MockControllerServer)(nil).CreateVolume), arg0, arg1) +} + +// DeleteVolume mocks base method +func (m *MockControllerServer) DeleteVolume(arg0 context.Context, arg1 *v0.DeleteVolumeRequest) (*v0.DeleteVolumeResponse, error) { + ret := m.ctrl.Call(m, "DeleteVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.DeleteVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteVolume indicates an expected call of DeleteVolume +func (mr *MockControllerServerMockRecorder) DeleteVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteVolume", reflect.TypeOf((*MockControllerServer)(nil).DeleteVolume), arg0, arg1) +} + +// GetCapacity mocks base method +func (m *MockControllerServer) GetCapacity(arg0 context.Context, arg1 *v0.GetCapacityRequest) (*v0.GetCapacityResponse, error) { + ret := m.ctrl.Call(m, "GetCapacity", arg0, arg1) + ret0, _ := ret[0].(*v0.GetCapacityResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCapacity indicates an expected call of GetCapacity +func (mr *MockControllerServerMockRecorder) GetCapacity(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCapacity", reflect.TypeOf((*MockControllerServer)(nil).GetCapacity), arg0, arg1) +} + +// ListVolumes mocks base method +func (m *MockControllerServer) ListVolumes(arg0 context.Context, arg1 *v0.ListVolumesRequest) (*v0.ListVolumesResponse, error) { + ret := m.ctrl.Call(m, "ListVolumes", arg0, arg1) + ret0, _ := ret[0].(*v0.ListVolumesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListVolumes indicates an expected call of ListVolumes +func (mr *MockControllerServerMockRecorder) ListVolumes(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVolumes", reflect.TypeOf((*MockControllerServer)(nil).ListVolumes), arg0, arg1) +} + +// ValidateVolumeCapabilities mocks base method +func (m *MockControllerServer) ValidateVolumeCapabilities(arg0 context.Context, arg1 *v0.ValidateVolumeCapabilitiesRequest) (*v0.ValidateVolumeCapabilitiesResponse, error) { + ret := m.ctrl.Call(m, "ValidateVolumeCapabilities", arg0, arg1) + ret0, _ := ret[0].(*v0.ValidateVolumeCapabilitiesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ValidateVolumeCapabilities indicates an expected call of ValidateVolumeCapabilities +func (mr *MockControllerServerMockRecorder) ValidateVolumeCapabilities(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateVolumeCapabilities", reflect.TypeOf((*MockControllerServer)(nil).ValidateVolumeCapabilities), arg0, arg1) +} + +// MockNodeServer is a mock of NodeServer interface +type MockNodeServer struct { + ctrl *gomock.Controller + recorder *MockNodeServerMockRecorder +} + +// MockNodeServerMockRecorder is the mock recorder for MockNodeServer +type MockNodeServerMockRecorder struct { + mock *MockNodeServer +} + +// NewMockNodeServer creates a new mock instance +func NewMockNodeServer(ctrl *gomock.Controller) *MockNodeServer { + mock := &MockNodeServer{ctrl: ctrl} + mock.recorder = &MockNodeServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockNodeServer) EXPECT() *MockNodeServerMockRecorder { + return m.recorder +} + +// NodeGetCapabilities mocks base method +func (m *MockNodeServer) NodeGetCapabilities(arg0 context.Context, arg1 *v0.NodeGetCapabilitiesRequest) (*v0.NodeGetCapabilitiesResponse, error) { + ret := m.ctrl.Call(m, "NodeGetCapabilities", arg0, arg1) + ret0, _ := ret[0].(*v0.NodeGetCapabilitiesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeGetCapabilities indicates an expected call of NodeGetCapabilities +func (mr *MockNodeServerMockRecorder) NodeGetCapabilities(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeGetCapabilities", reflect.TypeOf((*MockNodeServer)(nil).NodeGetCapabilities), arg0, arg1) +} + +// NodeGetId mocks base method +func (m *MockNodeServer) NodeGetId(arg0 context.Context, arg1 *v0.NodeGetIdRequest) (*v0.NodeGetIdResponse, error) { + ret := m.ctrl.Call(m, "NodeGetId", arg0, arg1) + ret0, _ := ret[0].(*v0.NodeGetIdResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeGetId indicates an expected call of NodeGetId +func (mr *MockNodeServerMockRecorder) NodeGetId(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeGetId", reflect.TypeOf((*MockNodeServer)(nil).NodeGetId), arg0, arg1) +} + +// NodePublishVolume mocks base method +func (m *MockNodeServer) NodePublishVolume(arg0 context.Context, arg1 *v0.NodePublishVolumeRequest) (*v0.NodePublishVolumeResponse, error) { + ret := m.ctrl.Call(m, "NodePublishVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.NodePublishVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodePublishVolume indicates an expected call of NodePublishVolume +func (mr *MockNodeServerMockRecorder) NodePublishVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodePublishVolume", reflect.TypeOf((*MockNodeServer)(nil).NodePublishVolume), arg0, arg1) +} + +// NodeStageVolume mocks base method +func (m *MockNodeServer) NodeStageVolume(arg0 context.Context, arg1 *v0.NodeStageVolumeRequest) (*v0.NodeStageVolumeResponse, error) { + ret := m.ctrl.Call(m, "NodeStageVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.NodeStageVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeStageVolume indicates an expected call of NodeStageVolume +func (mr *MockNodeServerMockRecorder) NodeStageVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeStageVolume", reflect.TypeOf((*MockNodeServer)(nil).NodeStageVolume), arg0, arg1) +} + +// NodeUnpublishVolume mocks base method +func (m *MockNodeServer) NodeUnpublishVolume(arg0 context.Context, arg1 *v0.NodeUnpublishVolumeRequest) (*v0.NodeUnpublishVolumeResponse, error) { + ret := m.ctrl.Call(m, "NodeUnpublishVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.NodeUnpublishVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeUnpublishVolume indicates an expected call of NodeUnpublishVolume +func (mr *MockNodeServerMockRecorder) NodeUnpublishVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeUnpublishVolume", reflect.TypeOf((*MockNodeServer)(nil).NodeUnpublishVolume), arg0, arg1) +} + +// NodeUnstageVolume mocks base method +func (m *MockNodeServer) NodeUnstageVolume(arg0 context.Context, arg1 *v0.NodeUnstageVolumeRequest) (*v0.NodeUnstageVolumeResponse, error) { + ret := m.ctrl.Call(m, "NodeUnstageVolume", arg0, arg1) + ret0, _ := ret[0].(*v0.NodeUnstageVolumeResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeUnstageVolume indicates an expected call of NodeUnstageVolume +func (mr *MockNodeServerMockRecorder) NodeUnstageVolume(arg0, arg1 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeUnstageVolume", reflect.TypeOf((*MockNodeServer)(nil).NodeUnstageVolume), arg0, arg1) +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/driver/mock.go b/vendor/github.com/kubernetes-csi/csi-test/driver/mock.go new file mode 100644 index 0000000000..9b051eee18 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/driver/mock.go @@ -0,0 +1,83 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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 driver + +import ( + "net" + + "github.com/kubernetes-csi/csi-test/utils" + "google.golang.org/grpc" +) + +type MockCSIDriverServers struct { + Controller *MockControllerServer + Identity *MockIdentityServer + Node *MockNodeServer +} + +type MockCSIDriver struct { + CSIDriver + conn *grpc.ClientConn +} + +func NewMockCSIDriver(servers *MockCSIDriverServers) *MockCSIDriver { + return &MockCSIDriver{ + CSIDriver: CSIDriver{ + servers: &CSIDriverServers{ + Controller: servers.Controller, + Node: servers.Node, + Identity: servers.Identity, + }, + }, + } +} + +func (m *MockCSIDriver) Start() error { + // Listen on a port assigned by the net package + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return err + } + + if err := m.CSIDriver.Start(l); err != nil { + l.Close() + return err + } + + return nil +} + +func (m *MockCSIDriver) Nexus() (*grpc.ClientConn, error) { + // Start server + err := m.Start() + if err != nil { + return nil, err + } + + // Create a client connection + m.conn, err = utils.Connect(m.Address()) + if err != nil { + return nil, err + } + + return m.conn, nil +} + +func (m *MockCSIDriver) Close() { + m.conn.Close() + m.server.Stop() +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/hack/e2e.sh b/vendor/github.com/kubernetes-csi/csi-test/hack/e2e.sh new file mode 100755 index 0000000000..abf2e2f586 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/hack/e2e.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +TESTARGS=$@ +UDS="/tmp/e2e-csi-sanity.sock" +CSI_ENDPOINTS="$CSI_ENDPOINTS ${UDS}" +CSI_MOCK_VERSION="master" + +# +# $1 - endpoint for mock. +# $2 - endpoint for csi-sanity in Grpc format. +# See https://github.com/grpc/grpc/blob/master/doc/naming.md +runTest() +{ + CSI_ENDPOINT=$1 mock & + local pid=$! + + csi-sanity $TESTARGS --csi.endpoint=$2; ret=$? + kill -9 $pid + + if [ $ret -ne 0 ] ; then + exit $ret + fi +} + +go install ./mock || exit 1 + +cd cmd/csi-sanity + make clean install || exit 1 +cd ../.. + +runTest "${UDS}" "${UDS}" +rm -f $UDS + +exit 0 diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/AUTHORS b/vendor/github.com/kubernetes-csi/csi-test/mock/AUTHORS new file mode 100644 index 0000000000..23eabcd296 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/AUTHORS @@ -0,0 +1,2 @@ +TheCodeTeam +Kubernetes Authors diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/README.md b/vendor/github.com/kubernetes-csi/csi-test/mock/README.md new file mode 100644 index 0000000000..d35e2d26e7 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/README.md @@ -0,0 +1,2 @@ +# Mock CSI Driver +Extremely simple mock driver used to test `csi-sanity` based on `rexray/gocsi/mock` diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/main.go b/vendor/github.com/kubernetes-csi/csi-test/mock/main.go new file mode 100644 index 0000000000..ef7b46acb8 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/main.go @@ -0,0 +1,82 @@ +/* +Copyright 2018 Kubernetes Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "fmt" + "net" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/kubernetes-csi/csi-test/driver" + "github.com/kubernetes-csi/csi-test/mock/service" +) + +func main() { + endpoint := os.Getenv("CSI_ENDPOINT") + if len(endpoint) == 0 { + fmt.Println("CSI_ENDPOINT must be defined and must be a path") + os.Exit(1) + } + if strings.Contains(endpoint, ":") { + fmt.Println("CSI_ENDPOINT must be a unix path") + os.Exit(1) + } + + // Create mock driver + s := service.New() + servers := &driver.CSIDriverServers{ + Controller: s, + Identity: s, + Node: s, + } + d := driver.NewCSIDriver(servers) + + // Listen + os.Remove(endpoint) + l, err := net.Listen("unix", endpoint) + if err != nil { + fmt.Printf("Error: Unable to listen on %s socket: %v\n", + endpoint, + err) + os.Exit(1) + } + defer os.Remove(endpoint) + + // Start server + if err := d.Start(l); err != nil { + fmt.Printf("Error: Unable to start mock CSI server: %v\n", + err) + os.Exit(1) + } + fmt.Println("mock driver started") + + // Wait for signal + sigc := make(chan os.Signal, 1) + sigs := []os.Signal{ + syscall.SIGTERM, + syscall.SIGHUP, + syscall.SIGINT, + syscall.SIGQUIT, + } + signal.Notify(sigc, sigs...) + + <-sigc + d.Stop() + fmt.Println("mock driver stopped") +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/service/controller.go b/vendor/github.com/kubernetes-csi/csi-test/mock/service/controller.go new file mode 100644 index 0000000000..e2d802d77e --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/service/controller.go @@ -0,0 +1,330 @@ +package service + +import ( + "fmt" + "math" + "path" + "strconv" + + log "github.com/sirupsen/logrus" + "golang.org/x/net/context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/container-storage-interface/spec/lib/go/csi/v0" +) + +const ( + MaxStorageCapacity = tib +) + +func (s *service) CreateVolume( + ctx context.Context, + req *csi.CreateVolumeRequest) ( + *csi.CreateVolumeResponse, error) { + + if len(req.Name) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume Name cannot be empty") + } + if req.VolumeCapabilities == nil { + return nil, status.Error(codes.InvalidArgument, "Volume Capabilities cannot be empty") + } + + // Check to see if the volume already exists. + if i, v := s.findVolByName(ctx, req.Name); i >= 0 { + // Requested volume name already exists, need to check if the existing volume's + // capacity is more or equal to new request's capacity. + if v.GetCapacityBytes() < req.GetCapacityRange().GetRequiredBytes() { + return nil, status.Error(codes.AlreadyExists, + fmt.Sprintf("Volume with name %s already exists", req.GetName())) + } + return &csi.CreateVolumeResponse{Volume: &v}, nil + } + + // If no capacity is specified then use 100GiB + capacity := gib100 + if cr := req.CapacityRange; cr != nil { + if rb := cr.RequiredBytes; rb > 0 { + capacity = rb + } + if lb := cr.LimitBytes; lb > 0 { + capacity = lb + } + } + // Check for maximum available capacity + if capacity >= MaxStorageCapacity { + return nil, status.Errorf(codes.OutOfRange, "Requested capacity %d exceeds maximum allowed %d", capacity, MaxStorageCapacity) + } + // Create the volume and add it to the service's in-mem volume slice. + v := s.newVolume(req.Name, capacity) + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + s.vols = append(s.vols, v) + MockVolumes[v.Id] = Volume{ + VolumeCSI: v, + NodeID: "", + ISStaged: false, + ISPublished: false, + StageTargetPath: "", + TargetPath: "", + } + + return &csi.CreateVolumeResponse{Volume: &v}, nil +} + +func (s *service) DeleteVolume( + ctx context.Context, + req *csi.DeleteVolumeRequest) ( + *csi.DeleteVolumeResponse, error) { + + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + + // If the volume is not specified, return error + if len(req.VolumeId) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty") + } + + // If the volume does not exist then return an idempotent response. + i, _ := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return &csi.DeleteVolumeResponse{}, nil + } + + // This delete logic preserves order and prevents potential memory + // leaks. The slice's elements may not be pointers, but the structs + // themselves have fields that are. + copy(s.vols[i:], s.vols[i+1:]) + s.vols[len(s.vols)-1] = csi.Volume{} + s.vols = s.vols[:len(s.vols)-1] + log.WithField("volumeID", req.VolumeId).Debug("mock delete volume") + return &csi.DeleteVolumeResponse{}, nil +} + +func (s *service) ControllerPublishVolume( + ctx context.Context, + req *csi.ControllerPublishVolumeRequest) ( + *csi.ControllerPublishVolumeResponse, error) { + + if len(req.VolumeId) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty") + } + if len(req.NodeId) == 0 { + return nil, status.Error(codes.InvalidArgument, "Node ID cannot be empty") + } + if req.VolumeCapability == nil { + return nil, status.Error(codes.InvalidArgument, "Volume Capabilities cannot be empty") + } + + if req.NodeId != s.nodeID { + return nil, status.Errorf(codes.NotFound, "Not matching Node ID %s to Mock Node ID %s", req.NodeId, s.nodeID) + } + + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + + i, v := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return nil, status.Error(codes.NotFound, req.VolumeId) + } + + // devPathKey is the key in the volume's attributes that is set to a + // mock device path if the volume has been published by the controller + // to the specified node. + devPathKey := path.Join(req.NodeId, "dev") + + // Check to see if the volume is already published. + if device := v.Attributes[devPathKey]; device != "" { + return &csi.ControllerPublishVolumeResponse{ + PublishInfo: map[string]string{ + "device": device, + }, + }, nil + } + + // Publish the volume. + device := "/dev/mock" + v.Attributes[devPathKey] = device + s.vols[i] = v + + return &csi.ControllerPublishVolumeResponse{ + PublishInfo: map[string]string{ + "device": device, + }, + }, nil +} + +func (s *service) ControllerUnpublishVolume( + ctx context.Context, + req *csi.ControllerUnpublishVolumeRequest) ( + *csi.ControllerUnpublishVolumeResponse, error) { + + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + + i, v := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return nil, status.Error(codes.NotFound, req.VolumeId) + } + + // devPathKey is the key in the volume's attributes that is set to a + // mock device path if the volume has been published by the controller + // to the specified node. + devPathKey := path.Join(req.NodeId, "dev") + + // Check to see if the volume is already unpublished. + if v.Attributes[devPathKey] == "" { + return &csi.ControllerUnpublishVolumeResponse{}, nil + } + + // Unpublish the volume. + delete(v.Attributes, devPathKey) + s.vols[i] = v + + return &csi.ControllerUnpublishVolumeResponse{}, nil +} + +func (s *service) ValidateVolumeCapabilities( + ctx context.Context, + req *csi.ValidateVolumeCapabilitiesRequest) ( + *csi.ValidateVolumeCapabilitiesResponse, error) { + + if len(req.GetVolumeId()) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty") + } + if len(req.VolumeCapabilities) == 0 { + return nil, status.Error(codes.InvalidArgument, req.VolumeId) + } + i, _ := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return nil, status.Error(codes.NotFound, req.VolumeId) + } + + return &csi.ValidateVolumeCapabilitiesResponse{ + Supported: true, + }, nil +} + +func (s *service) ListVolumes( + ctx context.Context, + req *csi.ListVolumesRequest) ( + *csi.ListVolumesResponse, error) { + + // Copy the mock volumes into a new slice in order to avoid + // locking the service's volume slice for the duration of the + // ListVolumes RPC. + var vols []csi.Volume + func() { + s.volsRWL.RLock() + defer s.volsRWL.RUnlock() + vols = make([]csi.Volume, len(s.vols)) + copy(vols, s.vols) + }() + + var ( + ulenVols = int32(len(vols)) + maxEntries = req.MaxEntries + startingToken int32 + ) + + if v := req.StartingToken; v != "" { + i, err := strconv.ParseUint(v, 10, 32) + if err != nil { + return nil, status.Errorf( + codes.InvalidArgument, + "startingToken=%d !< int32=%d", + startingToken, math.MaxUint32) + } + startingToken = int32(i) + } + + if startingToken > ulenVols { + return nil, status.Errorf( + codes.InvalidArgument, + "startingToken=%d > len(vols)=%d", + startingToken, ulenVols) + } + + // Discern the number of remaining entries. + rem := ulenVols - startingToken + + // If maxEntries is 0 or greater than the number of remaining entries then + // set maxEntries to the number of remaining entries. + if maxEntries == 0 || maxEntries > rem { + maxEntries = rem + } + + var ( + i int + j = startingToken + entries = make( + []*csi.ListVolumesResponse_Entry, + maxEntries) + ) + + for i = 0; i < len(entries); i++ { + entries[i] = &csi.ListVolumesResponse_Entry{ + Volume: &vols[j], + } + j++ + } + + var nextToken string + if n := startingToken + int32(i); n < ulenVols { + nextToken = fmt.Sprintf("%d", n) + } + + return &csi.ListVolumesResponse{ + Entries: entries, + NextToken: nextToken, + }, nil +} + +func (s *service) GetCapacity( + ctx context.Context, + req *csi.GetCapacityRequest) ( + *csi.GetCapacityResponse, error) { + + return &csi.GetCapacityResponse{ + AvailableCapacity: MaxStorageCapacity, + }, nil +} + +func (s *service) ControllerGetCapabilities( + ctx context.Context, + req *csi.ControllerGetCapabilitiesRequest) ( + *csi.ControllerGetCapabilitiesResponse, error) { + + return &csi.ControllerGetCapabilitiesResponse{ + Capabilities: []*csi.ControllerServiceCapability{ + { + Type: &csi.ControllerServiceCapability_Rpc{ + Rpc: &csi.ControllerServiceCapability_RPC{ + Type: csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME, + }, + }, + }, + { + Type: &csi.ControllerServiceCapability_Rpc{ + Rpc: &csi.ControllerServiceCapability_RPC{ + Type: csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME, + }, + }, + }, + { + Type: &csi.ControllerServiceCapability_Rpc{ + Rpc: &csi.ControllerServiceCapability_RPC{ + Type: csi.ControllerServiceCapability_RPC_LIST_VOLUMES, + }, + }, + }, + { + Type: &csi.ControllerServiceCapability_Rpc{ + Rpc: &csi.ControllerServiceCapability_RPC{ + Type: csi.ControllerServiceCapability_RPC_GET_CAPACITY, + }, + }, + }, + }, + }, nil +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/service/identity.go b/vendor/github.com/kubernetes-csi/csi-test/mock/service/identity.go new file mode 100644 index 0000000000..c83daea5f1 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/service/identity.go @@ -0,0 +1,45 @@ +package service + +import ( + "golang.org/x/net/context" + + "github.com/container-storage-interface/spec/lib/go/csi/v0" +) + +func (s *service) GetPluginInfo( + ctx context.Context, + req *csi.GetPluginInfoRequest) ( + *csi.GetPluginInfoResponse, error) { + + return &csi.GetPluginInfoResponse{ + Name: Name, + VendorVersion: VendorVersion, + Manifest: Manifest, + }, nil +} + +func (s *service) Probe( + ctx context.Context, + req *csi.ProbeRequest) ( + *csi.ProbeResponse, error) { + + return &csi.ProbeResponse{}, nil +} + +func (s *service) GetPluginCapabilities( + ctx context.Context, + req *csi.GetPluginCapabilitiesRequest) ( + *csi.GetPluginCapabilitiesResponse, error) { + + return &csi.GetPluginCapabilitiesResponse{ + Capabilities: []*csi.PluginCapability{ + { + Type: &csi.PluginCapability_Service_{ + Service: &csi.PluginCapability_Service{ + Type: csi.PluginCapability_Service_CONTROLLER_SERVICE, + }, + }, + }, + }, + }, nil +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/service/node.go b/vendor/github.com/kubernetes-csi/csi-test/mock/service/node.go new file mode 100644 index 0000000000..e4c7d874fe --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/service/node.go @@ -0,0 +1,135 @@ +package service + +import ( + "path" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "golang.org/x/net/context" + + "github.com/container-storage-interface/spec/lib/go/csi/v0" +) + +func (s *service) NodeStageVolume( + ctx context.Context, + req *csi.NodeStageVolumeRequest) ( + *csi.NodeStageVolumeResponse, error) { + + return nil, status.Error(codes.Unimplemented, "") +} + +func (s *service) NodeUnstageVolume( + ctx context.Context, + req *csi.NodeUnstageVolumeRequest) ( + *csi.NodeUnstageVolumeResponse, error) { + + return nil, status.Error(codes.Unimplemented, "") +} + +func (s *service) NodePublishVolume( + ctx context.Context, + req *csi.NodePublishVolumeRequest) ( + *csi.NodePublishVolumeResponse, error) { + + device, ok := req.PublishInfo["device"] + if !ok { + return nil, status.Error( + codes.InvalidArgument, + "publish volume info 'device' key required") + } + + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + + i, v := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return nil, status.Error(codes.NotFound, req.VolumeId) + } + + // nodeMntPathKey is the key in the volume's attributes that is set to a + // mock mount path if the volume has been published by the node + nodeMntPathKey := path.Join(s.nodeID, req.TargetPath) + + // Check to see if the volume has already been published. + if v.Attributes[nodeMntPathKey] != "" { + + // Requests marked Readonly fail due to volumes published by + // the Mock driver supporting only RW mode. + if req.Readonly { + return nil, status.Error(codes.AlreadyExists, req.VolumeId) + } + + return &csi.NodePublishVolumeResponse{}, nil + } + + // Publish the volume. + v.Attributes[nodeMntPathKey] = device + s.vols[i] = v + + return &csi.NodePublishVolumeResponse{}, nil +} + +func (s *service) NodeUnpublishVolume( + ctx context.Context, + req *csi.NodeUnpublishVolumeRequest) ( + *csi.NodeUnpublishVolumeResponse, error) { + + if len(req.GetVolumeId()) == 0 { + return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty") + } + if len(req.GetTargetPath()) == 0 { + return nil, status.Error(codes.InvalidArgument, "Target Path cannot be empty") + } + + s.volsRWL.Lock() + defer s.volsRWL.Unlock() + + i, v := s.findVolNoLock("id", req.VolumeId) + if i < 0 { + return nil, status.Error(codes.NotFound, req.VolumeId) + } + + // nodeMntPathKey is the key in the volume's attributes that is set to a + // mock mount path if the volume has been published by the node + nodeMntPathKey := path.Join(s.nodeID, req.TargetPath) + + // Check to see if the volume has already been unpublished. + if v.Attributes[nodeMntPathKey] == "" { + return &csi.NodeUnpublishVolumeResponse{}, nil + } + + // Unpublish the volume. + delete(v.Attributes, nodeMntPathKey) + s.vols[i] = v + + return &csi.NodeUnpublishVolumeResponse{}, nil +} + +func (s *service) NodeGetId( + ctx context.Context, + req *csi.NodeGetIdRequest) ( + *csi.NodeGetIdResponse, error) { + + return &csi.NodeGetIdResponse{ + NodeId: s.nodeID, + }, nil +} + +func (s *service) NodeGetCapabilities( + ctx context.Context, + req *csi.NodeGetCapabilitiesRequest) ( + *csi.NodeGetCapabilitiesResponse, error) { + + return &csi.NodeGetCapabilitiesResponse{ + Capabilities: []*csi.NodeServiceCapability{ + { + Type: &csi.NodeServiceCapability_Rpc{ + Rpc: &csi.NodeServiceCapability_RPC{ + Type: csi.NodeServiceCapability_RPC_UNKNOWN, + }, + }, + }, + }, + }, nil +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/mock/service/service.go b/vendor/github.com/kubernetes-csi/csi-test/mock/service/service.go new file mode 100644 index 0000000000..dccad79cd9 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/mock/service/service.go @@ -0,0 +1,111 @@ +package service + +import ( + "fmt" + "strings" + "sync" + "sync/atomic" + + "github.com/container-storage-interface/spec/lib/go/csi/v0" + "golang.org/x/net/context" +) + +const ( + // Name is the name of the CSI plug-in. + Name = "io.kubernetes.storage.mock" + + // VendorVersion is the version returned by GetPluginInfo. + VendorVersion = "0.2.0" +) + +// Manifest is the SP's manifest. +var Manifest = map[string]string{ + "url": "https://github.com/kubernetes-csi/csi-test/mock", +} + +// Service is the CSI Mock service provider. +type Service interface { + csi.ControllerServer + csi.IdentityServer + csi.NodeServer +} + +type service struct { + sync.Mutex + nodeID string + vols []csi.Volume + volsRWL sync.RWMutex + volsNID uint64 +} + +type Volume struct { + sync.Mutex + VolumeCSI csi.Volume + NodeID string + ISStaged bool + ISPublished bool + StageTargetPath string + TargetPath string +} + +var MockVolumes map[string]Volume + +// New returns a new Service. +func New() Service { + s := &service{nodeID: Name} + s.vols = []csi.Volume{ + s.newVolume("Mock Volume 1", gib100), + s.newVolume("Mock Volume 2", gib100), + s.newVolume("Mock Volume 3", gib100), + } + MockVolumes = map[string]Volume{} + return s +} + +const ( + kib int64 = 1024 + mib int64 = kib * 1024 + gib int64 = mib * 1024 + gib100 int64 = gib * 100 + tib int64 = gib * 1024 + tib100 int64 = tib * 100 +) + +func (s *service) newVolume(name string, capcity int64) csi.Volume { + return csi.Volume{ + Id: fmt.Sprintf("%d", atomic.AddUint64(&s.volsNID, 1)), + Attributes: map[string]string{"name": name}, + CapacityBytes: capcity, + } +} + +func (s *service) findVol(k, v string) (volIdx int, volInfo csi.Volume) { + s.volsRWL.RLock() + defer s.volsRWL.RUnlock() + return s.findVolNoLock(k, v) +} + +func (s *service) findVolNoLock(k, v string) (volIdx int, volInfo csi.Volume) { + volIdx = -1 + + for i, vi := range s.vols { + switch k { + case "id": + if strings.EqualFold(v, vi.Id) { + return i, vi + } + case "name": + if n, ok := vi.Attributes["name"]; ok && strings.EqualFold(v, n) { + return i, vi + } + } + } + + return +} + +func (s *service) findVolByName( + ctx context.Context, name string) (int, csi.Volume) { + + return s.findVol("name", name) +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/README.md b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/README.md new file mode 100644 index 0000000000..747744ea48 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/README.md @@ -0,0 +1,25 @@ +# CSI Driver Sanity Tester + +This library provides a simple way to ensure that a CSI driver conforms to +the CSI specification. There are two ways to leverage this testing framework. +For CSI drivers written in Golang, the framework provides a simple API function +to call to test the driver. Another way to run the test suite is to use the +command line program [csi-sanity](https://github.com/kubernetes-csi/csi-test/tree/master/cmd/csi-sanity). + +## For Golang CSI Drivers +This framework leverages the Ginkgo BDD testing framework to deliver a descriptive +test suite for your driver. To test your driver, simply call the API in one of your +Golang `TestXXX` functions. For example: + +```go +func TestMyDriver(t *testing.T) { + // Setup the full driver and its environment + ... setup driver ... + + // Now call the test suite + sanity.Test(t, driverEndpointAddress, "/mnt") +} +``` + +## Command line program +Please see [csi-sanity](https://github.com/kubernetes-csi/csi-test/tree/master/cmd/csi-sanity) diff --git a/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/controller.go b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/controller.go new file mode 100644 index 0000000000..e6c6ad9bfe --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/controller.go @@ -0,0 +1,808 @@ +/* +Copyright 2017 Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sanity + +import ( + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + context "golang.org/x/net/context" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func verifyVolumeInfo(v *csi.Volume) { + Expect(v).NotTo(BeNil()) + Expect(v.GetId()).NotTo(BeEmpty()) +} + +func isCapabilitySupported( + c csi.ControllerClient, + capType csi.ControllerServiceCapability_RPC_Type, +) bool { + + caps, err := c.ControllerGetCapabilities( + context.Background(), + &csi.ControllerGetCapabilitiesRequest{}) + Expect(err).NotTo(HaveOccurred()) + Expect(caps).NotTo(BeNil()) + Expect(caps.GetCapabilities()).NotTo(BeNil()) + + for _, cap := range caps.GetCapabilities() { + Expect(cap.GetRpc()).NotTo(BeNil()) + if cap.GetRpc().GetType() == capType { + return true + } + } + return false +} + +var _ = Describe("ControllerGetCapabilities [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + }) + + It("should return appropriate capabilities", func() { + caps, err := c.ControllerGetCapabilities( + context.Background(), + &csi.ControllerGetCapabilitiesRequest{}) + + By("checking successful response") + Expect(err).NotTo(HaveOccurred()) + Expect(caps).NotTo(BeNil()) + Expect(caps.GetCapabilities()).NotTo(BeNil()) + + for _, cap := range caps.GetCapabilities() { + Expect(cap.GetRpc()).NotTo(BeNil()) + + switch cap.GetRpc().GetType() { + case csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME: + case csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME: + case csi.ControllerServiceCapability_RPC_LIST_VOLUMES: + case csi.ControllerServiceCapability_RPC_GET_CAPACITY: + default: + Fail(fmt.Sprintf("Unknown capability: %v\n", cap.GetRpc().GetType())) + } + } + }) +}) + +var _ = Describe("GetCapacity [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_GET_CAPACITY) { + Skip("GetCapacity not supported") + } + }) + + It("should return capacity (no optional values added)", func() { + _, err := c.GetCapacity( + context.Background(), + &csi.GetCapacityRequest{}) + Expect(err).NotTo(HaveOccurred()) + + // Since capacity is int64 we will not be checking it + // The value of zero is a possible value. + }) +}) + +var _ = Describe("ListVolumes [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_LIST_VOLUMES) { + Skip("ListVolumes not supported") + } + }) + + It("should return appropriate values (no optional values added)", func() { + vols, err := c.ListVolumes( + context.Background(), + &csi.ListVolumesRequest{}) + Expect(err).NotTo(HaveOccurred()) + Expect(vols).NotTo(BeNil()) + + for _, vol := range vols.GetEntries() { + verifyVolumeInfo(vol.GetVolume()) + } + }) + + // TODO: Add test to test for tokens + + // TODO: Add test which checks list of volume is there when created, + // and not there when deleted. +}) + +var _ = Describe("CreateVolume [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { + Skip("CreateVolume not supported") + } + }) + + It("should fail when no name is provided", func() { + + _, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no volume capabilities are provided", func() { + + _, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: "name", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should return appropriate values SingleNodeWriter NoCapacity Type:Mount", func() { + + By("creating a volume") + name := "sanity" + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should return appropriate values SingleNodeWriter WithCapacity 1Gi Type:Mount", func() { + + By("creating a volume") + name := "sanity" + size := int64(1 * 1024 * 1024 * 1024) + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size, + }, + }) + if serverError, ok := status.FromError(err); ok { + if serverError.Code() == codes.OutOfRange || serverError.Code() == codes.Unimplemented { + Skip("Required bytes not supported") + } else { + Expect(err).NotTo(HaveOccurred()) + } + } else { + + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + Expect(vol.GetVolume().GetCapacityBytes()).To(Equal(size)) + } + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) + It("should not fail when requesting to create a volume with already exisiting name and same capacity.", func() { + + By("creating a volume") + name := "sanity" + size := int64(1 * 1024 * 1024 * 1024) + vol1, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol1).NotTo(BeNil()) + Expect(vol1.GetVolume()).NotTo(BeNil()) + Expect(vol1.GetVolume().GetId()).NotTo(BeEmpty()) + Expect(vol1.GetVolume().GetCapacityBytes()).To(Equal(size)) + vol2, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol2).NotTo(BeNil()) + Expect(vol2.GetVolume()).NotTo(BeNil()) + Expect(vol2.GetVolume().GetId()).NotTo(BeEmpty()) + Expect(vol2.GetVolume().GetCapacityBytes()).To(Equal(size)) + Expect(vol1.GetVolume().GetId()).To(Equal(vol2.GetVolume().GetId())) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol1.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) + It("should fail when requesting to create a volume with already exisiting name and different capacity.", func() { + + By("creating a volume") + name := "sanity" + size1 := int64(1 * 1024 * 1024 * 1024) + vol1, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size1, + }, + }) + Expect(err).ToNot(HaveOccurred()) + Expect(vol1).NotTo(BeNil()) + Expect(vol1.GetVolume()).NotTo(BeNil()) + Expect(vol1.GetVolume().GetId()).NotTo(BeEmpty()) + size2 := int64(2 * 1024 * 1024 * 1024) + _, err = c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size2, + }, + }) + Expect(err).To(HaveOccurred()) + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.AlreadyExists)) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol1.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) + It("should fail when requesting to create a volume exceeding Maximum Capacity", func() { + + By("creating a volume") + name := "sanity" + size := int64(10 * 1024 * 1024 * 1024 * 1024) + _, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + CapacityRange: &csi.CapacityRange{ + RequiredBytes: size, + }, + }) + Expect(err).To(HaveOccurred()) + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.OutOfRange)) + }) +}) + +var _ = Describe("DeleteVolume [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { + Skip("DeleteVolume not supported") + } + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should succeed when an invalid volume id is used", func() { + + _, err := c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: "reallyfakevolumeid", + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a volume") + name := "sanity" + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + // Delete Volume + By("deleting a volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) + +var _ = Describe("ValidateVolumeCapabilities [Controller Server]", func() { + var ( + c csi.ControllerClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.ValidateVolumeCapabilities( + context.Background(), + &csi.ValidateVolumeCapabilitiesRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no volume capabilities are provided", func() { + + _, err := c.ValidateVolumeCapabilities( + context.Background(), + &csi.ValidateVolumeCapabilitiesRequest{ + VolumeId: "id", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a single node writer volume") + name := "sanity" + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + // ValidateVolumeCapabilities + By("validating volume capabilities") + valivolcap, err := c.ValidateVolumeCapabilities( + context.Background(), + &csi.ValidateVolumeCapabilitiesRequest{ + VolumeId: vol.GetVolume().GetId(), + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(valivolcap).NotTo(BeNil()) + Expect(valivolcap.GetSupported()).To(BeTrue()) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) + +var _ = Describe("ControllerPublishVolume [Controller Server]", func() { + var ( + c csi.ControllerClient + n csi.NodeClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + n = csi.NewNodeClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { + Skip("ControllerPublishVolume not supported") + } + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no node id is provided", func() { + + _, err := c.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: "id", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no volume capability is provided", func() { + + _, err := c.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: "id", + NodeId: "fakenode", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a single node writer volume") + name := "sanity" + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + By("getting a node id") + nid, err := n.NodeGetId( + context.Background(), + &csi.NodeGetIdRequest{}) + Expect(err).NotTo(HaveOccurred()) + Expect(nid).NotTo(BeNil()) + Expect(nid.GetNodeId()).NotTo(BeEmpty()) + + // ControllerPublishVolume + By("calling controllerpublish on that volume") + conpubvol, err := c.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + NodeId: nid.GetNodeId(), + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + Readonly: false, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conpubvol).NotTo(BeNil()) + + By("cleaning up unpublishing the volume") + conunpubvol, err := c.ControllerUnpublishVolume( + context.Background(), + &csi.ControllerUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + // NodeID is optional in ControllerUnpublishVolume + NodeId: nid.GetNodeId(), + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conunpubvol).NotTo(BeNil()) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) + +var _ = Describe("ControllerUnpublishVolume [Controller Server]", func() { + var ( + c csi.ControllerClient + n csi.NodeClient + ) + + BeforeEach(func() { + c = csi.NewControllerClient(conn) + n = csi.NewNodeClient(conn) + + if !isCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { + Skip("ControllerUnpublishVolume not supported") + } + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.ControllerUnpublishVolume( + context.Background(), + &csi.ControllerUnpublishVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.NotFound)) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a single node writer volume") + name := "sanity" + vol, err := c.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + By("getting a node id") + nid, err := n.NodeGetId( + context.Background(), + &csi.NodeGetIdRequest{}) + Expect(err).NotTo(HaveOccurred()) + Expect(nid).NotTo(BeNil()) + Expect(nid.GetNodeId()).NotTo(BeEmpty()) + + // ControllerPublishVolume + By("calling controllerpublish on that volume") + conpubvol, err := c.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + NodeId: nid.GetNodeId(), + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + Readonly: false, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conpubvol).NotTo(BeNil()) + + // ControllerUnpublishVolume + By("calling controllerunpublish on that volume") + conunpubvol, err := c.ControllerUnpublishVolume( + context.Background(), + &csi.ControllerUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + // NodeID is optional in ControllerUnpublishVolume + NodeId: nid.GetNodeId(), + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conunpubvol).NotTo(BeNil()) + + By("cleaning up deleting the volume") + _, err = c.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) diff --git a/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/identity.go b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/identity.go new file mode 100644 index 0000000000..4df4d4b442 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/identity.go @@ -0,0 +1,55 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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 sanity + +import ( + "regexp" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + context "golang.org/x/net/context" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +// TODO: Tests for GetPluginCapabilities + +// TODO: Tests for Probe + +var _ = Describe("GetPluginInfo [Identity Server]", func() { + var ( + c csi.IdentityClient + ) + + BeforeEach(func() { + c = csi.NewIdentityClient(conn) + }) + + It("should return appropriate information", func() { + req := &csi.GetPluginInfoRequest{} + res, err := c.GetPluginInfo(context.Background(), req) + Expect(err).NotTo(HaveOccurred()) + Expect(res).NotTo(BeNil()) + + By("verifying name size and characters") + Expect(res.GetName()).ToNot(HaveLen(0)) + Expect(len(res.GetName())).To(BeNumerically("<=", 63)) + Expect(regexp. + MustCompile("^[a-zA-Z][A-Za-z0-9-\\.\\_]{0,61}[a-zA-Z]$"). + MatchString(res.GetName())).To(BeTrue()) + }) +}) diff --git a/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/node.go b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/node.go new file mode 100644 index 0000000000..e3f3902276 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/node.go @@ -0,0 +1,388 @@ +/* +Copyright 2017 Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sanity + +import ( + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + context "golang.org/x/net/context" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("NodeGetCapabilities [Node Server]", func() { + var ( + c csi.NodeClient + ) + + BeforeEach(func() { + c = csi.NewNodeClient(conn) + }) + + It("should return appropriate capabilities", func() { + caps, err := c.NodeGetCapabilities( + context.Background(), + &csi.NodeGetCapabilitiesRequest{}) + + By("checking successful response") + Expect(err).NotTo(HaveOccurred()) + Expect(caps).NotTo(BeNil()) + Expect(caps.GetCapabilities()).NotTo(BeNil()) + + for _, cap := range caps.GetCapabilities() { + Expect(cap.GetRpc()).NotTo(BeNil()) + + switch cap.GetRpc().GetType() { + case csi.NodeServiceCapability_RPC_UNKNOWN: + default: + Fail(fmt.Sprintf("Unknown capability: %v\n", cap.GetRpc().GetType())) + } + } + }) +}) + +var _ = Describe("NodeGetId [Node Server]", func() { + var ( + c csi.NodeClient + ) + + BeforeEach(func() { + c = csi.NewNodeClient(conn) + }) + + It("should return appropriate values", func() { + nid, err := c.NodeGetId( + context.Background(), + &csi.NodeGetIdRequest{}) + + Expect(err).NotTo(HaveOccurred()) + Expect(nid).NotTo(BeNil()) + Expect(nid.GetNodeId()).NotTo(BeEmpty()) + }) +}) + +var _ = Describe("NodePublishVolume [Node Server]", func() { + var ( + s csi.ControllerClient + c csi.NodeClient + controllerPublishSupported bool + ) + + BeforeEach(func() { + s = csi.NewControllerClient(conn) + c = csi.NewNodeClient(conn) + controllerPublishSupported = isCapabilitySupported( + s, + csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.NodePublishVolume( + context.Background(), + &csi.NodePublishVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no target path is provided", func() { + + _, err := c.NodePublishVolume( + context.Background(), + &csi.NodePublishVolumeRequest{ + VolumeId: "id", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no volume capability is provided", func() { + + _, err := c.NodePublishVolume( + context.Background(), + &csi.NodePublishVolumeRequest{ + VolumeId: "id", + TargetPath: csiTargetPath, + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a single node writer volume") + name := "sanity" + vol, err := s.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + By("getting a node id") + nid, err := c.NodeGetId( + context.Background(), + &csi.NodeGetIdRequest{}) + Expect(err).NotTo(HaveOccurred()) + Expect(nid).NotTo(BeNil()) + Expect(nid.GetNodeId()).NotTo(BeEmpty()) + var conpubvol *csi.ControllerPublishVolumeResponse + if controllerPublishSupported { + By("controller publishing volume") + conpubvol, err = s.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + NodeId: nid.GetNodeId(), + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + Readonly: false, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conpubvol).NotTo(BeNil()) + } + // NodePublishVolume + By("publishing the volume on a node") + nodepubvolRequest := &csi.NodePublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + } + if controllerPublishSupported { + nodepubvolRequest.PublishInfo = conpubvol.GetPublishInfo() + } + nodepubvol, err := c.NodePublishVolume(context.Background(), nodepubvolRequest) + Expect(err).NotTo(HaveOccurred()) + Expect(nodepubvol).NotTo(BeNil()) + + // NodeUnpublishVolume + By("cleaning up calling nodeunpublish") + nodeunpubvol, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(nodeunpubvol).NotTo(BeNil()) + + if controllerPublishSupported { + By("cleaning up calling controllerunpublishing the volume") + nodeunpubvol, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(nodeunpubvol).NotTo(BeNil()) + } + + By("cleaning up deleting the volume") + _, err = s.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) + +var _ = Describe("NodeUnpublishVolume [Node Server]", func() { + var ( + s csi.ControllerClient + c csi.NodeClient + controllerPublishSupported bool + ) + + BeforeEach(func() { + s = csi.NewControllerClient(conn) + c = csi.NewNodeClient(conn) + controllerPublishSupported = isCapabilitySupported( + s, + csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) + }) + + It("should fail when no volume id is provided", func() { + + _, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{}) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should fail when no target path is provided", func() { + + _, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{ + VolumeId: "id", + }) + Expect(err).To(HaveOccurred()) + + serverError, ok := status.FromError(err) + Expect(ok).To(BeTrue()) + Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) + }) + + It("should return appropriate values (no optional values added)", func() { + + // Create Volume First + By("creating a single node writer volume") + name := "sanity" + vol, err := s.CreateVolume( + context.Background(), + &csi.CreateVolumeRequest{ + Name: name, + VolumeCapabilities: []*csi.VolumeCapability{ + { + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + }, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(vol).NotTo(BeNil()) + Expect(vol.GetVolume()).NotTo(BeNil()) + Expect(vol.GetVolume().GetId()).NotTo(BeEmpty()) + + // ControllerPublishVolume + var conpubvol *csi.ControllerPublishVolumeResponse + if controllerPublishSupported { + By("calling controllerpublish on the volume") + conpubvol, err = s.ControllerPublishVolume( + context.Background(), + &csi.ControllerPublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + NodeId: "io.kubernetes.storage.mock", + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + Readonly: false, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(conpubvol).NotTo(BeNil()) + } + + // NodePublishVolume + By("publishing the volume on a node") + nodepubvolRequest := &csi.NodePublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + VolumeCapability: &csi.VolumeCapability{ + AccessType: &csi.VolumeCapability_Mount{ + Mount: &csi.VolumeCapability_MountVolume{}, + }, + AccessMode: &csi.VolumeCapability_AccessMode{ + Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER, + }, + }, + } + if controllerPublishSupported { + nodepubvolRequest.PublishInfo = conpubvol.GetPublishInfo() + } + nodepubvol, err := c.NodePublishVolume(context.Background(), nodepubvolRequest) + Expect(err).NotTo(HaveOccurred()) + Expect(nodepubvol).NotTo(BeNil()) + + // NodeUnpublishVolume + nodeunpubvol, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(nodeunpubvol).NotTo(BeNil()) + + if controllerPublishSupported { + By("cleaning up unpublishing the volume") + nodeunpubvol, err := c.NodeUnpublishVolume( + context.Background(), + &csi.NodeUnpublishVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + TargetPath: csiTargetPath, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(nodeunpubvol).NotTo(BeNil()) + } + + By("cleaning up deleting the volume") + _, err = s.DeleteVolume( + context.Background(), + &csi.DeleteVolumeRequest{ + VolumeId: vol.GetVolume().GetId(), + }) + Expect(err).NotTo(HaveOccurred()) + }) +}) + +// TODO: Tests for NodeStageVolume/NodeUnstageVolume diff --git a/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/sanity.go b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/sanity.go new file mode 100644 index 0000000000..0acb159c54 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/pkg/sanity/sanity.go @@ -0,0 +1,80 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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 sanity + +import ( + "fmt" + "os" + "sync" + "testing" + + "github.com/kubernetes-csi/csi-test/utils" + + "google.golang.org/grpc" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var ( + driverAddress string + csiTargetPath string + conn *grpc.ClientConn + lock sync.Mutex +) + +// Test will test the CSI driver at the specified address +func Test(t *testing.T, address, mountPoint string) { + lock.Lock() + defer lock.Unlock() + + driverAddress = address + csiTargetPath = mountPoint + RegisterFailHandler(Fail) + RunSpecs(t, "CSI Driver Test Suite") +} + +var _ = BeforeSuite(func() { + var err error + + By("connecting to CSI driver") + conn, err = utils.Connect(driverAddress) + Expect(err).NotTo(HaveOccurred()) + + By("creating mount directory") + err = createMountTargetLocation(csiTargetPath) + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + conn.Close() + os.Remove(csiTargetPath) +}) + +func createMountTargetLocation(targetPath string) error { + fileInfo, err := os.Stat(targetPath) + if err != nil && os.IsNotExist(err) { + return os.Mkdir(targetPath, 0755) + } else if err != nil { + return err + } + if !fileInfo.IsDir() { + return fmt.Errorf("Target location %s is not a directory", targetPath) + } + + return nil +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/test/co_test.go b/vendor/github.com/kubernetes-csi/csi-test/test/co_test.go new file mode 100644 index 0000000000..d4e5dfc381 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/test/co_test.go @@ -0,0 +1,105 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package test + +import ( + "testing" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + gomock "github.com/golang/mock/gomock" + mock_driver "github.com/kubernetes-csi/csi-test/driver" + mock_utils "github.com/kubernetes-csi/csi-test/utils" + "golang.org/x/net/context" +) + +func TestPluginInfoResponse(t *testing.T) { + + // Setup mock + m := gomock.NewController(t) + defer m.Finish() + driver := mock_driver.NewMockIdentityServer(m) + + // Setup input + in := &csi.GetPluginInfoRequest{} + + // Setup mock outout + out := &csi.GetPluginInfoResponse{ + Name: "mock", + VendorVersion: "0.1.1", + Manifest: map[string]string{ + "hello": "world", + }, + } + + // Setup expectation + driver.EXPECT().GetPluginInfo(nil, in).Return(out, nil).Times(1) + + // Actual call + r, err := driver.GetPluginInfo(nil, in) + name := r.GetName() + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + if name != "mock" { + t.Errorf("Unknown name: %s\n", name) + } +} + +func TestGRPCGetPluginInfoReponse(t *testing.T) { + + // Setup mock + m := gomock.NewController(&mock_utils.SafeGoroutineTester{}) + defer m.Finish() + driver := mock_driver.NewMockIdentityServer(m) + + // Setup input + in := &csi.GetPluginInfoRequest{} + + // Setup mock outout + out := &csi.GetPluginInfoResponse{ + Name: "mock", + VendorVersion: "0.1.1", + Manifest: map[string]string{ + "hello": "world", + }, + } + + // Setup expectation + // !IMPORTANT!: Must set context expected value to gomock.Any() to match any value + driver.EXPECT().GetPluginInfo(gomock.Any(), in).Return(out, nil).Times(1) + + // Create a new RPC + server := mock_driver.NewMockCSIDriver(&mock_driver.MockCSIDriverServers{ + Identity: driver, + }) + conn, err := server.Nexus() + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + defer server.Close() + + // Make call + c := csi.NewIdentityClient(conn) + r, err := c.GetPluginInfo(context.Background(), in) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + + name := r.GetName() + if name != "mock" { + t.Errorf("Unknown name: %s\n", name) + } +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/test/driver_test.go b/vendor/github.com/kubernetes-csi/csi-test/test/driver_test.go new file mode 100644 index 0000000000..4b0122b6ce --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/test/driver_test.go @@ -0,0 +1,127 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package test + +import ( + "context" + "net" + "sync" + "testing" + + csi "github.com/container-storage-interface/spec/lib/go/csi/v0" + "github.com/kubernetes-csi/csi-test/utils" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +// Example simple driver +// This example assumes that your driver will create the server and listen on +// some unix domain socket or port for tests. +type simpleDriver struct { + listener net.Listener + server *grpc.Server + wg sync.WaitGroup +} + +func (s *simpleDriver) GetPluginCapabilities(context.Context, *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) { + // TODO: Return some simple Plugin Capabilities + return &csi.GetPluginCapabilitiesResponse{}, nil +} + +func (s *simpleDriver) Probe(context.Context, *csi.ProbeRequest) (*csi.ProbeResponse, error) { + return &csi.ProbeResponse{}, nil +} + +func (s *simpleDriver) GetPluginInfo( + context.Context, *csi.GetPluginInfoRequest) (*csi.GetPluginInfoResponse, error) { + return &csi.GetPluginInfoResponse{ + Name: "simpleDriver", + VendorVersion: "0.1.1", + Manifest: map[string]string{ + "hello": "world", + }, + }, nil +} + +func (s *simpleDriver) goServe() { + s.wg.Add(1) + go func() { + defer s.wg.Done() + s.server.Serve(s.listener) + }() +} + +func (s *simpleDriver) Address() string { + return s.listener.Addr().String() +} + +func (s *simpleDriver) Start() error { + // Listen on a port assigned by the net package + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return err + } + s.listener = l + + // Create a new grpc server + s.server = grpc.NewServer() + + csi.RegisterIdentityServer(s.server, s) + reflection.Register(s.server) + + // Start listening for requests + s.goServe() + return nil +} + +func (s *simpleDriver) Stop() { + s.server.Stop() + s.wg.Wait() +} + +// +// Tests +// +func TestSimpleDriver(t *testing.T) { + + // Setup simple driver + s := &simpleDriver{} + err := s.Start() + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + defer s.Stop() + + // Setup a connection to the driver + conn, err := utils.Connect(s.Address()) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + defer conn.Close() + + // Make a call + c := csi.NewIdentityClient(conn) + r, err := c.GetPluginInfo(context.Background(), &csi.GetPluginInfoRequest{}) + if err != nil { + t.Errorf("Error: %s", err.Error()) + } + + // Verify + name := r.GetName() + if name != "simpleDriver" { + t.Errorf("Unknown name: %s\n", name) + } +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/utils/grpcutil.go b/vendor/github.com/kubernetes-csi/csi-test/utils/grpcutil.go new file mode 100644 index 0000000000..20eebbc898 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/utils/grpcutil.go @@ -0,0 +1,59 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import ( + "context" + "fmt" + "net" + "net/url" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" +) + +// Connect address by grpc +func Connect(address string) (*grpc.ClientConn, error) { + dialOptions := []grpc.DialOption{ + grpc.WithInsecure(), + } + u, err := url.Parse(address) + if err == nil && (!u.IsAbs() || u.Scheme == "unix") { + dialOptions = append(dialOptions, + grpc.WithDialer( + func(addr string, timeout time.Duration) (net.Conn, error) { + return net.DialTimeout("unix", u.Path, timeout) + })) + } + + conn, err := grpc.Dial(address, dialOptions...) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + for { + if !conn.WaitForStateChange(ctx, conn.GetState()) { + return conn, fmt.Errorf("Connection timed out") + } + if conn.GetState() == connectivity.Ready { + return conn, nil + } + } +} diff --git a/vendor/github.com/kubernetes-csi/csi-test/utils/safegoroutinetester.go b/vendor/github.com/kubernetes-csi/csi-test/utils/safegoroutinetester.go new file mode 100644 index 0000000000..c89a5cf1d7 --- /dev/null +++ b/vendor/github.com/kubernetes-csi/csi-test/utils/safegoroutinetester.go @@ -0,0 +1,40 @@ +/* +Copyright 2017 Luis Pabón luis@portworx.com + +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 utils + +import "fmt" + +// SafeGoroutineTester is an implementation of the mock ... interface +// which can be used to use the mock functions in another go routine. +// +// The major issue is that the golang mock framework uses t.Fatalf() +// which causes a deadlock when called in another goroutine. To avoid +// this issue, this simple implementation prints the error then panics, +// which avoids the deadlock. +type SafeGoroutineTester struct{} + +// Errorf prints the error to the screen then panics +func (s *SafeGoroutineTester) Errorf(format string, args ...interface{}) { + fmt.Printf(format, args) + panic("MOCK TEST ERROR") +} + +// Fatalf prints the error to the screen then panics +func (s *SafeGoroutineTester) Fatalf(format string, args ...interface{}) { + fmt.Printf(format+"\n", args...) + panic("MOCK TEST FATAL FAILURE") +} diff --git a/vendor/github.com/kubernetes-incubator/external-storage/flex/pkg/volume/provision.go b/vendor/github.com/kubernetes-incubator/external-storage/flex/pkg/volume/provision.go index 90cb11efdc..bb4c481b05 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/flex/pkg/volume/provision.go +++ b/vendor/github.com/kubernetes-incubator/external-storage/flex/pkg/volume/provision.go @@ -91,7 +91,7 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)], }, PersistentVolumeSource: v1.PersistentVolumeSource{ - FlexVolume: &v1.FlexVolumeSource{ + FlexVolume: &v1.FlexPersistentVolumeSource{ Driver: "flex", Options: map[string]string{}, ReadOnly: false, diff --git a/vendor/github.com/kubernetes-incubator/external-storage/glide.lock b/vendor/github.com/kubernetes-incubator/external-storage/glide.lock index c57d941a3a..2368aae78b 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/glide.lock +++ b/vendor/github.com/kubernetes-incubator/external-storage/glide.lock @@ -1,5 +1,5 @@ -hash: a28f6921f3abfce8e85777529ceff33cdbfefff5f3e320c43fd30ff4e1ddbce1 -updated: 2018-01-30T11:46:25.637858333+08:00 +hash: bad5b8cc5504a88c060c3135c372b906550627273744530f1af8a53eedf50dac +updated: 2018-03-05T14:22:31.127141222Z imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -7,7 +7,7 @@ imports: - compute/metadata - internal - name: github.com/aws/aws-sdk-go - version: 1b176c5c6b57adb03bb982c21930e708ebca5a77 + version: aace5875a5c3b85a3902c6d72b9caed301d64cce subpackages: - aws - aws/awserr @@ -25,6 +25,7 @@ imports: - aws/request - aws/session - aws/signer/v4 + - internal/sdkrand - internal/shareddefaults - private/protocol - private/protocol/ec2query @@ -86,31 +87,19 @@ imports: version: 449fdfce4d962303d702fec724ef0ad181c92528 subpackages: - spdy -- name: github.com/emicklei/go-restful - version: ff4f55a206334ef123e4f79bbf348980da81ca46 - subpackages: - - log - name: github.com/fsnotify/fsnotify version: f12c6236fe7b5cf6bcf30e5935d08cb079d78334 - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee - name: github.com/go-ini/ini - version: 2e44421e256d82ebbf3d4d4fcabe8930b905eff3 -- name: github.com/go-openapi/jsonpointer - version: 46af16f9f7b149af66e5d1bd010e3574dc06de98 -- name: github.com/go-openapi/jsonreference - version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272 -- name: github.com/go-openapi/spec - version: 7abd5745472fff5eb3685386d5fb8bf38683154d -- name: github.com/go-openapi/swag - version: f3f9494671f93fcff853e3c6e9e948b3eb71e590 + version: e88632e2fbbd517932de8a0af39beb223b03ae35 - name: github.com/gogo/protobuf version: c0656edd0d9eab7c66d1eb0c568f9039345796f7 subpackages: - proto - sortkeys - name: github.com/golang/glog - version: 44145f04b68cf362d9c4df2182967c2275eaefed + version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998 - name: github.com/golang/groupcache version: 02826c3e79038b59d737d3b1c0a1d937f71a4433 subpackages: @@ -123,10 +112,8 @@ imports: - ptypes/any - ptypes/duration - ptypes/timestamp -- name: github.com/google/btree - version: 7d79101e329e5a3adf994758c578dab82b90c017 - name: github.com/google/go-querystring - version: 9235644dd9e52eeae6fa48efd539fdc351a0af53 + version: 53e6ce116135b80d037921a7fdd5138cf32d7a8a subpackages: - query - name: github.com/google/gofuzz @@ -170,10 +157,6 @@ imports: - openstack/networking/v2/ports - openstack/utils - pagination -- name: github.com/gregjones/httpcache - version: 787624de3eb7bd915c329cba748687a3b22666a6 - subpackages: - - diskcache - name: github.com/guelfey/go.dbus version: f6a3a2366cc39b8479cadc499d3c735fb10fbdda - name: github.com/hashicorp/golang-lru @@ -206,27 +189,19 @@ imports: - name: github.com/jmespath/go-jmespath version: 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74 - name: github.com/json-iterator/go - version: 36b14963da70d11297d313183d7e6388c8510e1e -- name: github.com/juju/ratelimit - version: 5b9ff866471762aa2ab2dced63c9fb6f53921342 + version: 13f86432b882000a51c6e610c620974462691a97 - name: github.com/kr/fs version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b - name: github.com/lpabon/godbc version: 9577782540c1398b710ddae1b86268ba03a19b0c - name: github.com/magiconair/properties version: 61b492c03cf472e0c6419be5899b8e0dc28b1b88 -- name: github.com/mailru/easyjson - version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d - subpackages: - - buffer - - jlexer - - jwriter - name: github.com/matttproud/golang_protobuf_extensions version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a subpackages: - pbutil - name: github.com/miekg/dns - version: 5364553f1ee9cddc7ac8b62dce148309c386695b + version: 906238edc6eb0ddface4a1923f6d41ef2a5ca59b - name: github.com/mitchellh/mapstructure version: db1efb556f84b25a0a13a04aad883943538ad2e0 - name: github.com/onsi/ginkgo @@ -271,14 +246,12 @@ imports: version: df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d - name: github.com/pelletier/go-toml version: 0049ab3dc4c4c70a9eee23087437b69c0dde2130 -- name: github.com/peterbourgon/diskv - version: 5f041e8faa004a95c88a202771f4cc3e991971e6 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/pkg/sftp version: 4d0e916071f68db74f8a73926335f809396d6b42 - name: github.com/powerman/rpc-codec - version: d10c0e9cfeac32cd94ee57c8eb8728abd6594618 + version: 3e1ab3b635b7b0d5f771028cd45aa9a827fd9f31 subpackages: - jsonrpc2 - name: github.com/prometheus/client_golang @@ -300,12 +273,8 @@ imports: version: 65c1f6f8f0fc1e2185eb9863a3bc751496404259 subpackages: - xfs -- name: github.com/PuerkitoBio/purell - version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 -- name: github.com/PuerkitoBio/urlesc - version: 5bd2802263f21d8788851d5305584c82a5c75d7e - name: github.com/Sirupsen/logrus - version: 26709e2714106fb8ad40b773b711ebce25b78914 + version: f4ee69125072b22721efbe639bd0da9c9d19b8cc - name: github.com/spf13/afero version: b28a7effac979219c2a2ed6205a4d70e4b1bcd02 subpackages: @@ -360,19 +329,16 @@ imports: - name: golang.org/x/text version: b19bf474d317b857955b12035d2c5acb57ce8b01 subpackages: - - cases - - internal - - internal/tag - - language - - runes - secure/bidirule - - secure/precis - transform - unicode/bidi - unicode/norm - - width +- name: golang.org/x/time + version: f51c12702a4d776e4c1fa9b0fabab841babae631 + subpackages: + - rate - name: google.golang.org/api - version: 654f863362977d69086620b5f72f13e911da2410 + version: c0dae069ee96c9261a04c81efd9e0f1e55f565ac subpackages: - cloudmonitoring/v2beta2 - compute/v0.alpha @@ -386,7 +352,7 @@ imports: - monitoring/v3 - pubsub/v1 - name: google.golang.org/appengine - version: 4f7eeb5305a4ba1966344836ba4af9996b7b4e05 + version: 5bee14b453b4c71be47ec1781b0fa61c2ea182db subpackages: - internal - internal/app_identity @@ -405,12 +371,18 @@ imports: - types - name: gopkg.in/inf.v0 version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 +- name: gopkg.in/square/go-jose.v2 + version: f8f38de21b4dcd69d0413faf231983f5fd6634b1 + subpackages: + - cipher + - json + - jwt - name: gopkg.in/warnings.v0 version: 8a331561fe74dadba6edfc59f3be66c22c3b065d - name: gopkg.in/yaml.v2 - version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 + version: 670d4cfef0544295bc27a114dbac37980d83185a - name: k8s.io/api - version: 006a217681ae70cbacdd66a5e2fca1a61a8ff28e + version: 7aac3e00a1b32fa476b83078cebaaca606b2fb48 subpackages: - admissionregistration/v1alpha1 - admissionregistration/v1beta1 @@ -441,7 +413,7 @@ imports: - storage/v1alpha1 - storage/v1beta1 - name: k8s.io/apiextensions-apiserver - version: 6f29dd12234812844d29f52bd520bb01374619ce + version: 10b55e130fc1162aba4f16406798909e48397aee subpackages: - pkg/apis/apiextensions - pkg/apis/apiextensions/v1beta1 @@ -450,7 +422,7 @@ imports: - pkg/client/clientset/clientset/typed/apiextensions/v1beta1 - pkg/features - name: k8s.io/apimachinery - version: 68f9c3a1feb3140df59c67ced62d3a5df8e6c9c2 + version: 302974c03f7e50f16561ba237db776ab93594ef6 subpackages: - pkg/api/equality - pkg/api/errors @@ -464,7 +436,7 @@ imports: - pkg/apis/meta/v1 - pkg/apis/meta/v1/unstructured - pkg/apis/meta/v1/validation - - pkg/apis/meta/v1alpha1 + - pkg/apis/meta/v1beta1 - pkg/conversion - pkg/conversion/queryparams - pkg/fields @@ -505,7 +477,7 @@ imports: - third_party/forked/golang/netutil - third_party/forked/golang/reflect - name: k8s.io/apiserver - version: 2a1092aaa7202e8f9b188281ff9424a014ce61c2 + version: 26061451f517f2db9b642596067283d0c3e74dbb subpackages: - pkg/authentication/authenticator - pkg/authentication/serviceaccount @@ -513,7 +485,7 @@ imports: - pkg/features - pkg/util/feature - name: k8s.io/client-go - version: 9389c055a838d4f208b699b3c7c51b70f2368861 + version: 82eadfdc39007c2eb47e3ddeb7ed7d96365e409d subpackages: - discovery - discovery/fake @@ -670,12 +642,11 @@ imports: - util/retry - util/testing - name: k8s.io/kube-openapi - version: 39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1 + version: 50ae88d24ede7b8bad68e23c805b5d3da5c8abaf subpackages: - - pkg/common - pkg/util/proto - name: k8s.io/kubernetes - version: 5fa2db2bd46ac79e5e00a4e6ed24191080aa463b + version: 48b7bb56341914b85c76700becadc02b8009d9a0 subpackages: - pkg/api/legacyscheme - pkg/api/service @@ -700,6 +671,7 @@ imports: - pkg/fieldpath - pkg/kubelet/apis - pkg/kubelet/types + - pkg/master/ports - pkg/security/apparmor - pkg/serviceaccount - pkg/util/file @@ -734,3 +706,4 @@ testImports: subpackages: - assert - mock + - require diff --git a/vendor/github.com/kubernetes-incubator/external-storage/glide.yaml b/vendor/github.com/kubernetes-incubator/external-storage/glide.yaml index e0b265331d..a984f76ddc 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/glide.yaml +++ b/vendor/github.com/kubernetes-incubator/external-storage/glide.yaml @@ -17,17 +17,17 @@ import: - package: gopkg.in/gcfg.v1 version: v1.2.1 - package: k8s.io/apiserver - version: kubernetes-1.9.2 + version: kubernetes-1.10.0-beta.1 - package: k8s.io/apiextensions-apiserver - version: kubernetes-1.9.2 + version: kubernetes-1.10.0-beta.1 - package: k8s.io/apimachinery - version: kubernetes-1.9.2 + version: kubernetes-1.10.0-beta.1 - package: k8s.io/client-go - version: kubernetes-1.9.2 + version: kubernetes-1.10.0-beta.1 - package: k8s.io/api - version: kubernetes-1.9.2 + version: kubernetes-1.10.0-beta.1 - package: k8s.io/kubernetes - version: v1.9.2 + version: v1.10.0-beta.0 - package: github.com/heketi/heketi version: 300752517908f3456e90d1ee2a773e7dd8ce1afe subpackages: diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/README.md b/vendor/github.com/kubernetes-incubator/external-storage/gluster/README.md new file mode 100644 index 0000000000..a5fca0a9ed --- /dev/null +++ b/vendor/github.com/kubernetes-incubator/external-storage/gluster/README.md @@ -0,0 +1,2 @@ +This directory hosts external kubernetes provisioners for gluster file and block. Please refer file provisioner readme +[readme](https://github.com/kubernetes-incubator/external-storage/blob/master/gluster/file/README.md) and block provisioner [readme](https://github.com/kubernetes-incubator/external-storage/blob/master/gluster/block/README.md) for more details. diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner-pod.yaml b/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner-pod.yaml new file mode 100644 index 0000000000..ea5968a6e4 --- /dev/null +++ b/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: glusterblock-provisioner +spec: + containers: + env: + name: PROVISIONER_NAME + value: gluster.org/glusterblock + image: "quay.io/external_storage/glusterblock-provisioner:latest" + name: glusterblock-provisioner diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner.pod b/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner.pod deleted file mode 100644 index 1987399672..0000000000 --- a/vendor/github.com/kubernetes-incubator/external-storage/gluster/block/deploy/glusterblk-provisioner.pod +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: glusterblock-provisioner -spec: - containers: - - - env: - - - name: PROVISIONER_NAME - value: gluster.org/glusterblock - image: "quay.io/external_storage/glusterblock-provisioner:latest" - name: glusterblock-provisioner diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/cmd/glusterfile-provisioner/glusterfile-provisioner.go b/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/cmd/glusterfile-provisioner/glusterfile-provisioner.go index 6f433ab6ec..9dfca7d1e3 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/cmd/glusterfile-provisioner/glusterfile-provisioner.go +++ b/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/cmd/glusterfile-provisioner/glusterfile-provisioner.go @@ -284,7 +284,6 @@ func (p *glusterfileProvisioner) ExpandVolumeDevice(spec *volume.Spec, newSize r expansionSizeGiB := int(util.RoundUpToGiB(expansionSize)) // Find out requested Size - //requestGiB := util.RoundUpToGiB(newSize) requestGiB := int(util.RoundUpToGiB(newSize.Value())) //Check the existing volume size @@ -509,6 +508,7 @@ func (p *glusterfileProvisioner) Delete(volume *v1.PersistentVolume) error { return nil } + func (p *glusterfileProvisioner) deleteEndpointService(namespace string, epServiceName string) (err error) { kubeClient := p.client if kubeClient == nil { @@ -730,16 +730,16 @@ func main() { glog.Fatalf("Failed to create config: %v", err) } - prName := provisionerName - provName := os.Getenv(provisionerNameKey) + provName := provisionerName + provEnvName := os.Getenv(provisionerNameKey) // Precedence is given for ProvisionerNameKey - if provName != "" && *id != "" { - prName = provName + if provEnvName != "" && *id != "" { + provName = provEnvName } - if provName == "" && *id != "" { - prName = *id + if provEnvName == "" && *id != "" { + provName = *id } clientset, err := kubernetes.NewForConfig(config) @@ -756,14 +756,14 @@ func main() { // Create the provisioner: it implements the Provisioner interface expected by // the controller - glusterfileProvisioner := NewglusterfileProvisioner(clientset, prName) + glusterfileProvisioner := NewglusterfileProvisioner(clientset, provName) // Start the provision controller which will dynamically provision glusterfs // PVs pc := controller.NewProvisionController( clientset, - prName, + provName, glusterfileProvisioner, serverVersion.GitVersion, ) diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfile-provisioner-pod.yaml b/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfile-provisioner-pod.yaml new file mode 100644 index 0000000000..05a62b6649 --- /dev/null +++ b/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfile-provisioner-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: glusterfile-provisioner +spec: + containers: + env: + name: PROVISIONER_NAME + value: gluster.org/glusterfile + image: "quay.io/external_storage/glusterfile-provisioner:latest" + name: glusterfile-provisioner diff --git a/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfs-provisioner.pod b/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfs-provisioner.pod deleted file mode 100644 index c25f658ad7..0000000000 --- a/vendor/github.com/kubernetes-incubator/external-storage/gluster/file/deploy/glusterfs-provisioner.pod +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: glusterfile-provisioner -spec: - containers: - - - env: - - - name: PROVISIONER_NAME - value: gluster.org/glusterfile - image: "quay.io/external_storage/glusterfile-provisioner:latest" - name: glusterfile-provisioner diff --git a/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrole.yaml b/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrole.yaml index 882eed826b..4aec8b6a88 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrole.yaml +++ b/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrole.yaml @@ -1,5 +1,5 @@ kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1alpha1 +apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-provisioner-runner rules: diff --git a/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrolebinding.yaml b/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrolebinding.yaml index 8ece544c2c..3e4d68572c 100644 --- a/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrolebinding.yaml +++ b/vendor/github.com/kubernetes-incubator/external-storage/nfs/deploy/kubernetes/auth/clusterrolebinding.yaml @@ -1,5 +1,5 @@ kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1alpha1 +apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-provisioner subjects: diff --git a/vendor/github.com/modern-go/concurrent/README.md b/vendor/github.com/modern-go/concurrent/README.md index b4381f1c4d..acab3200aa 100644 --- a/vendor/github.com/modern-go/concurrent/README.md +++ b/vendor/github.com/modern-go/concurrent/README.md @@ -8,4 +8,42 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE) * concurrent.Map: backport sync.Map for go below 1.9 -* concurrent.Executor: goroutine with explicit ownership and cancellable \ No newline at end of file +* concurrent.Executor: goroutine with explicit ownership and cancellable + +# concurrent.Map + +because sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable + +```go +m := concurrent.NewMap() +m.Store("hello", "world") +elem, found := m.Load("hello") +// elem will be "world" +// found will be true +``` + +# concurrent.Executor + +```go +executor := concurrent.NewUnboundedExecutor() +executor.Go(func(ctx context.Context) { + everyMillisecond := time.NewTicker(time.Millisecond) + for { + select { + case <-ctx.Done(): + fmt.Println("goroutine exited") + return + case <-everyMillisecond.C: + // do something + } + } +}) +time.Sleep(time.Second) +executor.StopAndWaitForever() +fmt.Println("executor stopped") +``` + +attach goroutine to executor instance, so that we can + +* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever +* handle panic by callback: the default behavior will no longer crash your application \ No newline at end of file diff --git a/vendor/github.com/modern-go/concurrent/unbounded_executor.go b/vendor/github.com/modern-go/concurrent/unbounded_executor.go index 31f52a9eb9..05a77dceb1 100644 --- a/vendor/github.com/modern-go/concurrent/unbounded_executor.go +++ b/vendor/github.com/modern-go/concurrent/unbounded_executor.go @@ -16,9 +16,6 @@ var HandlePanic = func(recovered interface{}, funcName string) { ErrorLogger.Println(string(debug.Stack())) } -// StopSignal will not be recovered, will propagate to upper level goroutine -const StopSignal = "STOP!" - // UnboundedExecutor is a executor without limits on counts of alive goroutines // it tracks the goroutine started by it, and can cancel them when shutdown type UnboundedExecutor struct { @@ -62,7 +59,9 @@ func (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) { go func() { defer func() { recovered := recover() - if recovered != nil && recovered != StopSignal { + // if you want to quit a goroutine without trigger HandlePanic + // use runtime.Goexit() to quit + if recovered != nil { if executor.HandlePanic == nil { HandlePanic(recovered, funcName) } else { @@ -70,8 +69,8 @@ func (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) { } } executor.activeGoroutinesMutex.Lock() - defer executor.activeGoroutinesMutex.Unlock() executor.activeGoroutines[startFrom] -= 1 + executor.activeGoroutinesMutex.Unlock() }() handler(executor.ctx) }() @@ -93,24 +92,24 @@ func (executor *UnboundedExecutor) StopAndWaitForever() { func (executor *UnboundedExecutor) StopAndWait(ctx context.Context) { executor.cancel() for { - fiveSeconds := time.NewTimer(time.Millisecond * 100) + oneHundredMilliseconds := time.NewTimer(time.Millisecond * 100) select { - case <-fiveSeconds.C: + case <-oneHundredMilliseconds.C: + if executor.checkNoActiveGoroutines() { + return + } case <-ctx.Done(): return } - if executor.checkGoroutines() { - return - } } } -func (executor *UnboundedExecutor) checkGoroutines() bool { +func (executor *UnboundedExecutor) checkNoActiveGoroutines() bool { executor.activeGoroutinesMutex.Lock() defer executor.activeGoroutinesMutex.Unlock() for startFrom, count := range executor.activeGoroutines { if count > 0 { - InfoLogger.Println("event!unbounded_executor.still waiting goroutines to quit", + InfoLogger.Println("UnboundedExecutor is still waiting goroutines to quit", "startFrom", startFrom, "count", count) return false diff --git a/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go b/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go index dbd89904ff..fe86e84a39 100644 --- a/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go +++ b/vendor/github.com/modern-go/concurrent/unbounded_executor_test.go @@ -32,10 +32,10 @@ func ExampleUnboundedExecutor_StopAndWaitForever() { }) time.Sleep(time.Second) executor.StopAndWaitForever() - fmt.Println("exectuor stopped") + fmt.Println("executor stopped") // output: // goroutine exited - // exectuor stopped + // executor stopped } func ExampleUnboundedExecutor_Go_panic() { diff --git a/vendor/golang.org/x/crypto/acme/autocert/renewal.go b/vendor/golang.org/x/crypto/acme/autocert/renewal.go index 6c5da2bc8c..2a3a0a7061 100644 --- a/vendor/golang.org/x/crypto/acme/autocert/renewal.go +++ b/vendor/golang.org/x/crypto/acme/autocert/renewal.go @@ -102,7 +102,9 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) { if err != nil { return 0, err } - dr.m.cachePut(ctx, dr.domain, tlscert) + if err := dr.m.cachePut(ctx, dr.domain, tlscert); err != nil { + return 0, err + } dr.m.stateMu.Lock() defer dr.m.stateMu.Unlock() // m.state is guaranteed to be non-nil at this point diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go index 798f5cbdad..b423feaea9 100644 --- a/vendor/golang.org/x/crypto/argon2/argon2.go +++ b/vendor/golang.org/x/crypto/argon2/argon2.go @@ -54,11 +54,12 @@ const ( // Key derives a key from the password, salt, and cost parameters using Argon2i // returning a byte slice of length keyLen that can be used as cryptographic -// key. The CPU cost and parallism degree must be greater than zero. +// key. The CPU cost and parallelism degree must be greater than zero. // // For example, you can get a derived key for e.g. AES-256 (which needs a -// 32-byte key) by doing: `key := argon2.Key([]byte("some password"), salt, 3, -// 32*1024, 4, 32)` +// 32-byte key) by doing: +// +// key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32) // // The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number. // If using that amount of memory (32 MB) is not possible in some contexts then @@ -76,12 +77,13 @@ func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint3 // IDKey derives a key from the password, salt, and cost parameters using // Argon2id returning a byte slice of length keyLen that can be used as -// cryptographic key. The CPU cost and parallism degree must be greater than +// cryptographic key. The CPU cost and parallelism degree must be greater than // zero. // // For example, you can get a derived key for e.g. AES-256 (which needs a -// 32-byte key) by doing: `key := argon2.IDKey([]byte("some password"), salt, 1, -// 64*1024, 4, 32)` +// 32-byte key) by doing: +// +// key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32) // // The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number. // If using that amount of memory (64 MB) is not possible in some contexts then diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go index 5df1b2593d..a1fbffdd5f 100644 --- a/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go +++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go @@ -50,15 +50,23 @@ func TestVectors(t *testing.T) { } } -func TestMillionA(t *testing.T) { +func millionA() string { md := New() for i := 0; i < 100000; i++ { io.WriteString(md, "aaaaaaaaaa") } - out := "52783243c1697bdbe16d37f97f68f08325dc1528" - s := fmt.Sprintf("%x", md.Sum(nil)) - if s != out { + return fmt.Sprintf("%x", md.Sum(nil)) +} + +func TestMillionA(t *testing.T) { + const out = "52783243c1697bdbe16d37f97f68f08325dc1528" + if s := millionA(); s != out { t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out) } - md.Reset() +} + +func BenchmarkMillionA(b *testing.B) { + for i := 0; i < b.N; i++ { + millionA() + } } diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go index 7bc8e6c485..e0edc02f0f 100644 --- a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go +++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go @@ -8,6 +8,10 @@ package ripemd160 +import ( + "math/bits" +) + // work buffer indices and roll amounts for one line var _n = [80]uint{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -59,16 +63,16 @@ func _Block(md *digest, p []byte) int { i := 0 for i < 16 { alpha = a + (b ^ c ^ d) + x[_n[i]] - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 + s := int(_r[i]) + alpha = bits.RotateLeft32(alpha, s) + e + beta = bits.RotateLeft32(c, 10) a, b, c, d, e = e, alpha, b, beta, d // parallel line alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 + s = int(r_[i]) + alpha = bits.RotateLeft32(alpha, s) + ee + beta = bits.RotateLeft32(cc, 10) aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd i++ @@ -77,16 +81,16 @@ func _Block(md *digest, p []byte) int { // round 2 for i < 32 { alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999 - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 + s := int(_r[i]) + alpha = bits.RotateLeft32(alpha, s) + e + beta = bits.RotateLeft32(c, 10) a, b, c, d, e = e, alpha, b, beta, d // parallel line alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 + s = int(r_[i]) + alpha = bits.RotateLeft32(alpha, s) + ee + beta = bits.RotateLeft32(cc, 10) aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd i++ @@ -95,16 +99,16 @@ func _Block(md *digest, p []byte) int { // round 3 for i < 48 { alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1 - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 + s := int(_r[i]) + alpha = bits.RotateLeft32(alpha, s) + e + beta = bits.RotateLeft32(c, 10) a, b, c, d, e = e, alpha, b, beta, d // parallel line alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 + s = int(r_[i]) + alpha = bits.RotateLeft32(alpha, s) + ee + beta = bits.RotateLeft32(cc, 10) aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd i++ @@ -113,16 +117,16 @@ func _Block(md *digest, p []byte) int { // round 4 for i < 64 { alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 + s := int(_r[i]) + alpha = bits.RotateLeft32(alpha, s) + e + beta = bits.RotateLeft32(c, 10) a, b, c, d, e = e, alpha, b, beta, d // parallel line alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 + s = int(r_[i]) + alpha = bits.RotateLeft32(alpha, s) + ee + beta = bits.RotateLeft32(cc, 10) aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd i++ @@ -131,16 +135,16 @@ func _Block(md *digest, p []byte) int { // round 5 for i < 80 { alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 + s := int(_r[i]) + alpha = bits.RotateLeft32(alpha, s) + e + beta = bits.RotateLeft32(c, 10) a, b, c, d, e = e, alpha, b, beta, d // parallel line alpha = aa + (bb ^ cc ^ dd) + x[n_[i]] - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 + s = int(r_[i]) + alpha = bits.RotateLeft32(alpha, s) + ee + beta = bits.RotateLeft32(cc, 10) aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd i++ diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go index 841f9860f0..5a027d2da3 100644 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -40,7 +40,7 @@ func (d *state) Clone() ShakeHash { // least 32 bytes of its output are used. func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} } -// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash. +// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} } diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go index 02dad484e5..731c89a284 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go @@ -108,9 +108,7 @@ func ReadPassword(fd int) ([]byte, error) { return nil, err } - defer func() { - unix.IoctlSetTermios(fd, ioctlWriteTermios, termios) - }() + defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios) return readPasswordLine(passwordReader(fd)) } diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go index a2e1b57dc1..9e41b9f43f 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go @@ -14,7 +14,7 @@ import ( // State contains the state of a terminal. type State struct { - state *unix.Termios + termios unix.Termios } // IsTerminal returns true if the given file descriptor is a terminal. @@ -75,47 +75,43 @@ func ReadPassword(fd int) ([]byte, error) { // restored. // see http://cr.illumos.org/~webrev/andy_js/1060/ func MakeRaw(fd int) (*State, error) { - oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS) + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) if err != nil { return nil, err } - oldTermios := *oldTermiosPtr - - newTermios := oldTermios - newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON - newTermios.Oflag &^= syscall.OPOST - newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN - newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB - newTermios.Cflag |= syscall.CS8 - newTermios.Cc[unix.VMIN] = 1 - newTermios.Cc[unix.VTIME] = 0 - - if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil { + + oldState := State{termios: *termios} + + termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON + termios.Oflag &^= unix.OPOST + termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN + termios.Cflag &^= unix.CSIZE | unix.PARENB + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + + if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil { return nil, err } - return &State{ - state: oldTermiosPtr, - }, nil + return &oldState, nil } // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, oldState *State) error { - return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state) + return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios) } // GetState returns the current state of a terminal which may be useful to // restore the terminal after a signal. func GetState(fd int) (*State, error) { - oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS) + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) if err != nil { return nil, err } - return &State{ - state: oldTermiosPtr, - }, nil + return &State{termios: *termios}, nil } // GetSize returns the dimensions of the given terminal. diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go index 4933ac3611..8618955df7 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -89,9 +89,7 @@ func ReadPassword(fd int) ([]byte, error) { return nil, err } - defer func() { - windows.SetConsoleMode(windows.Handle(fd), old) - }() + defer windows.SetConsoleMode(windows.Handle(fd), old) var h windows.Handle p, _ := windows.GetCurrentProcess() diff --git a/vendor/golang.org/x/net/dns/dnsmessage/example_test.go b/vendor/golang.org/x/net/dns/dnsmessage/example_test.go index 5415c2d3ac..8600a6bc4a 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/example_test.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/example_test.go @@ -37,20 +37,20 @@ func ExampleParser() { }, Answers: []dnsmessage.Resource{ { - dnsmessage.ResourceHeader{ + Header: dnsmessage.ResourceHeader{ Name: mustNewName("foo.bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, - &dnsmessage.AResource{[4]byte{127, 0, 0, 1}}, + Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}}, }, { - dnsmessage.ResourceHeader{ + Header: dnsmessage.ResourceHeader{ Name: mustNewName("bar.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, }, - &dnsmessage.AResource{[4]byte{127, 0, 0, 2}}, + Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}}, }, }, } diff --git a/vendor/golang.org/x/net/http2/h2demo/service.yaml b/vendor/golang.org/x/net/http2/h2demo/service.yaml index 8e7671e4a6..2b7d54119a 100644 --- a/vendor/golang.org/x/net/http2/h2demo/service.yaml +++ b/vendor/golang.org/x/net/http2/h2demo/service.yaml @@ -3,6 +3,7 @@ kind: Service metadata: name: h2demo spec: + externalTrafficPolicy: Local ports: - port: 80 targetPort: 80 diff --git a/vendor/golang.org/x/net/route/syscall.go b/vendor/golang.org/x/net/route/syscall.go index c211188b10..5f69ea63d9 100644 --- a/vendor/golang.org/x/net/route/syscall.go +++ b/vendor/golang.org/x/net/route/syscall.go @@ -20,7 +20,7 @@ func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) } else { p = unsafe.Pointer(&zero) } - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), newlen) if errno != 0 { return error(errno) } diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index bb72a527e8..a46ee0eaa3 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -368,7 +368,11 @@ func New(family, title string) Trace { } func (tr *trace) Finish() { - tr.Elapsed = time.Now().Sub(tr.Start) + elapsed := time.Now().Sub(tr.Start) + tr.mu.Lock() + tr.Elapsed = elapsed + tr.mu.Unlock() + if DebugUseAfterFinish { buf := make([]byte, 4<<10) // 4 KB should be enough n := runtime.Stack(buf, false) @@ -381,14 +385,17 @@ func (tr *trace) Finish() { m.Remove(tr) f := getFamily(tr.Family, true) + tr.mu.RLock() // protects tr fields in Cond.match calls for _, b := range f.Buckets { if b.Cond.match(tr) { b.Add(tr) } } + tr.mu.RUnlock() + // Add a sample of elapsed time as microseconds to the family's timeseries h := new(histogram) - h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3) + h.addMeasurement(elapsed.Nanoseconds() / 1e3) f.LatencyMu.Lock() f.Latency.Add(h) f.LatencyMu.Unlock() @@ -684,25 +691,20 @@ type trace struct { // Title is the title of this trace. Title string - // Timing information. - Start time.Time - Elapsed time.Duration // zero while active - - // Trace information if non-zero. - traceID uint64 - spanID uint64 - - // Whether this trace resulted in an error. - IsError bool + // Start time of the this trace. + Start time.Time - // Append-only sequence of events (modulo discards). mu sync.RWMutex - events []event + events []event // Append-only sequence of events (modulo discards). maxEvents int + recycler func(interface{}) + IsError bool // Whether this trace resulted in an error. + Elapsed time.Duration // Elapsed time for this trace, zero while active. + traceID uint64 // Trace information if non-zero. + spanID uint64 - refs int32 // how many buckets this is in - recycler func(interface{}) - disc discarded // scratch space to avoid allocation + refs int32 // how many buckets this is in + disc discarded // scratch space to avoid allocation finishStack []byte // where finish was called, if DebugUseAfterFinish is set @@ -714,14 +716,18 @@ func (tr *trace) reset() { tr.Family = "" tr.Title = "" tr.Start = time.Time{} + + tr.mu.Lock() tr.Elapsed = 0 tr.traceID = 0 tr.spanID = 0 tr.IsError = false tr.maxEvents = 0 tr.events = nil - tr.refs = 0 tr.recycler = nil + tr.mu.Unlock() + + tr.refs = 0 tr.disc = 0 tr.finishStack = nil for i := range tr.eventsBuf { @@ -801,21 +807,31 @@ func (tr *trace) LazyPrintf(format string, a ...interface{}) { tr.addEvent(&lazySprintf{format, a}, false, false) } -func (tr *trace) SetError() { tr.IsError = true } +func (tr *trace) SetError() { + tr.mu.Lock() + tr.IsError = true + tr.mu.Unlock() +} func (tr *trace) SetRecycler(f func(interface{})) { + tr.mu.Lock() tr.recycler = f + tr.mu.Unlock() } func (tr *trace) SetTraceInfo(traceID, spanID uint64) { + tr.mu.Lock() tr.traceID, tr.spanID = traceID, spanID + tr.mu.Unlock() } func (tr *trace) SetMaxEvents(m int) { + tr.mu.Lock() // Always keep at least three events: first, discarded count, last. if len(tr.events) == 0 && m > 3 { tr.maxEvents = m } + tr.mu.Unlock() } func (tr *trace) ref() { @@ -824,6 +840,7 @@ func (tr *trace) ref() { func (tr *trace) unref() { if atomic.AddInt32(&tr.refs, -1) == 0 { + tr.mu.RLock() if tr.recycler != nil { // freeTrace clears tr, so we hold tr.recycler and tr.events here. go func(f func(interface{}), es []event) { @@ -834,6 +851,7 @@ func (tr *trace) unref() { } }(tr.recycler, tr.events) } + tr.mu.RUnlock() freeTrace(tr) } @@ -844,7 +862,10 @@ func (tr *trace) When() string { } func (tr *trace) ElapsedTime() string { + tr.mu.RLock() t := tr.Elapsed + tr.mu.RUnlock() + if t == 0 { // Active trace. t = time.Since(tr.Start) diff --git a/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/vendor/golang.org/x/sys/plan9/syscall_plan9.go index d39d07de1e..84e1471481 100644 --- a/vendor/golang.org/x/sys/plan9/syscall_plan9.go +++ b/vendor/golang.org/x/sys/plan9/syscall_plan9.go @@ -12,6 +12,7 @@ package plan9 import ( + "bytes" "syscall" "unsafe" ) @@ -50,12 +51,11 @@ func atoi(b []byte) (n uint) { } func cstring(s []byte) string { - for i := range s { - if s[i] == 0 { - return string(s[0:i]) - } + i := bytes.IndexByte(s, 0) + if i == -1 { + i = len(s) } - return string(s) + return string(s[:i]) } func errstr() string { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go new file mode 100644 index 0000000000..df9c123718 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build gccgo +// +build 386 arm + +package unix + +import ( + "syscall" + "unsafe" +) + +func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) { + offsetLow := uint32(offset & 0xffffffff) + offsetHigh := uint32((offset >> 32) & 0xffffffff) + _, _, err = Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0) + return newoffset, err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_test.go b/vendor/golang.org/x/sys/unix/syscall_linux_test.go index 78d28792d7..ff7ad82b1a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_test.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_test.go @@ -292,6 +292,10 @@ func TestSchedSetaffinity(t *testing.T) { t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask) } + if runtime.NumCPU() < 2 { + t.Skip("skipping setaffinity tests on single CPU system") + } + err = unix.SchedSetaffinity(0, &newMask) if err != nil { t.Fatalf("SchedSetaffinity: %v", err) diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index cd8f3a9c28..80b05a4065 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -7,6 +7,7 @@ package unix import ( + "bytes" "runtime" "sync" "syscall" @@ -52,12 +53,11 @@ func errnoErr(e syscall.Errno) error { // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. func clen(n []byte) int { - for i := 0; i < len(n); i++ { - if n[i] == 0 { - return i - } + i := bytes.IndexByte(n, 0) + if i == -1 { + i = len(n) } - return len(n) + return i } // Mmap manager, for use by operating system-specific implementations. diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/context.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/context.pb.go index 84c11da5c8..63066cbbb8 100644 --- a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/context.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/context.pb.go @@ -528,51 +528,55 @@ var _Contexts_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("google/cloud/dialogflow/v2beta1/context.proto", fileDescriptor1) } var fileDescriptor1 = []byte{ - // 731 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x96, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0xc7, 0x35, 0xe9, 0xbd, 0x6d, 0x7a, 0xda, 0xdc, 0xab, 0x0e, 0x51, 0x89, 0xd2, 0xa2, 0x46, - 0x46, 0x40, 0x14, 0x09, 0x5b, 0x84, 0x6f, 0x2a, 0x2a, 0xb5, 0x09, 0xad, 0x2a, 0x81, 0xa8, 0x52, - 0x60, 0xc1, 0x26, 0x9a, 0x26, 0x27, 0x96, 0xa9, 0xe3, 0x31, 0x9e, 0x09, 0x94, 0xa2, 0x6e, 0x10, - 0x6f, 0xc0, 0x82, 0x1d, 0x0b, 0x16, 0x2c, 0xfa, 0x06, 0x88, 0x05, 0xe2, 0x19, 0x78, 0x05, 0x1e, - 0x82, 0x25, 0xf2, 0x78, 0x9c, 0x8f, 0x26, 0x25, 0x71, 0x77, 0xf1, 0xcc, 0x7f, 0xce, 0xf9, 0x9d, - 0x33, 0xff, 0x63, 0x07, 0xae, 0xda, 0x9c, 0xdb, 0x2e, 0x5a, 0x0d, 0x97, 0x77, 0x9a, 0x56, 0xd3, - 0x61, 0x2e, 0xb7, 0x5b, 0x2e, 0x7f, 0x6d, 0xbd, 0x2a, 0xef, 0xa1, 0x64, 0xd7, 0xac, 0x06, 0xf7, - 0x24, 0x1e, 0x48, 0xd3, 0x0f, 0xb8, 0xe4, 0x74, 0x25, 0x92, 0x9b, 0x4a, 0x6e, 0xf6, 0xe4, 0xa6, - 0x96, 0xe7, 0x97, 0x75, 0x3c, 0xe6, 0x3b, 0x16, 0xf3, 0x3c, 0x2e, 0x99, 0x74, 0xb8, 0x27, 0xa2, - 0xe3, 0xf9, 0x25, 0xbd, 0xab, 0x9e, 0xf6, 0x3a, 0x2d, 0x0b, 0xdb, 0xbe, 0x7c, 0xa3, 0x37, 0x0b, - 0x27, 0x37, 0x5b, 0x0e, 0xba, 0xcd, 0x7a, 0x9b, 0x89, 0x7d, 0xad, 0x58, 0x3e, 0xa9, 0x10, 0x32, - 0xe8, 0x34, 0x34, 0x9b, 0x71, 0x04, 0x33, 0x95, 0x08, 0x96, 0x52, 0xf8, 0xc7, 0x63, 0x6d, 0xcc, - 0x91, 0x02, 0x29, 0xce, 0xd6, 0xd4, 0x6f, 0x7a, 0x09, 0xfe, 0x73, 0x9d, 0x16, 0x0a, 0x9f, 0x79, - 0xf5, 0x06, 0xef, 0x78, 0x32, 0x97, 0x2a, 0x90, 0xe2, 0xbf, 0xb5, 0x4c, 0xbc, 0x5a, 0x09, 0x17, - 0xe9, 0x6d, 0x00, 0x9f, 0x05, 0xac, 0x8d, 0x12, 0x03, 0x91, 0x9b, 0x2a, 0x90, 0xe2, 0x5c, 0xf9, - 0xbc, 0xa9, 0xcb, 0x8e, 0x13, 0x9b, 0xbb, 0x2a, 0x71, 0xad, 0x4f, 0x6a, 0x38, 0x70, 0xee, 0xa1, - 0x23, 0xa4, 0x46, 0x10, 0x35, 0x7c, 0xd9, 0x41, 0x21, 0xe9, 0x22, 0x4c, 0xfb, 0x2c, 0x40, 0x4f, - 0x6a, 0x18, 0xfd, 0x44, 0x97, 0x60, 0xd6, 0x67, 0x36, 0xd6, 0x85, 0x73, 0x88, 0x9a, 0x24, 0x1d, - 0x2e, 0xec, 0x3a, 0x87, 0x48, 0x2f, 0x84, 0x10, 0x36, 0xd6, 0x25, 0xdf, 0x47, 0x4f, 0x41, 0xcc, - 0xd6, 0x94, 0xfc, 0x49, 0xb8, 0x60, 0xbc, 0x27, 0x90, 0x1d, 0xcc, 0x25, 0x7c, 0xee, 0x09, 0xa4, - 0x55, 0x48, 0xeb, 0xfb, 0x12, 0x39, 0x52, 0x98, 0x2a, 0xce, 0x95, 0x8b, 0xe6, 0x98, 0x1b, 0x33, - 0x75, 0x90, 0x5a, 0xf7, 0x24, 0xbd, 0x0c, 0xff, 0x7b, 0x78, 0x20, 0xeb, 0x7d, 0x08, 0x29, 0x85, - 0x90, 0x09, 0x97, 0x77, 0xba, 0x18, 0x57, 0x60, 0x61, 0x0b, 0x63, 0x88, 0xb8, 0xde, 0x11, 0xad, - 0x37, 0x02, 0xc8, 0x56, 0x02, 0x64, 0x12, 0x4f, 0x68, 0x4f, 0xeb, 0xcd, 0x06, 0xcc, 0x68, 0x18, - 0x95, 0x38, 0x49, 0x15, 0xf1, 0x41, 0xe3, 0x23, 0x81, 0xec, 0x53, 0xbf, 0x39, 0x9c, 0xb4, 0x2f, - 0x38, 0x39, 0x63, 0x70, 0xba, 0x0a, 0x73, 0x1d, 0x15, 0x5b, 0xb9, 0x53, 0x43, 0xe6, 0x87, 0x5c, - 0xb2, 0x19, 0x1a, 0xf8, 0x11, 0x13, 0xfb, 0x35, 0x88, 0xe4, 0xe1, 0x6f, 0xa3, 0x04, 0xd9, 0x2a, - 0xba, 0x38, 0x04, 0x36, 0xaa, 0x73, 0x65, 0xc8, 0x45, 0xda, 0x75, 0xd7, 0x9d, 0xd0, 0x59, 0xe5, - 0xef, 0x69, 0x48, 0xc7, 0x5a, 0xfa, 0x8d, 0xc0, 0x7c, 0xbf, 0x55, 0xe8, 0x8d, 0xb1, 0xd5, 0x8e, - 0x70, 0x71, 0xfe, 0x66, 0xc2, 0x53, 0x91, 0x1f, 0x8d, 0xb5, 0x77, 0x3f, 0x7f, 0x7d, 0x48, 0xdd, - 0xa1, 0xb7, 0xba, 0xaf, 0x93, 0xb7, 0x11, 0xe4, 0x7d, 0x3f, 0xe0, 0x2f, 0xb0, 0x21, 0x85, 0x55, - 0xb2, 0x98, 0x8d, 0x9e, 0xb4, 0x04, 0x0a, 0x11, 0xbe, 0x29, 0xac, 0xd2, 0x91, 0xd5, 0x75, 0xe2, - 0x31, 0x01, 0xe8, 0x59, 0x8c, 0x96, 0xc7, 0x52, 0x0c, 0xf9, 0x31, 0x3f, 0xf1, 0xed, 0x8e, 0x82, - 0x0d, 0xef, 0xe0, 0x6f, 0xa8, 0x5d, 0x52, 0xab, 0x74, 0x44, 0xbf, 0x12, 0xc8, 0x0c, 0xd8, 0x9c, - 0x8e, 0xef, 0xda, 0xa8, 0xb1, 0x48, 0x80, 0xbc, 0xa5, 0x90, 0xd7, 0x8d, 0x33, 0xf6, 0xf7, 0x5e, - 0xd7, 0xd0, 0x3f, 0x08, 0x64, 0x06, 0xa6, 0x65, 0x02, 0xf6, 0x51, 0xd3, 0x95, 0x80, 0xfd, 0xb1, - 0x62, 0xdf, 0x2e, 0xaf, 0xf5, 0xd8, 0xe3, 0x6f, 0x4d, 0x92, 0xb6, 0xf7, 0x6a, 0xf8, 0x44, 0x20, - 0x33, 0x30, 0x58, 0x13, 0xd4, 0x30, 0x6a, 0x10, 0xf3, 0x8b, 0x43, 0x83, 0xfc, 0x20, 0xfc, 0x4c, - 0xc5, 0x06, 0x29, 0x9d, 0xd5, 0x20, 0x5f, 0x08, 0x2c, 0x0c, 0x4d, 0x33, 0xbd, 0x3b, 0x21, 0xe4, - 0xf0, 0x1b, 0x20, 0x09, 0x68, 0x12, 0x5b, 0x6c, 0x1c, 0x13, 0xb8, 0xd8, 0xe0, 0xed, 0x71, 0x60, - 0x1b, 0xf3, 0x1a, 0x68, 0x27, 0x4c, 0xbf, 0x43, 0x9e, 0x6f, 0xeb, 0x03, 0x36, 0x77, 0x99, 0x67, - 0x9b, 0x3c, 0xb0, 0x2d, 0x1b, 0x3d, 0x05, 0x67, 0x45, 0x5b, 0xcc, 0x77, 0xc4, 0xa9, 0xff, 0x35, - 0x56, 0x7b, 0x4b, 0xbf, 0x09, 0xf9, 0x9c, 0x4a, 0x55, 0x37, 0x8f, 0x53, 0x2b, 0x5b, 0x51, 0xcc, - 0x8a, 0x82, 0xa8, 0xf6, 0x20, 0x9e, 0x45, 0x87, 0xf6, 0xa6, 0x55, 0xfc, 0xeb, 0x7f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0x69, 0x4e, 0x3f, 0xa2, 0xca, 0x08, 0x00, 0x00, + // 793 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcd, 0x6f, 0xd3, 0x48, + 0x14, 0xd7, 0xb8, 0xbb, 0xfd, 0x98, 0x34, 0xbb, 0xea, 0x6c, 0xd4, 0x8d, 0xd2, 0xae, 0x1a, 0x79, + 0xb5, 0x4b, 0x14, 0x09, 0x5b, 0x98, 0x2f, 0x41, 0x05, 0x52, 0x9b, 0xd0, 0xaa, 0x52, 0x91, 0xaa, + 0xb4, 0x70, 0xe8, 0x25, 0x9a, 0x26, 0x2f, 0x96, 0xa9, 0x33, 0x63, 0x3c, 0x13, 0x28, 0x45, 0x39, + 0xf0, 0x71, 0xe1, 0xc4, 0x01, 0x09, 0xc4, 0x09, 0x89, 0x03, 0x87, 0xfe, 0x3b, 0xfc, 0x0b, 0x3d, + 0x72, 0xe0, 0xc8, 0x0d, 0x64, 0x7b, 0x9c, 0x8f, 0xc6, 0x25, 0x49, 0xcb, 0xcd, 0x7e, 0xf3, 0x7b, + 0x6f, 0x7e, 0xbf, 0x37, 0xbf, 0x79, 0x36, 0xbe, 0x68, 0x73, 0x6e, 0xbb, 0x60, 0xd6, 0x5c, 0xde, + 0xaa, 0x9b, 0x75, 0x87, 0xba, 0xdc, 0x6e, 0xb8, 0xfc, 0xb1, 0xf9, 0xc8, 0xda, 0x03, 0x49, 0x2f, + 0x99, 0x35, 0xce, 0x24, 0x1c, 0x48, 0xc3, 0xf3, 0xb9, 0xe4, 0x64, 0x29, 0x82, 0x1b, 0x21, 0xdc, + 0xe8, 0xc2, 0x0d, 0x05, 0xcf, 0x2d, 0xaa, 0x7a, 0xd4, 0x73, 0x4c, 0xca, 0x18, 0x97, 0x54, 0x3a, + 0x9c, 0x89, 0x28, 0x3d, 0xb7, 0xa0, 0x56, 0xc3, 0xb7, 0xbd, 0x56, 0xc3, 0x84, 0xa6, 0x27, 0x9f, + 0xa8, 0xc5, 0xfc, 0xc9, 0xc5, 0x86, 0x03, 0x6e, 0xbd, 0xda, 0xa4, 0x62, 0x5f, 0x21, 0x16, 0x4f, + 0x22, 0x84, 0xf4, 0x5b, 0x35, 0xc5, 0x4d, 0x6f, 0xe3, 0xa9, 0x52, 0x44, 0x96, 0x10, 0xfc, 0x1b, + 0xa3, 0x4d, 0xc8, 0xa2, 0x3c, 0x2a, 0xcc, 0x54, 0xc2, 0x67, 0xf2, 0x1f, 0xfe, 0xc3, 0x75, 0x1a, + 0x20, 0x3c, 0xca, 0xaa, 0x35, 0xde, 0x62, 0x32, 0xab, 0xe5, 0x51, 0xe1, 0xf7, 0x4a, 0x3a, 0x8e, + 0x96, 0x82, 0x20, 0xb9, 0x8e, 0xb1, 0x47, 0x7d, 0xda, 0x04, 0x09, 0xbe, 0xc8, 0x4e, 0xe4, 0x51, + 0x21, 0x65, 0xfd, 0x6d, 0x28, 0xd9, 0xf1, 0xc6, 0xc6, 0x76, 0xb8, 0x71, 0xa5, 0x07, 0xaa, 0x3b, + 0xf8, 0xaf, 0x4d, 0x47, 0x48, 0x45, 0x41, 0x54, 0xe0, 0x61, 0x0b, 0x84, 0x24, 0xf3, 0x78, 0xd2, + 0xa3, 0x3e, 0x30, 0xa9, 0xc8, 0xa8, 0x37, 0xb2, 0x80, 0x67, 0x3c, 0x6a, 0x43, 0x55, 0x38, 0x87, + 0xa0, 0x98, 0x4c, 0x07, 0x81, 0x6d, 0xe7, 0x10, 0xc8, 0x3f, 0x01, 0x09, 0x1b, 0xaa, 0x92, 0xef, + 0x03, 0x0b, 0x49, 0xcc, 0x54, 0x42, 0xf8, 0x4e, 0x10, 0xd0, 0x5f, 0x22, 0x9c, 0xe9, 0xdf, 0x4b, + 0x78, 0x9c, 0x09, 0x20, 0x65, 0x3c, 0xad, 0xce, 0x4b, 0x64, 0x51, 0x7e, 0xa2, 0x90, 0xb2, 0x0a, + 0xc6, 0x90, 0x13, 0x33, 0x54, 0x91, 0x4a, 0x27, 0x93, 0xfc, 0x8f, 0xff, 0x64, 0x70, 0x20, 0xab, + 0x3d, 0x14, 0xb4, 0x90, 0x42, 0x3a, 0x08, 0x6f, 0x75, 0x68, 0x5c, 0xc0, 0x73, 0xeb, 0x10, 0x93, + 0x88, 0xf5, 0x26, 0xb4, 0x5e, 0xf7, 0x71, 0xa6, 0xe4, 0x03, 0x95, 0x70, 0x02, 0x7b, 0x5a, 0x6f, + 0x56, 0xf1, 0x94, 0x22, 0x13, 0x6e, 0x3c, 0x8e, 0x8a, 0x38, 0x51, 0x7f, 0x87, 0x70, 0xe6, 0x9e, + 0x57, 0x1f, 0xdc, 0xb4, 0xa7, 0x38, 0x3a, 0x63, 0x71, 0xb2, 0x8c, 0x53, 0xad, 0xb0, 0x76, 0xe8, + 0x4e, 0x45, 0x32, 0x37, 0xe0, 0x92, 0xb5, 0xc0, 0xc0, 0x77, 0xa9, 0xd8, 0xaf, 0xe0, 0x08, 0x1e, + 0x3c, 0xeb, 0x45, 0x9c, 0x29, 0x83, 0x0b, 0x03, 0xc4, 0x92, 0x3a, 0x67, 0xe1, 0x6c, 0x84, 0x5d, + 0x71, 0xdd, 0x11, 0x9d, 0x65, 0x7d, 0x4f, 0xe1, 0xe9, 0x18, 0x4b, 0x9e, 0x69, 0x78, 0xb6, 0xd7, + 0x2a, 0xe4, 0xca, 0x50, 0xb5, 0x09, 0x2e, 0xce, 0x5d, 0x1d, 0x33, 0x2b, 0xf2, 0xa3, 0xfe, 0x02, + 0x3d, 0xff, 0x7c, 0xfc, 0x46, 0x6b, 0x93, 0x6b, 0x9d, 0x79, 0xf2, 0x34, 0x62, 0x79, 0xcb, 0xf3, + 0xf9, 0x03, 0xa8, 0x49, 0x61, 0x16, 0x4d, 0x6a, 0x03, 0x93, 0xa6, 0x00, 0x21, 0x82, 0x51, 0x61, + 0x16, 0xdb, 0xf1, 0xd0, 0x11, 0xbb, 0x25, 0xb2, 0x32, 0x3c, 0xd3, 0x6f, 0x31, 0xe9, 0x34, 0x21, + 0x08, 0x24, 0x15, 0x21, 0x5f, 0x11, 0xc6, 0x5d, 0xa3, 0x12, 0x6b, 0xa8, 0x96, 0x01, 0x57, 0xe7, + 0x46, 0xf6, 0x48, 0xa2, 0xe4, 0xe0, 0x28, 0x7f, 0x26, 0xb8, 0x43, 0xd5, 0x2c, 0xb6, 0xfb, 0x25, + 0x27, 0x67, 0x26, 0x0a, 0xee, 0x2d, 0x42, 0x5e, 0x69, 0x38, 0xdd, 0x77, 0xe5, 0xc8, 0xf0, 0x13, + 0x4c, 0xba, 0xa2, 0x63, 0x08, 0x7f, 0x1b, 0x09, 0x7f, 0x8d, 0xf4, 0x33, 0x1e, 0xf6, 0xcd, 0xf8, + 0x7a, 0xed, 0x6e, 0xea, 0xe7, 0x3f, 0xf5, 0x4e, 0x35, 0xf2, 0x5e, 0xc3, 0xe9, 0xbe, 0x49, 0x30, + 0x42, 0x2f, 0x92, 0x26, 0xc7, 0x18, 0xbd, 0xf8, 0x14, 0xf5, 0xe2, 0x03, 0xb2, 0x6e, 0x77, 0x85, + 0xc4, 0x5f, 0xd2, 0x71, 0xdc, 0xd0, 0xed, 0xc9, 0x8e, 0xb5, 0x31, 0x6a, 0xa9, 0xa1, 0xf6, 0xe8, + 0xf6, 0xe6, 0x18, 0xe1, 0x74, 0xdf, 0x30, 0x1a, 0xa1, 0x37, 0x49, 0xc3, 0x2b, 0x37, 0x3f, 0x30, + 0xfc, 0xee, 0x04, 0x9f, 0xf6, 0xce, 0x75, 0x28, 0x9e, 0xf9, 0x3a, 0x14, 0x7f, 0xc1, 0x75, 0xf8, + 0x82, 0xf0, 0xdc, 0xc0, 0x1c, 0x25, 0x37, 0x46, 0x94, 0x3a, 0x38, 0x7b, 0xc7, 0x92, 0x3b, 0xde, + 0xc0, 0x2b, 0x9e, 0xdf, 0xfa, 0xab, 0x47, 0x08, 0xff, 0x5b, 0xe3, 0xcd, 0x61, 0xf2, 0x56, 0x67, + 0x95, 0xac, 0xad, 0x40, 0xc4, 0x16, 0xda, 0xdd, 0x50, 0x09, 0x36, 0x77, 0x29, 0xb3, 0x0d, 0xee, + 0xdb, 0xa6, 0x0d, 0x2c, 0x94, 0x68, 0x46, 0x4b, 0xd4, 0x73, 0xc4, 0xa9, 0xff, 0x8a, 0xcb, 0xdd, + 0xd0, 0x37, 0x84, 0x3e, 0x6a, 0x5a, 0x79, 0xed, 0x48, 0x5b, 0x5a, 0x8f, 0x6a, 0x96, 0x42, 0x12, + 0xe5, 0x2e, 0x89, 0xfb, 0x51, 0xd2, 0xde, 0x64, 0x58, 0xff, 0xf2, 0x8f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x61, 0xec, 0x01, 0x66, 0x8a, 0x0a, 0x00, 0x00, } diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/intent.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/intent.pb.go index 4d9baf5c3d..9184b14bc9 100644 --- a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/intent.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/intent.pb.go @@ -185,7 +185,19 @@ type Intent struct { // Note: If `ml_enabled` setting is set to false, then this intent is not // taken into account during inference in `ML ONLY` match mode. Also, // auto-markup in the UI is turned off. + // DEPRECATED! Please use `ml_disabled` field instead. + // NOTE: If neither `ml_enabled` nor `ml_disabled` field is set, then the + // default value is determined as follows: + // - Before April 15th, 2018 the default is: + // ml_enabled = false / ml_disabled = true. + // - After April 15th, 2018 the default is: + // ml_enabled = true / ml_disabled = false. MlEnabled bool `protobuf:"varint,5,opt,name=ml_enabled,json=mlEnabled" json:"ml_enabled,omitempty"` + // Optional. Indicates whether Machine Learning is disabled for the intent. + // Note: If `ml_disabled` setting is set to true, then this intent is not + // taken into account during inference in `ML ONLY` match mode. Also, + // auto-markup in the UI is turned off. + MlDisabled bool `protobuf:"varint,19,opt,name=ml_disabled,json=mlDisabled" json:"ml_disabled,omitempty"` // Optional. The list of context names required for this intent to be // triggered. // Format: `projects//agent/sessions/-/contexts/`. @@ -277,6 +289,13 @@ func (m *Intent) GetMlEnabled() bool { return false } +func (m *Intent) GetMlDisabled() bool { + if m != nil { + return m.MlDisabled + } + return false +} + func (m *Intent) GetInputContextNames() []string { if m != nil { return m.InputContextNames @@ -2375,14 +2394,14 @@ var _Intents_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("google/cloud/dialogflow/v2beta1/intent.proto", fileDescriptor3) } var fileDescriptor3 = []byte{ - // 2577 bytes of a gzipped FileDescriptorProto + // 2592 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcd, 0x73, 0x23, 0x47, 0xd9, 0xf7, 0xe8, 0xc3, 0x96, 0x1e, 0xc9, 0xb2, 0xdc, 0xde, 0x6c, 0xb4, 0x93, 0xa4, 0xe2, 0x28, 0x6f, 0xf2, 0x3a, 0x7e, 0x13, 0xe9, 0x8d, 0x92, 0x37, 0x1f, 0xbb, 0x6f, 0x12, 0x64, 0x5b, 0x5e, 0x0b, 0xcb, 0x96, 0x76, 0x2c, 0x6f, 0xd8, 0x14, 0x30, 0x35, 0x92, 0xda, 0xda, 0xc6, 0xa3, 0x99, - 0xc9, 0x74, 0xcb, 0x1b, 0x05, 0x52, 0x45, 0x51, 0x05, 0x1c, 0xb8, 0x50, 0x70, 0xa2, 0xb8, 0xc1, - 0x29, 0x14, 0x07, 0x2a, 0x37, 0xfe, 0x04, 0x0e, 0x9c, 0x38, 0xe6, 0x40, 0x51, 0x45, 0xf1, 0x27, - 0x50, 0xdc, 0xa0, 0xfa, 0x63, 0xa4, 0x91, 0xa5, 0x45, 0x92, 0xbd, 0x70, 0xe1, 0x36, 0xfd, 0x74, + 0xc9, 0x74, 0xcb, 0x1b, 0x05, 0x52, 0x45, 0x51, 0x05, 0x1c, 0xb8, 0x50, 0x70, 0xa0, 0x28, 0x6e, + 0x70, 0x0a, 0xc5, 0x81, 0xca, 0x8d, 0x3f, 0x81, 0x03, 0x27, 0x8e, 0x39, 0x50, 0x54, 0x51, 0xfc, + 0x0d, 0xdc, 0xa0, 0xfa, 0x63, 0xa4, 0x91, 0xa5, 0x45, 0x92, 0xbd, 0x70, 0xe1, 0x36, 0xfd, 0x74, 0xf7, 0xef, 0xf9, 0xea, 0xfe, 0x3d, 0xdd, 0x2d, 0xc1, 0xab, 0x5d, 0xd7, 0xed, 0xda, 0xb8, 0xd8, 0xb6, 0xdd, 0x7e, 0xa7, 0xd8, 0x21, 0x96, 0xed, 0x76, 0xcf, 0x6c, 0xf7, 0x51, 0xf1, 0xa2, 0xd4, 0xc2, 0xcc, 0x7a, 0xbd, 0x48, 0x1c, 0x86, 0x1d, 0x56, 0xf0, 0x7c, 0x97, 0xb9, 0xe8, 0x79, 0x39, @@ -2391,151 +2410,151 @@ var fileDescriptor3 = []byte{ 0xf0, 0x27, 0x4a, 0x9b, 0xfe, 0xa2, 0x1a, 0x6e, 0xbb, 0x4e, 0xd7, 0xef, 0x3b, 0x0e, 0x71, 0xba, 0x45, 0xd7, 0xc3, 0xfe, 0x18, 0xe6, 0x33, 0x6a, 0x90, 0x68, 0xb5, 0xfa, 0x67, 0x45, 0xdc, 0xf3, 0xd8, 0x40, 0x75, 0x6e, 0x5e, 0xee, 0x3c, 0x23, 0xd8, 0xee, 0x98, 0x3d, 0x8b, 0x9e, 0xab, 0x11, - 0xcf, 0x5e, 0x1e, 0x41, 0x99, 0xdf, 0x6f, 0x2b, 0x0b, 0xf2, 0x7f, 0x7d, 0x05, 0x96, 0xab, 0x22, - 0x00, 0x08, 0x41, 0xcc, 0xb1, 0x7a, 0x38, 0xa7, 0x6d, 0x6a, 0x5b, 0x49, 0x43, 0x7c, 0xa3, 0x17, - 0x20, 0xdd, 0x21, 0xd4, 0xb3, 0xad, 0x81, 0x29, 0xfa, 0x22, 0xa2, 0x2f, 0xa5, 0x64, 0xc7, 0x7c, - 0xc8, 0x03, 0x58, 0x7d, 0x84, 0x5b, 0x0f, 0x5d, 0xf7, 0xdc, 0xa4, 0xcc, 0x62, 0x38, 0xb7, 0xbc, - 0xa9, 0x6d, 0x65, 0x4a, 0x6f, 0x16, 0x66, 0x44, 0xb2, 0x20, 0xd5, 0x16, 0x3e, 0x94, 0x93, 0x4f, - 0xf8, 0x5c, 0x23, 0xfd, 0x28, 0xd4, 0x42, 0x3a, 0x24, 0x3c, 0x9f, 0xb8, 0x3e, 0x61, 0x83, 0x5c, - 0x74, 0x53, 0xdb, 0x8a, 0x1b, 0xc3, 0x36, 0x7a, 0x1e, 0x52, 0x84, 0x9a, 0x67, 0x96, 0x6d, 0xb7, - 0xac, 0xf6, 0x79, 0x2e, 0xb6, 0xa9, 0x6d, 0x25, 0x0c, 0x20, 0x74, 0x5f, 0x49, 0xd0, 0x73, 0x00, - 0x3d, 0xdb, 0xc4, 0x8e, 0xd5, 0xb2, 0x71, 0x27, 0x17, 0x17, 0xfd, 0xc9, 0x9e, 0x5d, 0x91, 0x02, - 0x54, 0x80, 0x0d, 0xe2, 0x78, 0x7d, 0x66, 0xaa, 0x8c, 0x08, 0xff, 0x68, 0x6e, 0x65, 0x33, 0xba, - 0x95, 0x34, 0xd6, 0x45, 0xd7, 0xae, 0xec, 0xe1, 0x5e, 0x52, 0x74, 0x13, 0x96, 0xf1, 0x05, 0x76, - 0x18, 0xcd, 0x25, 0xc4, 0x10, 0xd5, 0x42, 0x16, 0x64, 0x99, 0x6f, 0x11, 0x9e, 0x3a, 0xd3, 0x7b, - 0xe8, 0x5b, 0x14, 0xd3, 0x5c, 0x72, 0x33, 0xba, 0x95, 0x2a, 0xbd, 0x35, 0x6f, 0x04, 0x9a, 0x6a, - 0x7e, 0x43, 0x4c, 0x37, 0xd6, 0xd8, 0x58, 0x5b, 0xa8, 0xb6, 0xda, 0x7c, 0x45, 0xe4, 0x40, 0x84, - 0x5f, 0xb5, 0xd0, 0x3d, 0x58, 0x73, 0xfb, 0x2c, 0xe4, 0x03, 0xcd, 0xa5, 0x84, 0xe6, 0xad, 0x99, - 0x9a, 0x95, 0x6b, 0x46, 0x46, 0x02, 0xa8, 0x26, 0x45, 0x2f, 0x41, 0xc6, 0xc7, 0x14, 0x87, 0x10, - 0xd3, 0x22, 0x70, 0xab, 0x42, 0x3a, 0x1c, 0x76, 0x0f, 0xc0, 0xb3, 0x7c, 0xab, 0x87, 0x19, 0xf6, - 0x69, 0x6e, 0x55, 0x28, 0x7d, 0x7d, 0x5e, 0x77, 0x1b, 0xc1, 0x4c, 0x23, 0x04, 0x82, 0x0e, 0x21, - 0xd1, 0xc3, 0x94, 0x5a, 0x5d, 0x4c, 0x73, 0x19, 0x01, 0x58, 0x9c, 0x17, 0xf0, 0x48, 0xce, 0x33, - 0x86, 0x00, 0xe8, 0x02, 0xf4, 0x0e, 0x3e, 0xb3, 0xfa, 0x36, 0x33, 0x7d, 0x4c, 0x3d, 0xd7, 0xa1, - 0xd8, 0xf4, 0x6c, 0x8b, 0x9d, 0xb9, 0x7e, 0x8f, 0xe6, 0xd6, 0x36, 0xa3, 0x5b, 0x99, 0xd2, 0x3b, - 0x0b, 0xc2, 0x17, 0x1a, 0x0a, 0xc0, 0xc8, 0x29, 0x6c, 0x43, 0x41, 0x07, 0x1d, 0x14, 0xbd, 0x0b, - 0xb7, 0x7c, 0xd7, 0x65, 0xe6, 0x99, 0x6b, 0xdb, 0xee, 0xa3, 0xbe, 0x67, 0x4a, 0x6e, 0x91, 0x7b, - 0x27, 0x2b, 0x92, 0x77, 0x93, 0x0f, 0xd8, 0x57, 0xfd, 0x52, 0x83, 0xd8, 0x46, 0xef, 0xc1, 0x33, - 0x9e, 0xe5, 0xf3, 0xc1, 0x53, 0x27, 0xaf, 0x8b, 0xc9, 0x39, 0x39, 0x64, 0xca, 0x74, 0x1b, 0x6e, - 0x5c, 0x9e, 0x47, 0x9c, 0x33, 0x37, 0x87, 0x44, 0x28, 0x6f, 0xcf, 0xeb, 0xeb, 0x38, 0x72, 0xd5, - 0x39, 0x73, 0x0d, 0x74, 0x36, 0x21, 0xd3, 0x7f, 0x19, 0x85, 0xcc, 0xf8, 0xaa, 0x9d, 0xca, 0x1e, - 0x75, 0x88, 0xb1, 0x81, 0x27, 0x59, 0x23, 0x53, 0xba, 0x73, 0xb5, 0xfd, 0x50, 0x68, 0x0e, 0x3c, - 0x6c, 0x08, 0x20, 0x74, 0x0f, 0xe2, 0x9e, 0xe5, 0x33, 0x9a, 0x8b, 0x0a, 0xb7, 0xae, 0x8a, 0xd8, - 0xb0, 0x7c, 0x66, 0x48, 0x24, 0xb4, 0x0d, 0xeb, 0x8c, 0xf4, 0x30, 0x35, 0xad, 0x4e, 0x07, 0x77, - 0xcc, 0xb6, 0xdb, 0x77, 0x98, 0x60, 0x93, 0xb8, 0xb1, 0x26, 0x3a, 0xca, 0x5c, 0xbe, 0xcb, 0xc5, - 0x3a, 0x83, 0x18, 0x9f, 0xca, 0x7d, 0xe5, 0xfb, 0x20, 0xf0, 0x95, 0x7f, 0x73, 0x3e, 0xc2, 0x0e, - 0x23, 0x6c, 0x60, 0x0e, 0x5d, 0x4e, 0x1a, 0x20, 0x45, 0xdc, 0x03, 0x74, 0x03, 0xe2, 0x96, 0x4d, - 0x2c, 0x2a, 0x98, 0x2c, 0x69, 0xc8, 0x06, 0x27, 0xd8, 0x3e, 0xc5, 0xbe, 0xd9, 0xc1, 0x67, 0xc4, - 0xc1, 0x1d, 0xc5, 0x63, 0x29, 0x2e, 0xdb, 0x93, 0xa2, 0xfc, 0xdb, 0x10, 0x53, 0x00, 0xd9, 0xe6, - 0x83, 0x46, 0xc5, 0x3c, 0x3d, 0x3e, 0x69, 0x54, 0x76, 0xab, 0xfb, 0xd5, 0xca, 0x5e, 0x76, 0x09, - 0xa5, 0x60, 0xa5, 0xf2, 0xb5, 0xf2, 0x51, 0xa3, 0x56, 0xc9, 0x6a, 0x28, 0x0d, 0x89, 0x66, 0xe5, - 0xa8, 0x51, 0x2b, 0x37, 0x2b, 0xd9, 0x88, 0xfe, 0xc3, 0x08, 0x24, 0x87, 0x9b, 0xed, 0xaa, 0xf4, - 0x7e, 0x03, 0xe2, 0x17, 0x96, 0xdd, 0xc7, 0x81, 0xd9, 0xa2, 0x81, 0x5e, 0x84, 0xd5, 0x60, 0x83, - 0xc9, 0xde, 0x98, 0xe8, 0x4d, 0x2b, 0xe1, 0x7d, 0x31, 0xe8, 0x6d, 0xc8, 0x85, 0x42, 0x62, 0x8e, - 0x69, 0x8a, 0x8b, 0xf1, 0x4f, 0x8d, 0xe2, 0xb3, 0x17, 0xd2, 0xf9, 0x2c, 0x24, 0x7b, 0x96, 0xd3, - 0xb1, 0x98, 0xeb, 0x0f, 0x44, 0x39, 0xe1, 0xcc, 0x1d, 0x08, 0x50, 0x0e, 0x56, 0x3c, 0xdf, 0xed, - 0x79, 0x2c, 0x60, 0xeb, 0xa0, 0x89, 0x9e, 0x86, 0x15, 0x42, 0x4d, 0x9b, 0x50, 0x96, 0x4b, 0x88, - 0x59, 0xcb, 0x84, 0xd6, 0x08, 0x65, 0xfa, 0x4f, 0x74, 0x58, 0x51, 0xdb, 0x18, 0x7d, 0x35, 0x94, - 0xbc, 0xd4, 0xfc, 0x65, 0x2a, 0x60, 0x81, 0x26, 0xfe, 0x84, 0x1d, 0x2c, 0xa9, 0xa4, 0x1f, 0x41, - 0x9c, 0xf4, 0xac, 0xae, 0x0c, 0x5c, 0xaa, 0xf4, 0x7f, 0x8b, 0x82, 0x55, 0xf9, 0xe4, 0x83, 0x25, - 0x43, 0xa2, 0xa0, 0x36, 0xac, 0x7e, 0xdc, 0x27, 0xed, 0x73, 0xd3, 0xc7, 0x9e, 0x4d, 0xb0, 0x5c, - 0x2a, 0xa9, 0xd2, 0xff, 0x2f, 0x0a, 0x7b, 0x8f, 0x83, 0x18, 0x12, 0xe3, 0x60, 0xc9, 0x48, 0x7f, - 0x1c, 0x6a, 0x73, 0xff, 0xdb, 0x96, 0x2f, 0x57, 0xda, 0x15, 0xfc, 0xdf, 0xb5, 0xfc, 0x0e, 0xf7, - 0x9f, 0x63, 0xa0, 0x37, 0x60, 0xc5, 0xb3, 0x06, 0xb6, 0x6b, 0xc9, 0x02, 0x9b, 0x2a, 0x3d, 0x1d, - 0xc0, 0x05, 0xa7, 0x8d, 0xc2, 0x89, 0x38, 0x6d, 0x1c, 0x2c, 0x19, 0xc1, 0x48, 0x64, 0x43, 0x96, - 0x92, 0x9e, 0x67, 0xe3, 0x21, 0x37, 0xf3, 0x44, 0xf2, 0xd9, 0x1f, 0x2c, 0x6a, 0xcc, 0x89, 0xc0, - 0x09, 0x78, 0x98, 0xfb, 0xba, 0x46, 0xc7, 0x45, 0xe8, 0x23, 0x80, 0x96, 0x45, 0x49, 0xdb, 0x14, - 0x4e, 0x27, 0x84, 0x9e, 0x77, 0x17, 0xd5, 0xb3, 0xc3, 0x11, 0x94, 0xe7, 0xc9, 0x56, 0xd0, 0x40, - 0x26, 0xa4, 0x68, 0xbf, 0xdb, 0xc5, 0x54, 0x1c, 0xd7, 0x72, 0x49, 0x01, 0x7e, 0x67, 0x61, 0x27, - 0x46, 0x10, 0x07, 0x4b, 0x46, 0x18, 0x11, 0x51, 0xd8, 0xb0, 0x89, 0x73, 0x6e, 0xba, 0x7d, 0x66, - 0x8e, 0xe4, 0xe2, 0x18, 0x90, 0x2a, 0x95, 0x17, 0x55, 0x54, 0x23, 0xce, 0x79, 0xbd, 0xcf, 0x46, - 0xfa, 0x0e, 0x96, 0x8c, 0x75, 0xfb, 0xb2, 0x10, 0x7d, 0x03, 0x52, 0x7c, 0x0b, 0x99, 0x14, 0xdb, - 0xb8, 0xcd, 0x72, 0x29, 0xa1, 0xec, 0xf6, 0xe2, 0xca, 0x28, 0x3b, 0x11, 0x08, 0x07, 0x4b, 0x06, - 0xd8, 0xc3, 0x16, 0x22, 0xb0, 0xd6, 0xb6, 0x7c, 0xb7, 0x4f, 0xb1, 0x1d, 0xa8, 0x48, 0x0b, 0x15, - 0xef, 0x5f, 0x61, 0x29, 0x0a, 0x98, 0xa1, 0x9a, 0x4c, 0x7b, 0x4c, 0x82, 0x9a, 0x90, 0x08, 0xaa, - 0xbe, 0x3a, 0x95, 0x5e, 0xbd, 0xe8, 0x0f, 0x91, 0x74, 0x1d, 0x62, 0x9c, 0x04, 0x42, 0x55, 0x20, - 0x1a, 0x54, 0x01, 0xfd, 0x04, 0xe2, 0x62, 0x4f, 0xa3, 0x67, 0x20, 0x29, 0xf6, 0xb4, 0xd9, 0xf7, - 0x89, 0xa2, 0xdc, 0x84, 0x10, 0x9c, 0xfa, 0x04, 0xbd, 0x06, 0xc8, 0x6a, 0xb7, 0x31, 0xa5, 0xa4, - 0x45, 0x6c, 0xc1, 0x8f, 0x1c, 0x47, 0x92, 0xef, 0xfa, 0x58, 0x0f, 0x57, 0xa4, 0x57, 0x21, 0x1d, - 0xde, 0xd1, 0x9c, 0x92, 0x19, 0x61, 0x76, 0x40, 0xe5, 0xb2, 0xc1, 0x29, 0x79, 0x9c, 0x3c, 0x22, - 0xc2, 0xae, 0xb1, 0xcd, 0xaf, 0xff, 0x45, 0x83, 0x98, 0x58, 0xba, 0xd3, 0x31, 0x74, 0x48, 0xd0, - 0x7e, 0x4b, 0x76, 0x48, 0x73, 0x86, 0xed, 0x71, 0x8f, 0xa2, 0x97, 0x3c, 0x3a, 0x85, 0x95, 0x56, - 0x9f, 0x31, 0xbe, 0x0b, 0x62, 0x8b, 0x95, 0xe6, 0x30, 0xaf, 0x14, 0x76, 0x04, 0x86, 0x11, 0x60, - 0xe9, 0xef, 0xc0, 0xb2, 0x14, 0x4d, 0x2d, 0xb9, 0xfc, 0x7a, 0xe0, 0x52, 0x26, 0xce, 0xff, 0xca, - 0xda, 0xa0, 0xad, 0xf7, 0x20, 0x33, 0x4e, 0x0e, 0xe8, 0xbf, 0x20, 0x23, 0xce, 0xf9, 0xcc, 0x35, - 0xa9, 0x87, 0x71, 0xfb, 0xa1, 0xc2, 0x4a, 0x73, 0x69, 0xd3, 0x3d, 0x11, 0x32, 0xae, 0x87, 0xd2, - 0x9e, 0xad, 0xf0, 0xc4, 0x77, 0xb8, 0x4a, 0x0a, 0x1b, 0xa2, 0x63, 0x55, 0x52, 0xa4, 0xe8, 0x3b, - 0xb0, 0x76, 0x89, 0x8b, 0x10, 0x99, 0x42, 0x73, 0x9a, 0x88, 0xcd, 0xfb, 0xd7, 0xa3, 0xb9, 0x09, - 0x8e, 0xd3, 0x7f, 0x17, 0x85, 0xe4, 0x90, 0xa2, 0xae, 0x90, 0xda, 0x97, 0x20, 0xc3, 0x57, 0xb6, - 0xc5, 0x18, 0xee, 0x84, 0x5d, 0x5c, 0x1d, 0x4a, 0xc5, 0x82, 0x3f, 0x0c, 0xaa, 0x5d, 0xec, 0x1a, - 0xd5, 0x2e, 0xa8, 0x75, 0x1f, 0x8d, 0x56, 0x4c, 0x5c, 0x44, 0xe5, 0x2b, 0x57, 0x26, 0xe5, 0x89, - 0x65, 0xf3, 0x5b, 0x6d, 0xb8, 0x6e, 0xa6, 0x07, 0xe3, 0x02, 0xd6, 0x5c, 0x0f, 0x3b, 0x7c, 0x29, - 0x9b, 0xea, 0x6a, 0x25, 0x2b, 0xf8, 0xf1, 0x75, 0x8d, 0x28, 0xd4, 0x3d, 0xec, 0x9c, 0xfa, 0xa4, - 0x2c, 0x50, 0x8d, 0x55, 0x37, 0xdc, 0xd4, 0x5f, 0x80, 0xd5, 0xb1, 0x7e, 0x94, 0x85, 0xe8, 0x88, - 0x20, 0xf8, 0xa7, 0x9e, 0x07, 0x08, 0x71, 0xf1, 0x54, 0xf3, 0xf5, 0x73, 0x48, 0x85, 0x8a, 0x06, - 0xfa, 0xfa, 0x78, 0x19, 0xd2, 0x16, 0x3b, 0xf2, 0x4f, 0x96, 0xa1, 0xb1, 0x1a, 0xa4, 0x37, 0x60, - 0x7d, 0xa2, 0x70, 0xa0, 0x57, 0x20, 0xdb, 0xe1, 0x9f, 0x8e, 0x78, 0xa9, 0x30, 0x43, 0x07, 0xcb, - 0xb5, 0x90, 0x5c, 0x1c, 0xe6, 0x94, 0x8b, 0x91, 0x91, 0x8b, 0x5f, 0x46, 0x00, 0x46, 0xe5, 0xe1, - 0x31, 0x29, 0x3a, 0x85, 0x38, 0x61, 0xb8, 0x27, 0x69, 0xec, 0x0a, 0x47, 0x83, 0x91, 0x82, 0x42, - 0x95, 0xe1, 0x9e, 0x21, 0xd1, 0xf4, 0x3f, 0x6a, 0x10, 0xe3, 0x6d, 0x64, 0x40, 0x4c, 0x5c, 0x90, - 0xb4, 0xab, 0xd5, 0x1e, 0x09, 0xcd, 0x91, 0xc4, 0x25, 0x49, 0x60, 0x8d, 0x3c, 0x89, 0x84, 0x3d, - 0xd9, 0x84, 0x54, 0x07, 0xd3, 0xb6, 0x4f, 0x3c, 0xb1, 0xd0, 0x02, 0xf6, 0x18, 0x89, 0x9e, 0xe8, - 0xc6, 0xd2, 0x7f, 0x1f, 0x81, 0xcc, 0x78, 0x65, 0x44, 0x0f, 0x82, 0x58, 0xca, 0xa5, 0xb1, 0x7b, - 0xbd, 0x42, 0xfb, 0x1f, 0x16, 0xcf, 0xf7, 0x21, 0x33, 0x6e, 0x1c, 0x5f, 0xd1, 0xe7, 0x78, 0x10, - 0x6c, 0xda, 0x73, 0x3c, 0x10, 0xe4, 0x3a, 0x70, 0x5c, 0x67, 0xd0, 0x0b, 0xca, 0xee, 0xb0, 0x9d, - 0xff, 0x91, 0x06, 0x89, 0xe0, 0x14, 0x81, 0x72, 0x70, 0x83, 0xdf, 0xce, 0xf6, 0xeb, 0xc6, 0xd1, - 0xa5, 0x7b, 0x5c, 0x1a, 0x12, 0xfb, 0xe5, 0xdd, 0xca, 0x4e, 0xbd, 0x7e, 0x98, 0xd5, 0x50, 0x12, - 0xe2, 0x27, 0xb5, 0xf2, 0xee, 0x61, 0x36, 0x22, 0xef, 0x74, 0xb5, 0xca, 0x5d, 0xa3, 0x7c, 0x94, - 0x8d, 0xa2, 0x15, 0x88, 0x1e, 0x56, 0x0f, 0xb3, 0x31, 0x31, 0xe2, 0xf0, 0x41, 0xa3, 0x92, 0x8d, - 0xa3, 0x04, 0xc4, 0x6a, 0xd5, 0xe3, 0x4a, 0x76, 0x99, 0x0b, 0xef, 0x57, 0x77, 0x2a, 0x46, 0x76, - 0x05, 0x3d, 0x05, 0xeb, 0xe5, 0xdd, 0x66, 0xb5, 0x7e, 0x7c, 0x62, 0xd6, 0x8f, 0xcd, 0xbb, 0xf5, - 0xfa, 0xdd, 0x5a, 0x25, 0x9b, 0xd8, 0x49, 0xc2, 0x8a, 0x7a, 0x25, 0xd1, 0xbf, 0xaf, 0x01, 0x9a, - 0xbc, 0xef, 0xa3, 0xff, 0x9d, 0x7c, 0x49, 0x08, 0x6d, 0xef, 0x4b, 0xaf, 0x01, 0xf3, 0x3c, 0x5d, - 0x44, 0xfe, 0xf9, 0xd3, 0x45, 0x9e, 0x41, 0x3a, 0xfc, 0x06, 0x88, 0x9e, 0x83, 0x5b, 0x1f, 0x56, - 0x76, 0x0e, 0xea, 0xf5, 0x43, 0xf3, 0xa4, 0x59, 0x6e, 0x5e, 0xbe, 0xf0, 0xde, 0x82, 0xa7, 0xc6, - 0xbb, 0x2b, 0xc7, 0xe5, 0x9d, 0x5a, 0x65, 0x2f, 0xab, 0xa1, 0x6d, 0x78, 0x79, 0x6a, 0x97, 0xb9, - 0x5f, 0x37, 0xcc, 0x93, 0x5a, 0xbd, 0x69, 0xee, 0x57, 0x6b, 0xb5, 0xea, 0xf1, 0xdd, 0x6c, 0x24, - 0xff, 0xa5, 0x06, 0x88, 0x73, 0x84, 0x34, 0x84, 0x1a, 0xf8, 0xe3, 0x3e, 0xa6, 0x0c, 0xdd, 0x84, - 0x65, 0x69, 0xa8, 0xf2, 0x57, 0xb5, 0xf8, 0xe9, 0xca, 0xb6, 0x9c, 0x6e, 0x9f, 0x1f, 0x80, 0xda, - 0x6e, 0x27, 0xf0, 0x2a, 0x1d, 0x08, 0x77, 0xdd, 0x0e, 0x46, 0x35, 0x48, 0x29, 0xc7, 0x2f, 0x08, - 0x7e, 0x24, 0x56, 0x66, 0xa6, 0xf4, 0x3f, 0x73, 0xae, 0xbe, 0xfb, 0x04, 0x3f, 0x32, 0x80, 0x0c, - 0xbf, 0xf9, 0x81, 0xcb, 0xe3, 0xea, 0x28, 0xf9, 0x14, 0xab, 0x17, 0x89, 0x04, 0x17, 0x9c, 0x90, - 0x4f, 0x79, 0x90, 0x40, 0x74, 0x32, 0xf7, 0x1c, 0x3b, 0xea, 0x36, 0x2d, 0x86, 0x37, 0xb9, 0x20, - 0xff, 0x5d, 0x0d, 0x36, 0xc6, 0xbc, 0x53, 0x87, 0xa0, 0x32, 0xac, 0x48, 0x0d, 0x01, 0x17, 0xfc, - 0xf7, 0x9c, 0xd6, 0x19, 0xc1, 0x3c, 0xf4, 0x32, 0xac, 0x39, 0xfc, 0x1c, 0x15, 0x52, 0x2f, 0x63, - 0xb1, 0xca, 0xc5, 0x8d, 0xa1, 0x09, 0x3f, 0xd3, 0x20, 0x7b, 0x17, 0x2b, 0x0b, 0x82, 0xf0, 0x4e, - 0x7b, 0x84, 0xf8, 0xf7, 0x87, 0x36, 0xff, 0x27, 0x0d, 0x36, 0x76, 0x7d, 0x6c, 0x31, 0x3c, 0x6e, - 0xde, 0xe3, 0xb2, 0xff, 0x01, 0x2c, 0xcb, 0xd9, 0xea, 0x98, 0x30, 0x77, 0xd4, 0xd4, 0xb4, 0x49, - 0x1f, 0xa3, 0xb3, 0x7d, 0x8c, 0x5d, 0xcf, 0xc7, 0x1f, 0x44, 0x60, 0xe3, 0xd4, 0xeb, 0x4c, 0xf8, - 0x38, 0xf2, 0x45, 0x7b, 0x42, 0xbe, 0x4c, 0xcb, 0xd7, 0x1d, 0x48, 0xf5, 0x85, 0x72, 0xf1, 0x53, - 0x84, 0x7a, 0xc8, 0xd0, 0x27, 0x5e, 0x07, 0xf6, 0x09, 0xb6, 0x3b, 0x47, 0x16, 0x3d, 0x37, 0x40, - 0x0e, 0xe7, 0xdf, 0x4f, 0x38, 0x10, 0xaf, 0xc0, 0xc6, 0x1e, 0xb6, 0xf1, 0xe5, 0x38, 0x4c, 0x59, - 0x8a, 0xf9, 0xbf, 0x47, 0xe0, 0xd6, 0x8e, 0xc5, 0xda, 0x0f, 0xc3, 0x81, 0x9b, 0xc9, 0x0d, 0xdb, - 0x90, 0x55, 0xe6, 0xb6, 0xf8, 0x5c, 0x73, 0x78, 0xdc, 0xe1, 0x57, 0x52, 0xd9, 0x23, 0x41, 0x7d, - 0x82, 0xbe, 0x09, 0x1b, 0x63, 0x63, 0x89, 0x63, 0x13, 0x07, 0xab, 0xf8, 0xbc, 0x3a, 0xa7, 0x8b, - 0x02, 0x8d, 0x5f, 0xde, 0x43, 0xe0, 0x55, 0x01, 0x34, 0x99, 0x9c, 0xd8, 0xec, 0xe4, 0xc4, 0xaf, - 0x93, 0x9c, 0xe5, 0x6b, 0x25, 0x67, 0x27, 0x03, 0xe9, 0x70, 0x3c, 0xf2, 0x26, 0xe8, 0xd3, 0x12, - 0xf0, 0xc4, 0xe8, 0x2b, 0x7f, 0xa1, 0x32, 0x1c, 0x5e, 0x12, 0x33, 0x33, 0x1c, 0xd2, 0x1b, 0xb9, - 0xa2, 0xde, 0x06, 0xa4, 0x42, 0xc9, 0x7b, 0x02, 0x9e, 0x6c, 0x7f, 0x00, 0x50, 0x0d, 0x57, 0x8b, - 0xa7, 0xab, 0xc7, 0xcd, 0xca, 0x71, 0xd3, 0xbc, 0x5f, 0xad, 0x7c, 0x78, 0xa9, 0x66, 0xde, 0x80, - 0x6c, 0xb8, 0x73, 0xff, 0xb4, 0x56, 0xcb, 0x6a, 0xa5, 0x2f, 0x92, 0xb0, 0xa2, 0x02, 0x80, 0x7e, - 0xad, 0x41, 0x2a, 0x54, 0x30, 0xd0, 0x1b, 0x33, 0xcd, 0x99, 0x2c, 0x9e, 0xfa, 0x9b, 0x8b, 0x4d, - 0x92, 0x49, 0xcd, 0x97, 0xbe, 0xf7, 0x87, 0x3f, 0xff, 0x34, 0xf2, 0x2a, 0xda, 0x1e, 0xfe, 0x48, - 0xfa, 0x6d, 0x19, 0xf6, 0xf7, 0x3c, 0xdf, 0xfd, 0x16, 0x6e, 0x33, 0x5a, 0xdc, 0x2e, 0x5a, 0x5d, - 0xec, 0xb0, 0xcf, 0x8a, 0x41, 0x11, 0xfa, 0xb9, 0x06, 0xc9, 0x61, 0x71, 0x41, 0xb3, 0x7f, 0x7a, - 0xba, 0x5c, 0x88, 0xf4, 0x79, 0xc3, 0x3d, 0xcd, 0x3a, 0x4e, 0x15, 0x13, 0xb6, 0x05, 0xa6, 0x15, - 0xb7, 0x3f, 0x43, 0x9f, 0x6b, 0x90, 0x0e, 0x97, 0x17, 0x34, 0x3b, 0x30, 0x53, 0xaa, 0xd1, 0xfc, - 0x36, 0xde, 0x16, 0x36, 0xbe, 0x99, 0x5f, 0x20, 0x82, 0xb7, 0x03, 0x36, 0xff, 0x8d, 0x06, 0xe9, - 0xf0, 0x66, 0x9b, 0xc3, 0xd6, 0x29, 0x55, 0x65, 0x7e, 0x5b, 0xcb, 0xc2, 0xd6, 0x3b, 0xa5, 0xd7, - 0x47, 0xb6, 0xaa, 0x1f, 0xe0, 0x67, 0x85, 0x75, 0x68, 0xf2, 0x8f, 0x35, 0x48, 0x87, 0xb7, 0xef, - 0x1c, 0x26, 0x4f, 0x29, 0x00, 0xfa, 0xcd, 0x09, 0xc2, 0xab, 0xf4, 0x3c, 0x36, 0x08, 0x32, 0xbe, - 0xbd, 0x48, 0xc6, 0xbf, 0xd0, 0x00, 0x4d, 0xf2, 0x16, 0x9a, 0x7d, 0x09, 0x7f, 0x6c, 0xb5, 0xd1, - 0x9f, 0x0b, 0xe6, 0x86, 0xfe, 0x1c, 0x50, 0xa8, 0x07, 0x7f, 0x0e, 0x08, 0xe2, 0x98, 0x7f, 0x6b, - 0x81, 0x9c, 0xb7, 0x46, 0xca, 0x6e, 0x6b, 0xdb, 0x23, 0xa3, 0xc7, 0xb8, 0x70, 0x5e, 0xa3, 0xa7, - 0x11, 0xe8, 0xbf, 0xcc, 0x68, 0xa9, 0xec, 0xb6, 0xb6, 0xbd, 0xf3, 0xb9, 0x06, 0x2f, 0xb6, 0xdd, - 0xde, 0x2c, 0x1b, 0x77, 0x14, 0xdb, 0x36, 0x78, 0x6e, 0x1b, 0xda, 0x47, 0x55, 0x35, 0xbe, 0xeb, - 0xf2, 0x4a, 0x58, 0x70, 0xfd, 0x6e, 0xb1, 0x8b, 0x1d, 0x91, 0xf9, 0xa2, 0xec, 0xb2, 0x3c, 0x42, - 0x1f, 0xfb, 0xbf, 0x8d, 0x3b, 0x23, 0xd1, 0xdf, 0x34, 0xed, 0x17, 0x91, 0xc8, 0xde, 0xfe, 0xaf, - 0x22, 0xcf, 0xdf, 0x95, 0x98, 0xbb, 0xc2, 0x86, 0xbd, 0x91, 0x0d, 0xf7, 0xe5, 0xa4, 0xd6, 0xb2, - 0xc0, 0x7f, 0xe3, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x83, 0x8c, 0xb5, 0x01, 0x83, 0x22, 0x00, - 0x00, + 0xcf, 0x5e, 0x1e, 0x41, 0x99, 0xdf, 0x6f, 0x2b, 0x0b, 0xf2, 0x3f, 0xdb, 0x86, 0xe5, 0xaa, 0x08, + 0x00, 0x42, 0x10, 0x73, 0xac, 0x1e, 0xce, 0x69, 0x9b, 0xda, 0x56, 0xd2, 0x10, 0xdf, 0xe8, 0x05, + 0x48, 0x77, 0x08, 0xf5, 0x6c, 0x6b, 0x60, 0x8a, 0xbe, 0x88, 0xe8, 0x4b, 0x29, 0xd9, 0x31, 0x1f, + 0xf2, 0x00, 0x56, 0x1f, 0xe1, 0xd6, 0x43, 0xd7, 0x3d, 0x37, 0x29, 0xb3, 0x18, 0xce, 0x2d, 0x6f, + 0x6a, 0x5b, 0x99, 0xd2, 0x9b, 0x85, 0x19, 0x91, 0x2c, 0x48, 0xb5, 0x85, 0x0f, 0xe5, 0xe4, 0x13, + 0x3e, 0xd7, 0x48, 0x3f, 0x0a, 0xb5, 0x90, 0x0e, 0x09, 0xcf, 0x27, 0xae, 0x4f, 0xd8, 0x20, 0x17, + 0xdd, 0xd4, 0xb6, 0xe2, 0xc6, 0xb0, 0x8d, 0x9e, 0x87, 0x14, 0xa1, 0xe6, 0x99, 0x65, 0xdb, 0x2d, + 0xab, 0x7d, 0x9e, 0x8b, 0x6d, 0x6a, 0x5b, 0x09, 0x03, 0x08, 0xdd, 0x57, 0x12, 0xf4, 0x1c, 0x40, + 0xcf, 0x36, 0xb1, 0x63, 0xb5, 0x6c, 0xdc, 0xc9, 0xc5, 0x45, 0x7f, 0xb2, 0x67, 0x57, 0xa4, 0x80, + 0xcf, 0xef, 0xd9, 0x66, 0x87, 0x50, 0xd9, 0xbf, 0x21, 0xe7, 0xf7, 0xec, 0x3d, 0x25, 0x41, 0x05, + 0xd8, 0x20, 0x8e, 0xd7, 0x67, 0xa6, 0x4a, 0x99, 0x08, 0x00, 0xcd, 0xad, 0x6c, 0x46, 0xb7, 0x92, + 0xc6, 0xba, 0xe8, 0xda, 0x95, 0x3d, 0x3c, 0x0c, 0x14, 0xdd, 0x84, 0x65, 0x7c, 0x81, 0x1d, 0x46, + 0x73, 0x09, 0x31, 0x44, 0xb5, 0x90, 0x05, 0x59, 0xe6, 0x5b, 0x84, 0xe7, 0xd6, 0xf4, 0x1e, 0xfa, + 0x16, 0xc5, 0x34, 0x97, 0xdc, 0x8c, 0x6e, 0xa5, 0x4a, 0x6f, 0xcd, 0x1b, 0xa2, 0xa6, 0x9a, 0xdf, + 0x10, 0xd3, 0x8d, 0x35, 0x36, 0xd6, 0x16, 0xaa, 0xad, 0x36, 0x5f, 0x32, 0x39, 0x10, 0xf9, 0x51, + 0x2d, 0x74, 0x0f, 0xd6, 0xdc, 0x3e, 0x0b, 0xf9, 0x40, 0x73, 0x29, 0xa1, 0x79, 0x6b, 0xa6, 0x66, + 0xe5, 0x9a, 0x91, 0x91, 0x00, 0xaa, 0x49, 0xd1, 0x4b, 0x90, 0xf1, 0x31, 0xc5, 0x21, 0xc4, 0xb4, + 0x88, 0xdc, 0xaa, 0x90, 0x0e, 0x87, 0xdd, 0x03, 0xf0, 0x2c, 0xdf, 0xea, 0x61, 0x86, 0x7d, 0x9a, + 0x5b, 0x15, 0x4a, 0x5f, 0x9f, 0xd7, 0xdd, 0x46, 0x30, 0xd3, 0x08, 0x81, 0xa0, 0x43, 0x48, 0xf4, + 0x30, 0xa5, 0x56, 0x17, 0xd3, 0x5c, 0x46, 0x00, 0x16, 0xe7, 0x05, 0x3c, 0x92, 0xf3, 0x8c, 0x21, + 0x00, 0xba, 0x00, 0xbd, 0x83, 0xcf, 0xac, 0xbe, 0xcd, 0x4c, 0x1f, 0x53, 0xcf, 0x75, 0x28, 0x36, + 0x3d, 0xdb, 0x62, 0x67, 0xae, 0xdf, 0xa3, 0xb9, 0xb5, 0xcd, 0xe8, 0x56, 0xa6, 0xf4, 0xce, 0x82, + 0xf0, 0x85, 0x86, 0x02, 0x30, 0x72, 0x0a, 0xdb, 0x50, 0xd0, 0x41, 0x07, 0x45, 0xef, 0xc2, 0x2d, + 0xdf, 0x75, 0x99, 0x79, 0xe6, 0xda, 0xb6, 0xfb, 0xa8, 0xef, 0x99, 0x92, 0x7c, 0xe4, 0xe6, 0xca, + 0x8a, 0xe4, 0xdd, 0xe4, 0x03, 0xf6, 0x55, 0xbf, 0xd4, 0x20, 0xf6, 0xd9, 0x7b, 0xf0, 0x8c, 0x67, + 0xf9, 0x7c, 0xf0, 0xd4, 0xc9, 0xeb, 0x62, 0x72, 0x4e, 0x0e, 0x99, 0x32, 0xdd, 0x86, 0x1b, 0x97, + 0xe7, 0x11, 0xe7, 0xcc, 0xcd, 0x21, 0x11, 0xca, 0xdb, 0xf3, 0xfa, 0x3a, 0x8e, 0x5c, 0x75, 0xce, + 0x5c, 0x03, 0x9d, 0x4d, 0xc8, 0xf4, 0x5f, 0x45, 0x21, 0x33, 0xbe, 0x6a, 0xa7, 0xd2, 0x4b, 0x1d, + 0x62, 0x6c, 0xe0, 0x49, 0x5a, 0xc9, 0x94, 0xee, 0x5c, 0x6d, 0x3f, 0x14, 0x9a, 0x03, 0x0f, 0x1b, + 0x02, 0x08, 0xdd, 0x83, 0xb8, 0x67, 0xf9, 0x8c, 0xe6, 0xa2, 0xc2, 0xad, 0xab, 0x22, 0x36, 0x2c, + 0x9f, 0x19, 0x12, 0x09, 0x6d, 0xc3, 0x3a, 0x23, 0x3d, 0x4c, 0x4d, 0xab, 0xd3, 0xc1, 0x1d, 0xb3, + 0xed, 0xf6, 0x1d, 0x26, 0xe8, 0x26, 0x6e, 0xac, 0x89, 0x8e, 0x32, 0x97, 0xef, 0x72, 0xb1, 0xce, + 0x20, 0xc6, 0xa7, 0x72, 0x5f, 0xf9, 0x3e, 0x08, 0x7c, 0xe5, 0xdf, 0x9c, 0x70, 0xb0, 0xc3, 0x08, + 0x1b, 0x98, 0x43, 0x97, 0x93, 0x06, 0x48, 0x11, 0xf7, 0x00, 0xdd, 0x80, 0xb8, 0x65, 0x13, 0x8b, + 0x0a, 0xaa, 0x4b, 0x1a, 0xb2, 0xc1, 0x19, 0xb8, 0x4f, 0xb1, 0x6f, 0x76, 0xf0, 0x19, 0x71, 0x70, + 0x47, 0x11, 0x5d, 0x8a, 0xcb, 0xf6, 0xa4, 0x28, 0xff, 0x36, 0xc4, 0x14, 0x40, 0xb6, 0xf9, 0xa0, + 0x51, 0x31, 0x4f, 0x8f, 0x4f, 0x1a, 0x95, 0xdd, 0xea, 0x7e, 0xb5, 0xb2, 0x97, 0x5d, 0x42, 0x29, + 0x58, 0xa9, 0x7c, 0xad, 0x7c, 0xd4, 0xa8, 0x55, 0xb2, 0x1a, 0x4a, 0x43, 0xa2, 0x59, 0x39, 0x6a, + 0xd4, 0xca, 0xcd, 0x4a, 0x36, 0xa2, 0xff, 0x30, 0x02, 0xc9, 0xe1, 0x66, 0xbb, 0x2a, 0xff, 0xdf, + 0x80, 0xf8, 0x85, 0x65, 0xf7, 0x71, 0x60, 0xb6, 0x68, 0xa0, 0x17, 0x61, 0x35, 0xd8, 0x60, 0xb2, + 0x37, 0x26, 0x7a, 0xd3, 0x4a, 0x78, 0x5f, 0x0c, 0x7a, 0x1b, 0x72, 0xa1, 0x90, 0x98, 0x63, 0x9a, + 0xe2, 0x62, 0xfc, 0x53, 0xa3, 0xf8, 0xec, 0x85, 0x74, 0x3e, 0x0b, 0xc9, 0x9e, 0xe5, 0x74, 0x2c, + 0xe6, 0xfa, 0x03, 0x51, 0x6f, 0x38, 0xb5, 0x07, 0x02, 0x94, 0x83, 0x15, 0xcf, 0x77, 0x7b, 0x1e, + 0x0b, 0xd8, 0x3a, 0x68, 0xa2, 0xa7, 0x61, 0x85, 0x50, 0xd3, 0x26, 0x94, 0xe5, 0x12, 0x62, 0xd6, + 0x32, 0xa1, 0x35, 0x42, 0x99, 0xfe, 0x13, 0x1d, 0x56, 0xd4, 0x36, 0x46, 0x5f, 0x0d, 0x25, 0x2f, + 0x35, 0x7f, 0x1d, 0x0b, 0x58, 0xa0, 0x89, 0x3f, 0x61, 0x07, 0x4b, 0x2a, 0xe9, 0x47, 0x10, 0x27, + 0x3d, 0xab, 0x2b, 0x03, 0x97, 0x2a, 0xfd, 0xdf, 0xa2, 0x60, 0x55, 0x3e, 0xf9, 0x60, 0xc9, 0x90, + 0x28, 0xa8, 0x0d, 0xab, 0x1f, 0xf7, 0x49, 0xfb, 0xdc, 0xf4, 0xb1, 0x67, 0x13, 0x2c, 0x97, 0x4a, + 0xaa, 0xf4, 0xff, 0x8b, 0xc2, 0xde, 0xe3, 0x20, 0x86, 0xc4, 0x38, 0x58, 0x32, 0xd2, 0x1f, 0x87, + 0xda, 0xdc, 0xff, 0xb6, 0xe5, 0xcb, 0x95, 0x76, 0x05, 0xff, 0x77, 0x2d, 0xbf, 0xc3, 0xfd, 0xe7, + 0x18, 0xe8, 0x0d, 0x58, 0xf1, 0xac, 0x81, 0xed, 0x5a, 0xb2, 0x02, 0xa7, 0x4a, 0x4f, 0x07, 0x70, + 0xc1, 0x71, 0xa4, 0x70, 0x22, 0x8e, 0x23, 0x07, 0x4b, 0x46, 0x30, 0x12, 0xd9, 0x90, 0xa5, 0xa4, + 0xe7, 0xd9, 0x78, 0xc8, 0xcd, 0x3c, 0x91, 0x7c, 0xf6, 0x07, 0x8b, 0x1a, 0x73, 0x22, 0x70, 0x02, + 0x1e, 0xe6, 0xbe, 0xae, 0xd1, 0x71, 0x11, 0xfa, 0x08, 0xa0, 0x65, 0x51, 0xd2, 0x36, 0x85, 0xd3, + 0x09, 0xa1, 0xe7, 0xdd, 0x45, 0xf5, 0xec, 0x70, 0x04, 0xe5, 0x79, 0xb2, 0x15, 0x34, 0x90, 0x09, + 0x29, 0xda, 0xef, 0x76, 0x31, 0x15, 0xe7, 0xb9, 0x5c, 0x52, 0x80, 0xdf, 0x59, 0xd8, 0x89, 0x11, + 0xc4, 0xc1, 0x92, 0x11, 0x46, 0x44, 0x14, 0x36, 0x6c, 0xe2, 0x9c, 0x9b, 0x6e, 0x9f, 0x99, 0x23, + 0xb9, 0x38, 0x06, 0xa4, 0x4a, 0xe5, 0x45, 0x15, 0xd5, 0x88, 0x73, 0x5e, 0xef, 0xb3, 0x91, 0xbe, + 0x83, 0x25, 0x63, 0xdd, 0xbe, 0x2c, 0x44, 0xdf, 0x80, 0x14, 0xdf, 0x42, 0x26, 0xc5, 0x36, 0x6e, + 0xb3, 0x5c, 0x4a, 0x28, 0xbb, 0xbd, 0xb8, 0x32, 0xca, 0x4e, 0x04, 0xc2, 0xc1, 0x92, 0x01, 0xf6, + 0xb0, 0x85, 0x08, 0xac, 0xb5, 0x2d, 0xdf, 0xed, 0x53, 0x6c, 0x07, 0x2a, 0xd2, 0x42, 0xc5, 0xfb, + 0x57, 0x58, 0x8a, 0x02, 0x66, 0xa8, 0x26, 0xd3, 0x1e, 0x93, 0xa0, 0x26, 0x24, 0x82, 0xaa, 0xaf, + 0x8e, 0xad, 0x57, 0x2f, 0xfa, 0x43, 0x24, 0x5d, 0x87, 0x18, 0x27, 0x81, 0x50, 0x15, 0x88, 0x06, + 0x55, 0x40, 0x3f, 0x81, 0xb8, 0xd8, 0xd3, 0xe8, 0x19, 0x48, 0x8a, 0x3d, 0x6d, 0xf6, 0x7d, 0xa2, + 0x28, 0x37, 0x21, 0x04, 0xa7, 0x3e, 0x41, 0xaf, 0x01, 0xb2, 0xda, 0x6d, 0x4c, 0x29, 0x69, 0x11, + 0x5b, 0xf0, 0x23, 0xc7, 0x91, 0xe4, 0xbb, 0x3e, 0xd6, 0xc3, 0x15, 0xe9, 0x55, 0x48, 0x87, 0x77, + 0x34, 0xa7, 0x64, 0x46, 0x98, 0x1d, 0x50, 0xb9, 0x6c, 0x70, 0x4a, 0x1e, 0x27, 0x8f, 0x88, 0xb0, + 0x6b, 0x6c, 0xf3, 0xeb, 0x7f, 0xd5, 0x20, 0x26, 0x96, 0xee, 0x74, 0x0c, 0x1d, 0x12, 0xb4, 0xdf, + 0x92, 0x1d, 0xd2, 0x9c, 0x61, 0x7b, 0xdc, 0xa3, 0xe8, 0x25, 0x8f, 0x4e, 0x61, 0xa5, 0xd5, 0x67, + 0x8c, 0xef, 0x82, 0xd8, 0x62, 0xa5, 0x39, 0xcc, 0x2b, 0x85, 0x1d, 0x81, 0x61, 0x04, 0x58, 0xfa, + 0x3b, 0xb0, 0x2c, 0x45, 0x53, 0x4b, 0x2e, 0xbf, 0x3f, 0xb8, 0x94, 0x89, 0x0b, 0x82, 0xb2, 0x36, + 0x68, 0xeb, 0x3d, 0xc8, 0x8c, 0x93, 0x03, 0xfa, 0x2f, 0xc8, 0x88, 0x73, 0x3e, 0x73, 0x4d, 0xea, + 0x61, 0xdc, 0x7e, 0xa8, 0xb0, 0xd2, 0x5c, 0xda, 0x74, 0x4f, 0x84, 0x8c, 0xeb, 0xa1, 0xb4, 0x67, + 0x2b, 0x3c, 0xf1, 0x1d, 0xae, 0x92, 0xc2, 0x86, 0xe8, 0x58, 0x95, 0x14, 0x29, 0xfa, 0x0e, 0xac, + 0x5d, 0xe2, 0x22, 0x44, 0xa6, 0xd0, 0x9c, 0x26, 0x62, 0xf3, 0xfe, 0xf5, 0x68, 0x6e, 0x82, 0xe3, + 0xf4, 0xdf, 0x47, 0x21, 0x39, 0xa4, 0xa8, 0x2b, 0xa4, 0xf6, 0x25, 0xc8, 0xf0, 0x95, 0x6d, 0x31, + 0x86, 0x3b, 0x61, 0x17, 0x57, 0x87, 0x52, 0xb1, 0xe0, 0x0f, 0x83, 0x6a, 0x17, 0xbb, 0x46, 0xb5, + 0x0b, 0x6a, 0xdd, 0x47, 0xa3, 0x15, 0x13, 0x17, 0x51, 0xf9, 0xca, 0x95, 0x49, 0x79, 0x62, 0xd9, + 0xfc, 0x4e, 0x1b, 0xae, 0x9b, 0xe9, 0xc1, 0xb8, 0x80, 0x35, 0xd7, 0xc3, 0x0e, 0x5f, 0xca, 0xa6, + 0xba, 0x5a, 0xc9, 0x0a, 0x7e, 0x7c, 0x5d, 0x23, 0x0a, 0x75, 0x0f, 0x3b, 0xa7, 0x3e, 0x29, 0x0b, + 0x54, 0x63, 0xd5, 0x0d, 0x37, 0xf5, 0x17, 0x60, 0x75, 0xac, 0x1f, 0x65, 0x21, 0x3a, 0x22, 0x08, + 0xfe, 0xa9, 0xe7, 0x01, 0x42, 0x5c, 0x3c, 0xd5, 0x7c, 0xfd, 0x1c, 0x52, 0xa1, 0xa2, 0x81, 0xbe, + 0x3e, 0x5e, 0x86, 0xb4, 0xc5, 0x8e, 0xfc, 0x93, 0x65, 0x68, 0xac, 0x06, 0xe9, 0x0d, 0x58, 0x9f, + 0x28, 0x1c, 0xe8, 0x15, 0xc8, 0x76, 0xf8, 0xa7, 0x23, 0x9e, 0x32, 0xcc, 0xd0, 0xc1, 0x72, 0x2d, + 0x24, 0x17, 0x87, 0x39, 0xe5, 0x62, 0x64, 0xe4, 0xe2, 0x97, 0x11, 0x80, 0x51, 0x79, 0x78, 0x4c, + 0x8a, 0x4e, 0x21, 0x4e, 0x18, 0xee, 0x49, 0x1a, 0xbb, 0xc2, 0xd1, 0x60, 0xa4, 0xa0, 0x50, 0x65, + 0xb8, 0x67, 0x48, 0x34, 0xfd, 0x4f, 0x1a, 0xc4, 0x78, 0x1b, 0x19, 0x10, 0x13, 0x17, 0x24, 0xed, + 0x6a, 0xb5, 0x47, 0x42, 0x73, 0x24, 0x71, 0x49, 0x12, 0x58, 0x23, 0x4f, 0x22, 0x61, 0x4f, 0x36, + 0x21, 0xd5, 0xc1, 0xb4, 0xed, 0x13, 0x4f, 0x2c, 0xb4, 0x80, 0x3d, 0x46, 0xa2, 0x27, 0xba, 0xb1, + 0xf4, 0x3f, 0x44, 0x20, 0x33, 0x5e, 0x19, 0xd1, 0x83, 0x20, 0x96, 0x72, 0x69, 0xec, 0x5e, 0xaf, + 0xd0, 0xfe, 0x87, 0xc5, 0xf3, 0x7d, 0xc8, 0x8c, 0x1b, 0xc7, 0x57, 0xf4, 0x39, 0x1e, 0x04, 0x9b, + 0xf6, 0x1c, 0x0f, 0x04, 0xb9, 0x0e, 0x1c, 0xd7, 0x19, 0xf4, 0x82, 0xb2, 0x3b, 0x6c, 0xe7, 0x7f, + 0xa4, 0x41, 0x22, 0x38, 0x45, 0xa0, 0x1c, 0xdc, 0xe0, 0xb7, 0xb3, 0xfd, 0xba, 0x71, 0x74, 0xe9, + 0x1e, 0x97, 0x86, 0xc4, 0x7e, 0x79, 0xb7, 0xb2, 0x53, 0xaf, 0x1f, 0x66, 0x35, 0x94, 0x84, 0xf8, + 0x49, 0xad, 0xbc, 0x7b, 0x98, 0x8d, 0xc8, 0x3b, 0x5d, 0xad, 0x72, 0xd7, 0x28, 0x1f, 0x65, 0xa3, + 0x68, 0x05, 0xa2, 0x87, 0xd5, 0xc3, 0x6c, 0x4c, 0x8c, 0x38, 0x7c, 0xd0, 0xa8, 0x64, 0xe3, 0x28, + 0x01, 0xb1, 0x5a, 0xf5, 0xb8, 0x92, 0x5d, 0xe6, 0xc2, 0xfb, 0xd5, 0x9d, 0x8a, 0x91, 0x5d, 0x41, + 0x4f, 0xc1, 0x7a, 0x79, 0xb7, 0x59, 0xad, 0x1f, 0x9f, 0x98, 0xf5, 0x63, 0xf3, 0x6e, 0xbd, 0x7e, + 0xb7, 0x56, 0xc9, 0x26, 0x76, 0x92, 0xb0, 0xa2, 0x5e, 0x49, 0xf4, 0xef, 0x6b, 0x80, 0x26, 0xef, + 0xfb, 0xe8, 0x7f, 0x27, 0x5f, 0x12, 0x42, 0xdb, 0xfb, 0xd2, 0x6b, 0xc0, 0x3c, 0x4f, 0x17, 0x91, + 0x7f, 0xfe, 0x74, 0x91, 0x67, 0x90, 0x0e, 0x3f, 0x12, 0xa2, 0xe7, 0xe0, 0xd6, 0x87, 0x95, 0x9d, + 0x83, 0x7a, 0xfd, 0xd0, 0x3c, 0x69, 0x96, 0x9b, 0x97, 0x2f, 0xbc, 0xb7, 0xe0, 0xa9, 0xf1, 0xee, + 0xca, 0x71, 0x79, 0xa7, 0x56, 0xd9, 0xcb, 0x6a, 0x68, 0x1b, 0x5e, 0x9e, 0xda, 0x65, 0xee, 0xd7, + 0x0d, 0xf3, 0xa4, 0x56, 0x6f, 0x9a, 0xfb, 0xd5, 0x5a, 0xad, 0x7a, 0x7c, 0x37, 0x1b, 0xc9, 0x7f, + 0xa9, 0x01, 0xe2, 0x1c, 0x21, 0x0d, 0xa1, 0x06, 0xfe, 0xb8, 0x8f, 0x29, 0x43, 0x37, 0x61, 0x59, + 0x1a, 0xaa, 0xfc, 0x55, 0x2d, 0x7e, 0xba, 0xb2, 0x2d, 0xa7, 0xdb, 0xe7, 0x07, 0xa0, 0xb6, 0xdb, + 0x09, 0xbc, 0x4a, 0x07, 0xc2, 0x5d, 0xb7, 0x83, 0x51, 0x0d, 0x52, 0xca, 0xf1, 0x0b, 0x82, 0x1f, + 0x89, 0x95, 0x99, 0x29, 0xfd, 0xcf, 0x9c, 0xab, 0xef, 0x3e, 0xc1, 0x8f, 0x0c, 0x20, 0xc3, 0x6f, + 0x7e, 0xe0, 0xf2, 0xb8, 0x3a, 0x4a, 0x3e, 0xc5, 0xea, 0x45, 0x22, 0xc1, 0x05, 0x27, 0xe4, 0x53, + 0x1e, 0x24, 0x10, 0x9d, 0xcc, 0x3d, 0xc7, 0x8e, 0xba, 0x4d, 0x8b, 0xe1, 0x4d, 0x2e, 0xc8, 0x7f, + 0x57, 0x83, 0x8d, 0x31, 0xef, 0xd4, 0x21, 0xa8, 0x0c, 0x2b, 0x52, 0x43, 0xc0, 0x05, 0xff, 0x3d, + 0xa7, 0x75, 0x46, 0x30, 0x0f, 0xbd, 0x0c, 0x6b, 0x0e, 0x3f, 0x47, 0x85, 0xd4, 0xcb, 0x58, 0xac, + 0x72, 0x71, 0x63, 0x68, 0xc2, 0xcf, 0x35, 0xc8, 0xde, 0xc5, 0xca, 0x82, 0x20, 0xbc, 0xd3, 0x1e, + 0x21, 0xfe, 0xfd, 0xa1, 0xcd, 0xff, 0x59, 0x83, 0x8d, 0x5d, 0x1f, 0x5b, 0x0c, 0x8f, 0x9b, 0xf7, + 0xb8, 0xec, 0x7f, 0x00, 0xcb, 0x72, 0xb6, 0x3a, 0x26, 0xcc, 0x1d, 0x35, 0x35, 0x6d, 0xd2, 0xc7, + 0xe8, 0x6c, 0x1f, 0x63, 0xd7, 0xf3, 0xf1, 0x07, 0x11, 0xd8, 0x38, 0xf5, 0x3a, 0x13, 0x3e, 0x8e, + 0x7c, 0xd1, 0x9e, 0x90, 0x2f, 0xd3, 0xf2, 0x75, 0x07, 0x52, 0x7d, 0xa1, 0x5c, 0xfc, 0x56, 0xa1, + 0x1e, 0x32, 0xf4, 0x89, 0xd7, 0x81, 0x7d, 0x82, 0xed, 0xce, 0x91, 0x45, 0xcf, 0x0d, 0x90, 0xc3, + 0xf9, 0xf7, 0x13, 0x0e, 0xc4, 0x2b, 0xb0, 0xb1, 0x87, 0x6d, 0x7c, 0x39, 0x0e, 0x53, 0x96, 0x62, + 0xfe, 0xef, 0x11, 0xb8, 0xb5, 0x63, 0xb1, 0xf6, 0xc3, 0x70, 0xe0, 0x66, 0x72, 0xc3, 0x36, 0x64, + 0x95, 0xb9, 0x2d, 0x3e, 0xd7, 0x1c, 0x1e, 0x77, 0xf8, 0x95, 0x54, 0xf6, 0x48, 0x50, 0x9f, 0xa0, + 0x6f, 0xc2, 0xc6, 0xd8, 0x58, 0xe2, 0xd8, 0xc4, 0xc1, 0x2a, 0x3e, 0xaf, 0xce, 0xe9, 0xa2, 0x40, + 0xe3, 0x97, 0xf7, 0x10, 0x78, 0x55, 0x00, 0x4d, 0x26, 0x27, 0x36, 0x3b, 0x39, 0xf1, 0xeb, 0x24, + 0x67, 0xf9, 0x5a, 0xc9, 0xd9, 0xc9, 0x40, 0x3a, 0x1c, 0x8f, 0xbc, 0x09, 0xfa, 0xb4, 0x04, 0x3c, + 0x31, 0xfa, 0xca, 0x5f, 0xa8, 0x0c, 0x87, 0x97, 0xc4, 0xcc, 0x0c, 0x87, 0xf4, 0x46, 0xae, 0xa8, + 0xb7, 0x01, 0xa9, 0x50, 0xf2, 0x9e, 0x80, 0x27, 0xdb, 0x1f, 0x00, 0x54, 0xc3, 0xd5, 0xe2, 0xe9, + 0xea, 0x71, 0xb3, 0x72, 0xdc, 0x34, 0xef, 0x57, 0x2b, 0x1f, 0x5e, 0xaa, 0x99, 0x37, 0x20, 0x1b, + 0xee, 0xdc, 0x3f, 0xad, 0xd5, 0xb2, 0x5a, 0xe9, 0x8b, 0x24, 0xac, 0xa8, 0x00, 0xa0, 0xdf, 0x68, + 0x90, 0x0a, 0x15, 0x0c, 0xf4, 0xc6, 0x4c, 0x73, 0x26, 0x8b, 0xa7, 0xfe, 0xe6, 0x62, 0x93, 0x64, + 0x52, 0xf3, 0xa5, 0xef, 0xfd, 0xf1, 0x2f, 0x3f, 0x8d, 0xbc, 0x8a, 0xb6, 0x87, 0xbf, 0xa2, 0x7e, + 0x5b, 0x86, 0xfd, 0x3d, 0xcf, 0x77, 0xbf, 0x85, 0xdb, 0x8c, 0x16, 0xb7, 0x8b, 0x56, 0x17, 0x3b, + 0xec, 0xb3, 0x62, 0x50, 0x84, 0x7e, 0xa1, 0x41, 0x72, 0x58, 0x5c, 0xd0, 0xec, 0x9f, 0x9e, 0x2e, + 0x17, 0x22, 0x7d, 0xde, 0x70, 0x4f, 0xb3, 0x8e, 0x53, 0xc5, 0x84, 0x6d, 0x81, 0x69, 0xc5, 0xed, + 0xcf, 0xd0, 0xe7, 0x1a, 0xa4, 0xc3, 0xe5, 0x05, 0xcd, 0x0e, 0xcc, 0x94, 0x6a, 0x34, 0xbf, 0x8d, + 0xb7, 0x85, 0x8d, 0x6f, 0xe6, 0x17, 0x88, 0xe0, 0xed, 0x80, 0xcd, 0x7f, 0xab, 0x41, 0x3a, 0xbc, + 0xd9, 0xe6, 0xb0, 0x75, 0x4a, 0x55, 0x99, 0xdf, 0xd6, 0xb2, 0xb0, 0xf5, 0x4e, 0xe9, 0xf5, 0x91, + 0xad, 0xea, 0x17, 0xfa, 0x59, 0x61, 0x1d, 0x9a, 0xfc, 0x63, 0x0d, 0xd2, 0xe1, 0xed, 0x3b, 0x87, + 0xc9, 0x53, 0x0a, 0x80, 0x7e, 0x73, 0x82, 0xf0, 0x2a, 0x3d, 0x8f, 0x0d, 0x82, 0x8c, 0x6f, 0x2f, + 0x92, 0xf1, 0x2f, 0x34, 0x40, 0x93, 0xbc, 0x85, 0x66, 0x5f, 0xc2, 0x1f, 0x5b, 0x6d, 0xf4, 0xe7, + 0x82, 0xb9, 0xa1, 0x7f, 0x0f, 0x14, 0xea, 0xc1, 0xbf, 0x07, 0x82, 0x38, 0xe6, 0xdf, 0x5a, 0x20, + 0xe7, 0xad, 0x91, 0xb2, 0xdb, 0xda, 0xf6, 0xc8, 0xe8, 0x31, 0x2e, 0x9c, 0xd7, 0xe8, 0x69, 0x04, + 0xfa, 0x2f, 0x33, 0x5a, 0x2a, 0xbb, 0xad, 0x6d, 0xef, 0x7c, 0xae, 0xc1, 0x8b, 0x6d, 0xb7, 0x37, + 0xcb, 0xc6, 0x1d, 0xc5, 0xb6, 0x0d, 0x9e, 0xdb, 0x86, 0xf6, 0x51, 0x55, 0x8d, 0xef, 0xba, 0xbc, + 0x12, 0x16, 0x5c, 0xbf, 0x5b, 0xec, 0x62, 0x47, 0x64, 0xbe, 0x28, 0xbb, 0x2c, 0x8f, 0xd0, 0xc7, + 0xfe, 0xb1, 0xe3, 0xce, 0x48, 0xf4, 0x37, 0x4d, 0xfb, 0x65, 0x24, 0xb2, 0xb7, 0xff, 0xeb, 0xc8, + 0xf3, 0x77, 0x25, 0xe6, 0xae, 0xb0, 0x61, 0x6f, 0x64, 0xc3, 0x7d, 0x39, 0xa9, 0xb5, 0x2c, 0xf0, + 0xdf, 0xf8, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x20, 0xe1, 0xfe, 0xa4, 0x22, 0x00, 0x00, } diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session.pb.go index 39d33d3835..28e66c524d 100644 --- a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session.pb.go @@ -654,10 +654,14 @@ type StreamingDetectIntentRequest struct { // // 3. an event that specifies which intent to trigger. QueryInput *QueryInput `protobuf:"bytes,3,opt,name=query_input,json=queryInput" json:"query_input,omitempty"` - // Optional. If `true`, the recognizer will detect a single spoken utterance - // in input audio. When it detects that the user has paused or stopped - // speaking, it will cease recognition. This setting is ignored when - // `query_input` is a piece of text or an event. + // Optional. If `false` (default), recognition does not cease until the + // client closes the stream. + // If `true`, the recognizer will detect a single spoken utterance in input + // audio. Recognition ceases when it detects the audio's voice has + // stopped or paused. In this case, once a detected intent is received, the + // client should close the stream and start a new request with a new stream as + // needed. + // This setting is ignored when `query_input` is a piece of text or an event. SingleUtterance bool `protobuf:"varint,4,opt,name=single_utterance,json=singleUtterance" json:"single_utterance,omitempty"` // Optional. The input audio content to be recognized. Must be sent if // `query_input` was set to a streaming input audio config. The complete audio @@ -1149,104 +1153,106 @@ var _Sessions_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("google/cloud/dialogflow/v2beta1/session.proto", fileDescriptor4) } var fileDescriptor4 = []byte{ - // 1580 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0x3f, 0x73, 0x1b, 0xc7, - 0x15, 0xd7, 0x81, 0xff, 0x1f, 0x40, 0x12, 0x5e, 0xc9, 0xd6, 0x89, 0x94, 0x2c, 0x05, 0x1e, 0x4f, - 0x28, 0xc6, 0x01, 0x2c, 0x26, 0x71, 0xc6, 0xd6, 0xc8, 0x11, 0x08, 0x1c, 0x49, 0xcc, 0x80, 0x20, - 0xbc, 0x00, 0x2d, 0xdb, 0xcd, 0xce, 0xf2, 0xb0, 0x38, 0x9e, 0x72, 0xd8, 0x3d, 0xde, 0x2e, 0x6c, - 0xd3, 0x99, 0xa4, 0xc8, 0x57, 0x48, 0x97, 0x32, 0x4d, 0x66, 0xdc, 0xa6, 0x49, 0x93, 0xca, 0x1f, - 0x21, 0x75, 0xba, 0x94, 0x49, 0x95, 0x14, 0x99, 0x49, 0x93, 0xb9, 0xdd, 0x3d, 0x00, 0x02, 0x29, - 0x03, 0x4a, 0x52, 0xb9, 0xc3, 0xbe, 0xf7, 0x7b, 0x6f, 0xdf, 0x7b, 0xf7, 0x7b, 0xef, 0x2d, 0xe0, - 0x87, 0x81, 0x10, 0x41, 0xc4, 0x2a, 0x7e, 0x24, 0x86, 0xbd, 0x4a, 0x2f, 0xa4, 0x91, 0x08, 0xfa, - 0x91, 0xf8, 0xa2, 0xf2, 0xf9, 0xde, 0x19, 0x53, 0xf4, 0x51, 0x45, 0x32, 0x29, 0x43, 0xc1, 0xcb, - 0x71, 0x22, 0x94, 0x40, 0xf7, 0x0d, 0xbc, 0xac, 0xe1, 0xe5, 0x31, 0xbc, 0x6c, 0xe1, 0x5b, 0x77, - 0xad, 0x3f, 0x1a, 0x87, 0x15, 0xca, 0xb9, 0x50, 0x54, 0x85, 0x82, 0x4b, 0x63, 0xbe, 0x35, 0xf3, - 0x36, 0x5f, 0x70, 0xc5, 0xbe, 0x54, 0x16, 0xfe, 0xce, 0x2c, 0x78, 0xc8, 0x15, 0xe3, 0x19, 0xfa, - 0xfd, 0x39, 0x53, 0x21, 0x8c, 0xab, 0x50, 0x5d, 0x12, 0x75, 0x19, 0x33, 0x6b, 0x9a, 0x45, 0xad, - 0x4f, 0x67, 0xc3, 0x7e, 0x45, 0xaa, 0x64, 0xe8, 0x67, 0x8e, 0x6f, 0x5b, 0x6d, 0x12, 0xfb, 0x15, - 0xa9, 0xa8, 0x1a, 0x66, 0xe9, 0xb8, 0x56, 0x91, 0x7a, 0xaa, 0x44, 0x54, 0x45, 0x3c, 0x30, 0x9a, - 0xd2, 0x3f, 0x1c, 0xb8, 0x59, 0x67, 0x8a, 0xf9, 0xaa, 0xa1, 0x43, 0xc4, 0xec, 0x62, 0xc8, 0xa4, - 0x42, 0x2e, 0xac, 0xd8, 0x28, 0x5c, 0xe7, 0x81, 0xb3, 0xb3, 0x86, 0xb3, 0x23, 0xea, 0x40, 0xe1, - 0x62, 0xc8, 0x92, 0x4b, 0x12, 0xd3, 0x84, 0x0e, 0xa4, 0x9b, 0x7b, 0xe0, 0xec, 0xe4, 0xf7, 0xde, - 0x2d, 0xcf, 0x28, 0x78, 0xf9, 0xa3, 0xd4, 0xa8, 0x9d, 0xda, 0x30, 0xc5, 0x12, 0x89, 0xf3, 0x17, - 0x23, 0x81, 0x44, 0x4d, 0x30, 0x47, 0x12, 0xf2, 0x78, 0xa8, 0xdc, 0x05, 0xed, 0xf3, 0x07, 0xf3, - 0xf9, 0x6c, 0xa4, 0x26, 0x18, 0x2e, 0x46, 0xbf, 0xd1, 0x7d, 0xc8, 0x6b, 0x3f, 0x84, 0x0e, 0x7b, - 0xa1, 0x70, 0x97, 0x1e, 0x38, 0x3b, 0x05, 0x0c, 0x5a, 0x54, 0x4d, 0x25, 0xa5, 0x6f, 0x1c, 0xb8, - 0xf5, 0x62, 0xd6, 0x32, 0x16, 0x5c, 0xb2, 0xd4, 0x32, 0xb1, 0xbf, 0x49, 0xd8, 0xb3, 0xa9, 0x43, - 0x26, 0x6a, 0xf4, 0xd0, 0x49, 0x96, 0x7d, 0xc2, 0xe4, 0x30, 0x52, 0x36, 0xfb, 0x77, 0xe6, 0x8b, - 0x14, 0x6b, 0x1b, 0x9b, 0xb9, 0x39, 0xa0, 0xf7, 0x61, 0xe3, 0x0b, 0x76, 0x76, 0x2e, 0xc4, 0xcf, - 0x89, 0xf9, 0x64, 0x36, 0x79, 0x94, 0xb9, 0x4c, 0x62, 0xbf, 0xdc, 0xd1, 0x1a, 0xbc, 0x6e, 0x91, - 0xe6, 0x58, 0xfa, 0x5b, 0x0e, 0x36, 0xa7, 0xaa, 0x8a, 0xb6, 0x61, 0x4d, 0x85, 0x03, 0x46, 0xbe, - 0x12, 0x9c, 0xd9, 0xf0, 0x57, 0x53, 0xc1, 0x67, 0x82, 0x33, 0xf4, 0x1e, 0x14, 0x02, 0x26, 0x48, - 0x24, 0x7c, 0x4d, 0x76, 0x1b, 0xfc, 0xcd, 0xec, 0x26, 0xcd, 0xb3, 0x26, 0x55, 0x4d, 0x1e, 0xe0, - 0x7c, 0xc0, 0x44, 0xd3, 0xe2, 0x50, 0x1d, 0x56, 0x2d, 0xdf, 0xd3, 0xe8, 0x16, 0x76, 0xf2, 0x7b, - 0x3b, 0x33, 0x13, 0xae, 0x19, 0x03, 0x3c, 0xb2, 0x44, 0x6f, 0xc3, 0x46, 0xc2, 0x24, 0x53, 0x64, - 0xe4, 0x6b, 0xf1, 0x81, 0xb3, 0xb3, 0x8a, 0xd7, 0xb5, 0xb4, 0x96, 0xc1, 0x7a, 0x70, 0xeb, 0x1a, - 0xfe, 0x4b, 0x77, 0x49, 0x5f, 0xbc, 0x37, 0xf3, 0xe2, 0x8e, 0x31, 0xf6, 0xb4, 0x6d, 0xf7, 0x32, - 0x66, 0x18, 0xc9, 0x69, 0x91, 0x44, 0x8f, 0x60, 0x25, 0xa6, 0x97, 0x91, 0xa0, 0x3d, 0x77, 0x59, - 0x57, 0xe1, 0x76, 0xe6, 0x38, 0x6b, 0xad, 0x72, 0x47, 0xb7, 0x16, 0xce, 0x70, 0xa5, 0x7f, 0x3a, - 0x00, 0x63, 0xc2, 0xa1, 0x8f, 0xa1, 0xa0, 0xe9, 0x95, 0xa6, 0xd3, 0x0f, 0x03, 0x5d, 0xec, 0xfc, - 0xde, 0xa3, 0x99, 0xf1, 0x35, 0x46, 0x34, 0xac, 0x69, 0xc3, 0xa3, 0x1b, 0x38, 0x4f, 0xc7, 0x47, - 0xf4, 0x14, 0x16, 0xd3, 0x42, 0xd8, 0x8f, 0xb3, 0x3b, 0xd3, 0x5f, 0x97, 0x7d, 0xa9, 0xb4, 0xcf, - 0xa3, 0x1b, 0x58, 0x5b, 0xa2, 0x1a, 0x2c, 0xb1, 0xcf, 0x19, 0x9f, 0xbf, 0x8d, 0xbc, 0x14, 0x9d, - 0xf9, 0x30, 0xb6, 0xfb, 0x2b, 0xb0, 0xa4, 0x1b, 0xa6, 0xf4, 0x87, 0x65, 0xc8, 0x4f, 0xb0, 0x17, - 0xdd, 0x03, 0xd3, 0x6a, 0x44, 0x47, 0x69, 0x28, 0xb6, 0xa6, 0x25, 0x69, 0x24, 0xe8, 0x2d, 0x58, - 0x8f, 0x28, 0x0f, 0x86, 0x34, 0x60, 0xc4, 0x17, 0x3d, 0xe6, 0x6e, 0x6a, 0x44, 0x21, 0x13, 0xd6, - 0x44, 0x8f, 0xa1, 0x7d, 0xb8, 0x27, 0x63, 0xc6, 0xfc, 0x73, 0x92, 0x30, 0x5f, 0x04, 0x3c, 0x4c, - 0x69, 0x66, 0x0a, 0xd9, 0x63, 0xdc, 0x67, 0x3a, 0xf9, 0x1c, 0xde, 0x36, 0x20, 0x3c, 0xc6, 0xd4, - 0x46, 0x10, 0xf4, 0x06, 0x2c, 0x53, 0x5f, 0xd3, 0x78, 0x41, 0xdf, 0x60, 0x4f, 0xe8, 0xa7, 0x00, - 0xf1, 0xa8, 0x1f, 0x34, 0xc5, 0xbe, 0xe5, 0xe3, 0x4e, 0x40, 0xd1, 0x13, 0xd8, 0xa6, 0x51, 0x44, - 0x12, 0x76, 0x31, 0x0c, 0x13, 0xd6, 0xb3, 0xf3, 0x8d, 0xc4, 0x29, 0x3d, 0xb9, 0xd2, 0x53, 0x64, - 0x15, 0xbb, 0x34, 0x8a, 0xb0, 0x45, 0x98, 0xd9, 0xd5, 0x36, 0x7a, 0xf4, 0x10, 0x8a, 0xfd, 0x61, - 0xd4, 0x0f, 0xa3, 0x68, 0xc0, 0xb8, 0x32, 0xd5, 0x59, 0xd6, 0x91, 0x6d, 0x4e, 0xc8, 0x75, 0x8d, - 0xce, 0xe0, 0xd6, 0x24, 0x74, 0xc0, 0xa4, 0xa4, 0x01, 0x93, 0xee, 0x8a, 0xa6, 0x78, 0x65, 0x0e, - 0x0a, 0xe9, 0x6d, 0x72, 0x6c, 0xec, 0xf0, 0xcd, 0x09, 0x67, 0x56, 0xa6, 0xbb, 0x6d, 0x34, 0x57, - 0xc4, 0x30, 0xf1, 0x99, 0xbb, 0xaa, 0x83, 0x19, 0xcd, 0x10, 0x2d, 0x44, 0x4f, 0x61, 0x33, 0x83, - 0x65, 0xfd, 0xb0, 0xf6, 0xed, 0x25, 0xcb, 0xdc, 0xb6, 0x0d, 0x1c, 0x7d, 0x04, 0x9b, 0x62, 0xa8, - 0xd2, 0x69, 0x3b, 0xea, 0x6b, 0x78, 0xc5, 0x19, 0xb1, 0x61, 0x1c, 0x8c, 0x46, 0xc0, 0xcf, 0x60, - 0xd9, 0x2c, 0x4c, 0x37, 0xaf, 0x63, 0xf9, 0xfe, 0x9c, 0x15, 0xc1, 0xd6, 0x0c, 0x7d, 0x08, 0xdb, - 0xe6, 0x17, 0xe9, 0xe9, 0x29, 0x3f, 0xc5, 0xae, 0x82, 0x66, 0xd7, 0x1d, 0x03, 0xa9, 0x67, 0x88, - 0x09, 0x6e, 0x3d, 0x85, 0xcd, 0x5e, 0x48, 0x03, 0x2e, 0xa4, 0x0a, 0x7d, 0x12, 0xf2, 0xbe, 0x70, - 0x37, 0x66, 0x54, 0x65, 0x8c, 0x6f, 0xf0, 0xbe, 0x28, 0xfd, 0x3e, 0x07, 0x77, 0x3b, 0x2a, 0x61, - 0x74, 0x10, 0xf2, 0xe0, 0x3b, 0xb7, 0x60, 0x1f, 0x42, 0x51, 0x86, 0x3c, 0x88, 0x18, 0x19, 0x2a, - 0xc5, 0x12, 0x9a, 0x16, 0xd5, 0x0c, 0xf3, 0x4d, 0x23, 0x3f, 0xcd, 0xc4, 0xd3, 0xbb, 0x78, 0xf9, - 0xca, 0x2e, 0xfe, 0x63, 0x0e, 0xee, 0xbd, 0xa4, 0x52, 0xf3, 0x2e, 0xe5, 0xe7, 0x80, 0x26, 0xe7, - 0xc8, 0x0b, 0xab, 0xf9, 0xf1, 0xec, 0x85, 0x91, 0x5d, 0x3e, 0x31, 0x67, 0xec, 0xa6, 0x7e, 0x2d, - 0x99, 0x16, 0x5d, 0x79, 0x00, 0x2c, 0xfc, 0xff, 0x1f, 0x00, 0x8b, 0xf3, 0x3e, 0x00, 0xfe, 0x94, - 0x83, 0xad, 0x97, 0x47, 0x8f, 0x9e, 0x43, 0xc1, 0x8e, 0x16, 0xbd, 0x42, 0x75, 0xe1, 0x36, 0xf6, - 0x0e, 0xff, 0x87, 0x82, 0x64, 0x23, 0x47, 0xaf, 0xd5, 0xfc, 0x60, 0x7c, 0x40, 0x6f, 0x02, 0xa8, - 0x84, 0x72, 0xe9, 0x27, 0x61, 0x6c, 0x4a, 0xbf, 0x86, 0x27, 0x24, 0xe8, 0x0e, 0xac, 0x86, 0x92, - 0xf4, 0x43, 0x4e, 0x23, 0x5d, 0xb2, 0x55, 0xbc, 0x12, 0xca, 0x83, 0xf4, 0x98, 0x9a, 0x4e, 0xf4, - 0xe6, 0xa2, 0xee, 0xcd, 0x09, 0x49, 0xe9, 0x13, 0xc8, 0x4f, 0x5c, 0x8b, 0xee, 0x82, 0x7b, 0xec, - 0x75, 0x3a, 0xd5, 0x43, 0x8f, 0x74, 0x3f, 0x6d, 0x7b, 0xe4, 0xb4, 0xd5, 0x69, 0x7b, 0xb5, 0xc6, - 0x41, 0xc3, 0xab, 0x17, 0x6f, 0xa0, 0x0d, 0x80, 0x2e, 0xae, 0xb6, 0x3a, 0x35, 0xdc, 0x68, 0x77, - 0x8b, 0x0e, 0xda, 0x86, 0xdb, 0x5e, 0xab, 0x4e, 0x4e, 0x0e, 0x48, 0xa7, 0xd1, 0x3a, 0x6c, 0x7a, - 0xe4, 0xb4, 0xdb, 0xf5, 0x70, 0xb5, 0x55, 0xf3, 0x8a, 0xb9, 0xd2, 0x5f, 0x1c, 0x28, 0x4e, 0xaf, - 0x63, 0x74, 0x0a, 0x1b, 0x66, 0xaf, 0x33, 0xee, 0x8b, 0x5e, 0xc8, 0x03, 0x5b, 0xb7, 0xf2, 0xcc, - 0xba, 0x69, 0x2f, 0x9e, 0xb5, 0xc2, 0xeb, 0x74, 0xf2, 0x88, 0x76, 0xe1, 0x35, 0x49, 0x07, 0x71, - 0xc4, 0x48, 0x42, 0x15, 0x23, 0xe7, 0x2c, 0x51, 0x5f, 0xe9, 0x3a, 0x2d, 0xe1, 0x4d, 0xa3, 0xc0, - 0x54, 0xb1, 0xa3, 0x54, 0x7c, 0x75, 0x87, 0x2e, 0x5c, 0xb3, 0x43, 0xbf, 0x07, 0x85, 0xf8, 0x3c, - 0xa1, 0x92, 0x91, 0xf3, 0x90, 0xeb, 0xc7, 0xd4, 0xc2, 0xce, 0x1a, 0xce, 0x1b, 0xd9, 0x51, 0x2a, - 0x2a, 0xd5, 0x61, 0x6d, 0xf4, 0x3a, 0x40, 0xc8, 0xbe, 0x2b, 0x4c, 0xfb, 0x98, 0x97, 0xc2, 0x95, - 0x8b, 0x72, 0x57, 0x2f, 0x2a, 0xfd, 0x0a, 0x60, 0xfc, 0x40, 0x48, 0xdd, 0x70, 0x3a, 0xc8, 0xde, - 0x96, 0xfa, 0xf7, 0xd4, 0xca, 0xcd, 0xcd, 0xbf, 0x72, 0xe7, 0x49, 0x74, 0xf7, 0xdf, 0x0e, 0xac, - 0xbf, 0x50, 0x5a, 0xf4, 0x26, 0x6c, 0x55, 0x4f, 0xeb, 0x8d, 0x13, 0xe2, 0xb5, 0x6a, 0x27, 0xf5, - 0x46, 0xeb, 0x70, 0x8a, 0x04, 0x77, 0xc1, 0x9d, 0xd2, 0x37, 0x1b, 0x2d, 0xaf, 0x8a, 0xc9, 0xa3, - 0xf7, 0x8a, 0x0e, 0xba, 0x0d, 0x37, 0xa7, 0xb4, 0x07, 0xcd, 0x6a, 0xad, 0x98, 0x43, 0x2e, 0xdc, - 0x9a, 0x52, 0x1c, 0x9f, 0x36, 0xab, 0xcf, 0x8a, 0x0b, 0xe8, 0x0d, 0x40, 0x53, 0x9a, 0xea, 0x31, - 0x2e, 0x2e, 0xa2, 0x3b, 0xf0, 0xfa, 0x55, 0x39, 0x79, 0xb6, 0x5f, 0x5c, 0x4a, 0x89, 0x37, 0xa5, - 0x3a, 0x39, 0x3c, 0x24, 0x27, 0xed, 0xd3, 0x4e, 0x71, 0x19, 0x3d, 0x84, 0xb7, 0xa7, 0x94, 0x9d, - 0xb6, 0xe7, 0x7d, 0x42, 0x9e, 0x35, 0xba, 0x47, 0xe4, 0xc8, 0xab, 0xd6, 0x3d, 0x4c, 0xf6, 0x3f, - 0xed, 0x7a, 0xc5, 0x95, 0xbd, 0xbf, 0xe7, 0x60, 0xd5, 0x3e, 0x69, 0x25, 0xfa, 0xc6, 0x81, 0xc2, - 0xe4, 0x88, 0x44, 0x3f, 0x9e, 0x49, 0xca, 0x6b, 0x76, 0xcf, 0xd6, 0x4f, 0x5e, 0xd1, 0xca, 0x0c, - 0xda, 0xd2, 0xc1, 0xaf, 0xff, 0xfc, 0xd7, 0xdf, 0xe4, 0x9e, 0x96, 0x1e, 0x8f, 0xfe, 0xa8, 0xfe, - 0xc2, 0xee, 0xac, 0x27, 0x71, 0x22, 0x9e, 0x33, 0x5f, 0xc9, 0xca, 0x6e, 0x85, 0x06, 0x8c, 0xab, - 0xec, 0x2f, 0xac, 0xac, 0xec, 0xfe, 0xf2, 0x83, 0xde, 0x84, 0xb3, 0x0f, 0x9c, 0x5d, 0xf4, 0x5b, - 0x07, 0x5e, 0xbf, 0x76, 0xe2, 0xa3, 0x27, 0xf3, 0xcf, 0xa6, 0xeb, 0xf2, 0xfa, 0xf0, 0xbf, 0x35, - 0x37, 0x09, 0xee, 0x38, 0xef, 0x3a, 0xfb, 0x5f, 0x3b, 0xf0, 0x96, 0x2f, 0x06, 0xb3, 0x3c, 0xed, - 0x17, 0xec, 0x47, 0x69, 0xa7, 0xf4, 0x6e, 0x3b, 0x9f, 0x35, 0xac, 0x41, 0x20, 0x52, 0xf2, 0x96, - 0x45, 0x12, 0x54, 0x02, 0xc6, 0x35, 0xf9, 0x2b, 0x46, 0x45, 0xe3, 0x50, 0xbe, 0xf4, 0x3f, 0xff, - 0xe3, 0xb1, 0xe8, 0x5f, 0x8e, 0xf3, 0xbb, 0x5c, 0xae, 0x7e, 0xf0, 0x75, 0xee, 0xfe, 0xa1, 0xf1, - 0x59, 0xd3, 0x41, 0xd4, 0xc7, 0x41, 0x7c, 0x6c, 0x8c, 0xce, 0x96, 0xb5, 0xff, 0x1f, 0xfd, 0x27, - 0x00, 0x00, 0xff, 0xff, 0x78, 0xce, 0xe5, 0x99, 0x1d, 0x11, 0x00, 0x00, + // 1601 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcd, 0x73, 0x23, 0x47, + 0x15, 0xdf, 0x91, 0xbf, 0x9f, 0x64, 0x5b, 0xe9, 0xdd, 0x64, 0x67, 0xed, 0xdd, 0xec, 0xa2, 0x54, + 0x0a, 0xaf, 0x09, 0x52, 0xd6, 0x40, 0xa8, 0x64, 0x6b, 0xc3, 0xca, 0xd2, 0xd8, 0x56, 0xe1, 0xb5, + 0x95, 0x96, 0x9c, 0x4d, 0xf6, 0xd2, 0xd5, 0x1e, 0xb5, 0xc6, 0xb3, 0x8c, 0xba, 0xc7, 0xd3, 0x3d, + 0x49, 0x1c, 0x0a, 0x0e, 0xdc, 0xb9, 0x00, 0x27, 0x8e, 0x5c, 0xa8, 0xca, 0x95, 0x0b, 0x07, 0x38, + 0xf1, 0x27, 0x70, 0xe6, 0xc6, 0x91, 0x1b, 0x1c, 0xa8, 0xe2, 0x42, 0x4d, 0x77, 0x8f, 0xa4, 0x95, + 0xbd, 0x2b, 0x05, 0x38, 0x71, 0x53, 0xbf, 0xf7, 0x7b, 0xaf, 0xdf, 0xfb, 0xcd, 0xfb, 0x68, 0x1b, + 0xbe, 0x1d, 0x08, 0x11, 0x44, 0xac, 0xe6, 0x47, 0x22, 0xed, 0xd5, 0x7a, 0x21, 0x8d, 0x44, 0xd0, + 0x8f, 0xc4, 0xe7, 0xb5, 0xcf, 0x76, 0x4e, 0x99, 0xa2, 0x0f, 0x6a, 0x92, 0x49, 0x19, 0x0a, 0x5e, + 0x8d, 0x13, 0xa1, 0x04, 0xba, 0x6b, 0xe0, 0x55, 0x0d, 0xaf, 0x8e, 0xe0, 0x55, 0x0b, 0xdf, 0xb8, + 0x6d, 0xfd, 0xd1, 0x38, 0xac, 0x51, 0xce, 0x85, 0xa2, 0x2a, 0x14, 0x5c, 0x1a, 0xf3, 0x8d, 0xa9, + 0xb7, 0xf9, 0x82, 0x2b, 0xf6, 0x85, 0xb2, 0xf0, 0x77, 0xa6, 0xc1, 0x43, 0xae, 0x18, 0xcf, 0xd1, + 0xef, 0xcf, 0x98, 0x0a, 0x61, 0x5c, 0x85, 0xea, 0x82, 0xa8, 0x8b, 0x98, 0x59, 0xd3, 0x3c, 0x6a, + 0x7d, 0x3a, 0x4d, 0xfb, 0x35, 0xa9, 0x92, 0xd4, 0xcf, 0x1d, 0xdf, 0xb4, 0xda, 0x24, 0xf6, 0x6b, + 0x52, 0x51, 0x95, 0xe6, 0xe9, 0xb8, 0x56, 0x91, 0x79, 0xaa, 0x45, 0x54, 0x45, 0x3c, 0x30, 0x9a, + 0xca, 0xdf, 0x1d, 0xb8, 0xde, 0x64, 0x8a, 0xf9, 0xaa, 0xa5, 0x43, 0xc4, 0xec, 0x3c, 0x65, 0x52, + 0x21, 0x17, 0x96, 0x6c, 0x14, 0xae, 0x73, 0xcf, 0xd9, 0x5a, 0xc1, 0xf9, 0x11, 0x75, 0xa0, 0x74, + 0x9e, 0xb2, 0xe4, 0x82, 0xc4, 0x34, 0xa1, 0x03, 0xe9, 0x16, 0xee, 0x39, 0x5b, 0xc5, 0x9d, 0x77, + 0xab, 0x53, 0x08, 0xaf, 0x7e, 0x94, 0x19, 0xb5, 0x33, 0x1b, 0xa6, 0x58, 0x22, 0x71, 0xf1, 0x7c, + 0x28, 0x90, 0xe8, 0x10, 0xcc, 0x91, 0x84, 0x3c, 0x4e, 0x95, 0x3b, 0xa7, 0x7d, 0x7e, 0x6b, 0x36, + 0x9f, 0xad, 0xcc, 0x04, 0xc3, 0xf9, 0xf0, 0x37, 0xba, 0x0b, 0x45, 0xed, 0x87, 0xd0, 0xb4, 0x17, + 0x0a, 0x77, 0xe1, 0x9e, 0xb3, 0x55, 0xc2, 0xa0, 0x45, 0xf5, 0x4c, 0x52, 0xf9, 0x93, 0x03, 0x37, + 0x5e, 0xcc, 0x5a, 0xc6, 0x82, 0x4b, 0x96, 0x59, 0x26, 0xf6, 0x37, 0x09, 0x7b, 0x36, 0x75, 0xc8, + 0x45, 0xad, 0x1e, 0x3a, 0xce, 0xb3, 0x4f, 0x98, 0x4c, 0x23, 0x65, 0xb3, 0x7f, 0x67, 0xb6, 0x48, + 0xb1, 0xb6, 0xb1, 0x99, 0x9b, 0x03, 0x7a, 0x1f, 0xd6, 0x3e, 0x67, 0xa7, 0x67, 0x42, 0xfc, 0x88, + 0x98, 0x4f, 0x66, 0x93, 0x47, 0xb9, 0xcb, 0x24, 0xf6, 0xab, 0x1d, 0xad, 0xc1, 0xab, 0x16, 0x69, + 0x8e, 0x95, 0xbf, 0x15, 0x60, 0x7d, 0x82, 0x55, 0xb4, 0x09, 0x2b, 0x2a, 0x1c, 0x30, 0xf2, 0xa5, + 0xe0, 0xcc, 0x86, 0xbf, 0x9c, 0x09, 0x9e, 0x09, 0xce, 0xd0, 0x7b, 0x50, 0x0a, 0x98, 0x20, 0x91, + 0xf0, 0x75, 0xb1, 0xdb, 0xe0, 0xaf, 0xe7, 0x37, 0xe9, 0x3a, 0x3b, 0xa4, 0xea, 0x90, 0x07, 0xb8, + 0x18, 0x30, 0x71, 0x68, 0x71, 0xa8, 0x09, 0xcb, 0xb6, 0xde, 0xb3, 0xe8, 0xe6, 0xb6, 0x8a, 0x3b, + 0x5b, 0x53, 0x13, 0x6e, 0x18, 0x03, 0x3c, 0xb4, 0x44, 0x6f, 0xc3, 0x5a, 0xc2, 0x24, 0x53, 0x64, + 0xe8, 0x6b, 0xfe, 0x9e, 0xb3, 0xb5, 0x8c, 0x57, 0xb5, 0xb4, 0x91, 0xc3, 0x7a, 0x70, 0xe3, 0x8a, + 0xfa, 0x97, 0xee, 0x82, 0xbe, 0x78, 0x67, 0xea, 0xc5, 0x1d, 0x63, 0xec, 0x69, 0xdb, 0xee, 0x45, + 0xcc, 0x30, 0x92, 0x93, 0x22, 0x89, 0x1e, 0xc0, 0x52, 0x4c, 0x2f, 0x22, 0x41, 0x7b, 0xee, 0xa2, + 0x66, 0xe1, 0x66, 0xee, 0x38, 0x6f, 0xad, 0x6a, 0x47, 0xb7, 0x16, 0xce, 0x71, 0x95, 0x7f, 0x38, + 0x00, 0xa3, 0x82, 0x43, 0x1f, 0x43, 0x49, 0x97, 0x57, 0x96, 0x4e, 0x3f, 0x0c, 0x34, 0xd9, 0xc5, + 0x9d, 0x07, 0x53, 0xe3, 0x6b, 0x0d, 0xcb, 0xb0, 0xa1, 0x0d, 0x0f, 0xae, 0xe1, 0x22, 0x1d, 0x1d, + 0xd1, 0x63, 0x98, 0xcf, 0x88, 0xb0, 0x1f, 0x67, 0x7b, 0xaa, 0xbf, 0x2e, 0xfb, 0x42, 0x69, 0x9f, + 0x07, 0xd7, 0xb0, 0xb6, 0x44, 0x0d, 0x58, 0x60, 0x9f, 0x31, 0x3e, 0x7b, 0x1b, 0x79, 0x19, 0x3a, + 0xf7, 0x61, 0x6c, 0x77, 0x97, 0x60, 0x41, 0x37, 0x4c, 0xe5, 0x77, 0x8b, 0x50, 0x1c, 0xab, 0x5e, + 0x74, 0x07, 0x4c, 0xab, 0x11, 0x1d, 0xa5, 0x29, 0xb1, 0x15, 0x2d, 0xc9, 0x22, 0x41, 0x6f, 0xc1, + 0x6a, 0x44, 0x79, 0x90, 0xd2, 0x80, 0x11, 0x5f, 0xf4, 0x98, 0xbb, 0xae, 0x11, 0xa5, 0x5c, 0xd8, + 0x10, 0x3d, 0x86, 0x76, 0xe1, 0x8e, 0x8c, 0x19, 0xf3, 0xcf, 0x48, 0xc2, 0x7c, 0x11, 0xf0, 0x30, + 0x2b, 0x33, 0x43, 0x64, 0x8f, 0x71, 0x9f, 0xe9, 0xe4, 0x0b, 0x78, 0xd3, 0x80, 0xf0, 0x08, 0xd3, + 0x18, 0x42, 0xd0, 0x1b, 0xb0, 0x48, 0x7d, 0x5d, 0xc6, 0x73, 0xfa, 0x06, 0x7b, 0x42, 0xdf, 0x07, + 0x88, 0x87, 0xfd, 0xa0, 0x4b, 0xec, 0x15, 0x1f, 0x77, 0x0c, 0x8a, 0x1e, 0xc1, 0x26, 0x8d, 0x22, + 0x92, 0xb0, 0xf3, 0x34, 0x4c, 0x58, 0xcf, 0xce, 0x37, 0x12, 0x67, 0xe5, 0xc9, 0x95, 0x9e, 0x22, + 0xcb, 0xd8, 0xa5, 0x51, 0x84, 0x2d, 0xc2, 0xcc, 0xae, 0xb6, 0xd1, 0xa3, 0xfb, 0x50, 0xee, 0xa7, + 0x51, 0x3f, 0x8c, 0xa2, 0x01, 0xe3, 0xca, 0xb0, 0xb3, 0xa8, 0x23, 0x5b, 0x1f, 0x93, 0x6b, 0x8e, + 0x4e, 0xe1, 0xc6, 0x38, 0x74, 0xc0, 0xa4, 0xa4, 0x01, 0x93, 0xee, 0x92, 0x2e, 0xf1, 0xda, 0x0c, + 0x25, 0xa4, 0xb7, 0xc9, 0x13, 0x63, 0x87, 0xaf, 0x8f, 0x39, 0xb3, 0x32, 0xdd, 0x6d, 0xc3, 0xb9, + 0x22, 0xd2, 0xc4, 0x67, 0xee, 0xb2, 0x0e, 0x66, 0x38, 0x43, 0xb4, 0x10, 0x3d, 0x86, 0xf5, 0x1c, + 0x96, 0xf7, 0xc3, 0xca, 0xab, 0x29, 0xcb, 0xdd, 0xb6, 0x0d, 0x1c, 0x7d, 0x04, 0xeb, 0x22, 0x55, + 0xd9, 0xb4, 0x1d, 0xf6, 0x35, 0x7c, 0xcd, 0x19, 0xb1, 0x66, 0x1c, 0x0c, 0x47, 0xc0, 0x0f, 0x60, + 0xd1, 0x2c, 0x4c, 0xb7, 0xa8, 0x63, 0xf9, 0xe6, 0x8c, 0x8c, 0x60, 0x6b, 0x86, 0x3e, 0x84, 0x4d, + 0xf3, 0x8b, 0xf4, 0xf4, 0x94, 0x9f, 0xa8, 0xae, 0x92, 0xae, 0xae, 0x5b, 0x06, 0xd2, 0xcc, 0x11, + 0x63, 0xb5, 0xf5, 0x18, 0xd6, 0x7b, 0x21, 0x0d, 0xb8, 0x90, 0x2a, 0xf4, 0x49, 0xc8, 0xfb, 0xc2, + 0x5d, 0x9b, 0xc2, 0xca, 0x08, 0xdf, 0xe2, 0x7d, 0x51, 0xf9, 0x6d, 0x01, 0x6e, 0x77, 0x54, 0xc2, + 0xe8, 0x20, 0xe4, 0xc1, 0xff, 0xdd, 0x82, 0xbd, 0x0f, 0x65, 0x19, 0xf2, 0x20, 0x62, 0x24, 0x55, + 0x8a, 0x25, 0x34, 0x23, 0xd5, 0x0c, 0xf3, 0x75, 0x23, 0x3f, 0xc9, 0xc5, 0x93, 0xbb, 0x78, 0xf1, + 0xd2, 0x2e, 0xfe, 0x7d, 0x01, 0xee, 0xbc, 0x84, 0xa9, 0x59, 0x97, 0xf2, 0x73, 0x40, 0xe3, 0x73, + 0xe4, 0x85, 0xd5, 0xfc, 0x70, 0xfa, 0xc2, 0xc8, 0x2f, 0x1f, 0x9b, 0x33, 0x76, 0x53, 0xbf, 0x96, + 0x4c, 0x8a, 0x2e, 0x3d, 0x00, 0xe6, 0xfe, 0xf7, 0x0f, 0x80, 0xf9, 0x59, 0x1f, 0x00, 0x7f, 0x2c, + 0xc0, 0xc6, 0xcb, 0xa3, 0x47, 0xcf, 0xa1, 0x64, 0x47, 0x8b, 0x5e, 0xa1, 0x9a, 0xb8, 0xb5, 0x9d, + 0xfd, 0xff, 0x82, 0x90, 0x7c, 0xe4, 0xe8, 0xb5, 0x5a, 0x1c, 0x8c, 0x0e, 0xe8, 0x4d, 0x00, 0x95, + 0x50, 0x2e, 0xfd, 0x24, 0x8c, 0x0d, 0xf5, 0x2b, 0x78, 0x4c, 0x82, 0x6e, 0xc1, 0x72, 0x28, 0x49, + 0x3f, 0xe4, 0x34, 0xd2, 0x94, 0x2d, 0xe3, 0xa5, 0x50, 0xee, 0x65, 0xc7, 0xcc, 0x74, 0xac, 0x37, + 0xe7, 0x75, 0x6f, 0x8e, 0x49, 0x2a, 0x9f, 0x40, 0x71, 0xec, 0x5a, 0x74, 0x1b, 0xdc, 0x27, 0x5e, + 0xa7, 0x53, 0xdf, 0xf7, 0x48, 0xf7, 0xd3, 0xb6, 0x47, 0x4e, 0x8e, 0x3a, 0x6d, 0xaf, 0xd1, 0xda, + 0x6b, 0x79, 0xcd, 0xf2, 0x35, 0xb4, 0x06, 0xd0, 0xc5, 0xf5, 0xa3, 0x4e, 0x03, 0xb7, 0xda, 0xdd, + 0xb2, 0x83, 0x36, 0xe1, 0xa6, 0x77, 0xd4, 0x24, 0xc7, 0x7b, 0xa4, 0xd3, 0x3a, 0xda, 0x3f, 0xf4, + 0xc8, 0x49, 0xb7, 0xeb, 0xe1, 0xfa, 0x51, 0xc3, 0x2b, 0x17, 0x2a, 0x7f, 0x71, 0xa0, 0x3c, 0xb9, + 0x8e, 0xd1, 0x09, 0xac, 0x99, 0xbd, 0xce, 0xb8, 0x2f, 0x7a, 0x21, 0x0f, 0x2c, 0x6f, 0xd5, 0xa9, + 0xbc, 0x69, 0x2f, 0x9e, 0xb5, 0xc2, 0xab, 0x74, 0xfc, 0x88, 0xb6, 0xe1, 0x35, 0x49, 0x07, 0x71, + 0xc4, 0x48, 0x42, 0x15, 0x23, 0x67, 0x2c, 0x51, 0x5f, 0x6a, 0x9e, 0x16, 0xf0, 0xba, 0x51, 0x60, + 0xaa, 0xd8, 0x41, 0x26, 0xbe, 0xbc, 0x43, 0xe7, 0xae, 0xd8, 0xa1, 0xdf, 0x80, 0x52, 0x7c, 0x96, + 0x50, 0xc9, 0xc8, 0x59, 0xc8, 0xf5, 0x63, 0x6a, 0x6e, 0x6b, 0x05, 0x17, 0x8d, 0xec, 0x20, 0x13, + 0x55, 0x9a, 0xb0, 0x32, 0x7c, 0x1d, 0x20, 0x64, 0xdf, 0x15, 0xa6, 0x7d, 0xcc, 0x4b, 0xe1, 0xd2, + 0x45, 0x85, 0xcb, 0x17, 0x55, 0x7e, 0x0a, 0x30, 0x7a, 0x20, 0x64, 0x6e, 0x38, 0x1d, 0xe4, 0x6f, + 0x4b, 0xfd, 0x7b, 0x62, 0xe5, 0x16, 0x66, 0x5f, 0xb9, 0xb3, 0x24, 0xba, 0xfd, 0x2f, 0x07, 0x56, + 0x5f, 0xa0, 0x16, 0xbd, 0x09, 0x1b, 0xf5, 0x93, 0x66, 0xeb, 0x98, 0x78, 0x47, 0x8d, 0xe3, 0x66, + 0xeb, 0x68, 0x7f, 0xa2, 0x08, 0x6e, 0x83, 0x3b, 0xa1, 0x3f, 0x6c, 0x1d, 0x79, 0x75, 0x4c, 0x1e, + 0xbc, 0x57, 0x76, 0xd0, 0x4d, 0xb8, 0x3e, 0xa1, 0xdd, 0x3b, 0xac, 0x37, 0xca, 0x05, 0xe4, 0xc2, + 0x8d, 0x09, 0xc5, 0x93, 0x93, 0xc3, 0xfa, 0xd3, 0xf2, 0x1c, 0x7a, 0x03, 0xd0, 0x84, 0xa6, 0xfe, + 0x04, 0x97, 0xe7, 0xd1, 0x2d, 0x78, 0xfd, 0xb2, 0x9c, 0x3c, 0xdd, 0x2d, 0x2f, 0x64, 0x85, 0x37, + 0xa1, 0x3a, 0xde, 0xdf, 0x27, 0xc7, 0xed, 0x93, 0x4e, 0x79, 0x11, 0xdd, 0x87, 0xb7, 0x27, 0x94, + 0x9d, 0xb6, 0xe7, 0x7d, 0x42, 0x9e, 0xb6, 0xba, 0x07, 0xe4, 0xc0, 0xab, 0x37, 0x3d, 0x4c, 0x76, + 0x3f, 0xed, 0x7a, 0xe5, 0xa5, 0x9d, 0x3f, 0xcc, 0xc1, 0xb2, 0x7d, 0xd2, 0x4a, 0xf4, 0x8b, 0x02, + 0x94, 0xc6, 0x47, 0x24, 0xfa, 0xee, 0xd4, 0xa2, 0xbc, 0x62, 0xf7, 0x6c, 0x7c, 0xef, 0x6b, 0x5a, + 0x99, 0x41, 0x5b, 0xf9, 0x95, 0xf3, 0xb3, 0x3f, 0xff, 0xf5, 0x97, 0x85, 0x9f, 0x3b, 0x95, 0x87, + 0xc3, 0x3f, 0x55, 0x7f, 0x6c, 0xb7, 0xd6, 0xa3, 0x38, 0x11, 0xcf, 0x99, 0xaf, 0x64, 0x6d, 0xbb, + 0x46, 0x03, 0xc6, 0x55, 0xfe, 0x47, 0xac, 0xac, 0x6d, 0xff, 0xe4, 0x83, 0xde, 0x98, 0xbb, 0x0f, + 0x9c, 0xed, 0x67, 0x3f, 0xac, 0xec, 0xcd, 0xe0, 0x21, 0x49, 0x79, 0xf6, 0xa7, 0x4b, 0x26, 0x78, + 0x85, 0x33, 0xf4, 0x6b, 0x07, 0x5e, 0xbf, 0x72, 0x81, 0xa0, 0x47, 0xb3, 0x8f, 0xba, 0xab, 0x68, + 0xfa, 0xf0, 0x3f, 0x35, 0x37, 0x7c, 0x6d, 0x39, 0xef, 0x3a, 0xbb, 0x5f, 0x39, 0xf0, 0x96, 0x2f, + 0x06, 0xd3, 0x3c, 0xed, 0x96, 0xec, 0x37, 0x6e, 0x67, 0xdd, 0xd2, 0x76, 0x9e, 0xb5, 0xac, 0x41, + 0x20, 0xb2, 0x5e, 0xa8, 0x8a, 0x24, 0xa8, 0x05, 0x8c, 0xeb, 0x5e, 0xaa, 0x19, 0x15, 0x8d, 0x43, + 0xf9, 0xd2, 0x7f, 0x21, 0x3c, 0x1c, 0x89, 0xfe, 0xe9, 0x38, 0xbf, 0x29, 0x14, 0x9a, 0x7b, 0x5f, + 0x15, 0xee, 0xee, 0x1b, 0x9f, 0x0d, 0x1d, 0x44, 0x73, 0x14, 0xc4, 0xc7, 0xc6, 0xe8, 0x74, 0x51, + 0xfb, 0xff, 0xce, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x93, 0x54, 0x90, 0x52, 0x6c, 0x11, 0x00, + 0x00, } diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session_entity_type.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session_entity_type.pb.go index 9914622c18..19eb590aa7 100644 --- a/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session_entity_type.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/cloud/dialogflow/v2beta1/session_entity_type.pb.go @@ -515,56 +515,59 @@ func init() { } var fileDescriptor5 = []byte{ - // 804 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x4f, 0xdb, 0x48, - 0x14, 0xdf, 0x31, 0xbb, 0x08, 0x06, 0xed, 0x2e, 0xcc, 0xa2, 0x10, 0x85, 0x25, 0x64, 0xcd, 0x6a, - 0x85, 0x72, 0xb0, 0x45, 0x76, 0x2f, 0x2c, 0xfd, 0xa3, 0x42, 0x0c, 0x8a, 0x44, 0x42, 0xe4, 0x04, - 0xa4, 0xf6, 0x62, 0x39, 0xf8, 0x61, 0x19, 0x12, 0x8f, 0x9b, 0x99, 0x40, 0x43, 0xc5, 0x85, 0xaf, - 0xd0, 0x6b, 0x4f, 0x3d, 0xf6, 0xd0, 0x53, 0xfb, 0x01, 0x7a, 0xee, 0xb1, 0xd7, 0x4a, 0xbd, 0x54, - 0xfd, 0x06, 0x95, 0xaa, 0x9e, 0x2a, 0x8f, 0x1d, 0x82, 0xea, 0x3f, 0xa1, 0x51, 0x6f, 0x9e, 0x37, - 0xf3, 0x7b, 0xef, 0xf7, 0x7b, 0xf3, 0xde, 0xf3, 0xe0, 0x75, 0x9b, 0x52, 0xbb, 0x0d, 0xea, 0x61, - 0x9b, 0xf6, 0x2c, 0xd5, 0x72, 0xcc, 0x36, 0xb5, 0x8f, 0xda, 0xf4, 0x4c, 0x3d, 0x2d, 0xb5, 0x80, - 0x9b, 0x6b, 0x2a, 0x03, 0xc6, 0x1c, 0xea, 0x1a, 0xe0, 0x72, 0x87, 0xf7, 0x0d, 0xde, 0xf7, 0x40, - 0xf1, 0xba, 0x94, 0x53, 0xb2, 0x1c, 0x40, 0x15, 0x01, 0x55, 0x86, 0x50, 0x25, 0x84, 0xe6, 0xfe, - 0x0c, 0x7d, 0x9b, 0x9e, 0xa3, 0x9a, 0xae, 0x4b, 0xb9, 0xc9, 0x1d, 0xea, 0xb2, 0x00, 0x9e, 0x5b, - 0x1b, 0x15, 0x39, 0x12, 0x31, 0xb7, 0x18, 0x42, 0xc4, 0xaa, 0xd5, 0x3b, 0x52, 0xa1, 0xe3, 0xf1, - 0x7e, 0xb8, 0x59, 0xf8, 0x76, 0xf3, 0xc8, 0x81, 0xb6, 0x65, 0x74, 0x4c, 0x76, 0x12, 0x9c, 0x90, - 0x3f, 0x49, 0x78, 0xae, 0x11, 0xc8, 0xd1, 0x84, 0xef, 0x66, 0xdf, 0x03, 0x42, 0xf0, 0xcf, 0xae, - 0xd9, 0x81, 0x2c, 0x2a, 0xa0, 0xd5, 0x69, 0x5d, 0x7c, 0x93, 0x33, 0x3c, 0x1f, 0x46, 0xa7, 0xa7, - 0xd0, 0xed, 0x3a, 0x16, 0x18, 0x1d, 0x6a, 0x41, 0x56, 0x2a, 0xa0, 0xd5, 0xdf, 0x4a, 0x9a, 0x32, - 0x42, 0xb9, 0x12, 0x89, 0xa2, 0x04, 0x9f, 0x7b, 0xa1, 0xb7, 0x2a, 0xb5, 0x40, 0x27, 0x10, 0xb1, - 0x91, 0x1a, 0x9e, 0x12, 0x56, 0x07, 0x58, 0x76, 0xa2, 0x30, 0xb1, 0x3a, 0x53, 0x2a, 0x8d, 0x0c, - 0x16, 0x89, 0xa2, 0x5f, 0xf9, 0x90, 0x2f, 0x11, 0x26, 0xd1, 0xd0, 0xe4, 0x6f, 0x5c, 0xd0, 0x6a, - 0xcd, 0x4a, 0xf3, 0xbe, 0xb1, 0x77, 0xa0, 0xe9, 0x7a, 0xa5, 0xac, 0x19, 0xd5, 0xbd, 0xb2, 0x66, - 0xec, 0xd7, 0x1a, 0x75, 0x6d, 0xab, 0xb2, 0x5d, 0xd1, 0xca, 0xb3, 0x3f, 0x91, 0xbf, 0xf0, 0x52, - 0xec, 0xa9, 0xc1, 0x6a, 0x16, 0x91, 0x15, 0xbc, 0x1c, 0x7b, 0xa4, 0xb1, 0x5f, 0xaf, 0xef, 0x6a, - 0x55, 0xad, 0xd6, 0x9c, 0x95, 0x64, 0x86, 0x97, 0x76, 0x1d, 0xc6, 0x23, 0x49, 0x61, 0x3a, 0x3c, - 0xec, 0x01, 0xe3, 0x24, 0x83, 0x27, 0x3d, 0xb3, 0x0b, 0x2e, 0x0f, 0x2f, 0x21, 0x5c, 0x91, 0x45, - 0x3c, 0xed, 0x99, 0x36, 0x18, 0xcc, 0x39, 0x0f, 0x72, 0xff, 0x8b, 0x3e, 0xe5, 0x1b, 0x1a, 0xce, - 0x39, 0x90, 0x25, 0x8c, 0xc5, 0x26, 0xa7, 0x27, 0xe0, 0x66, 0x27, 0x04, 0x50, 0x1c, 0x6f, 0xfa, - 0x06, 0xf9, 0x05, 0xc2, 0xf9, 0xa4, 0xa8, 0xcc, 0xa3, 0x2e, 0x03, 0x62, 0xe1, 0xf9, 0x98, 0xea, - 0x66, 0x59, 0x74, 0xc3, 0xc4, 0x47, 0x5c, 0xeb, 0x84, 0x45, 0xa2, 0x91, 0x7f, 0xf0, 0xef, 0x2e, - 0x3c, 0xe2, 0xc6, 0x35, 0xb2, 0x92, 0x20, 0xfb, 0xab, 0x6f, 0xae, 0x5f, 0x11, 0x5e, 0xc3, 0x8b, - 0x3b, 0x10, 0xa5, 0x3b, 0xc8, 0x51, 0x4c, 0x99, 0xca, 0x4f, 0x11, 0xce, 0x6f, 0x75, 0xc1, 0xe4, - 0x90, 0x08, 0x4b, 0x4a, 0x6d, 0x0b, 0xff, 0x11, 0xa3, 0x5d, 0x30, 0x1b, 0x4f, 0xfa, 0x5c, 0x44, - 0xba, 0xfc, 0x1a, 0xe1, 0xfc, 0xbe, 0x67, 0xa5, 0xd1, 0x4b, 0xa0, 0x81, 0x7e, 0x20, 0x0d, 0xb2, - 0x81, 0x67, 0x7a, 0x82, 0x85, 0x98, 0x05, 0xa1, 0xc4, 0xdc, 0xc0, 0xf7, 0x60, 0x5c, 0x28, 0xdb, - 0xfe, 0xb8, 0xa8, 0x9a, 0xec, 0x44, 0xc7, 0xc1, 0x71, 0xff, 0x5b, 0xfe, 0x0f, 0xe7, 0xcb, 0xd0, - 0x86, 0x14, 0x09, 0x31, 0x17, 0x53, 0x7a, 0x3f, 0x85, 0x49, 0xb4, 0xf0, 0xc8, 0x3b, 0x84, 0x33, - 0xf1, 0x35, 0x49, 0xee, 0x8c, 0xd4, 0x9a, 0xda, 0x42, 0xb9, 0xbb, 0x63, 0xe3, 0x83, 0x66, 0x90, - 0xef, 0x5d, 0xbe, 0xfd, 0xf0, 0x44, 0xda, 0x20, 0xeb, 0x57, 0xf3, 0xf7, 0x71, 0x50, 0x2a, 0xb7, - 0xbd, 0x2e, 0x3d, 0x86, 0x43, 0xce, 0xd4, 0xa2, 0x6a, 0xda, 0xe0, 0xf2, 0xc1, 0x2f, 0x81, 0xa9, - 0xc5, 0x8b, 0x70, 0x48, 0x07, 0x1a, 0xde, 0x20, 0x3c, 0x1f, 0x57, 0xc2, 0xe4, 0xd6, 0x48, 0x72, - 0x29, 0x95, 0x9f, 0x1b, 0xa3, 0x0c, 0xe2, 0xd4, 0xf8, 0x17, 0x93, 0xa6, 0xe5, 0xba, 0x14, 0xb5, - 0x78, 0x41, 0x3e, 0x22, 0xbc, 0x90, 0xd0, 0x5c, 0x64, 0x74, 0xb6, 0xd3, 0xdb, 0x72, 0x2c, 0x4d, - 0x07, 0x42, 0x53, 0x5d, 0x1e, 0xff, 0x86, 0xfe, 0x8f, 0x6b, 0x36, 0xf2, 0x05, 0xe1, 0x85, 0x84, - 0x36, 0xbd, 0x81, 0xd0, 0xf4, 0x06, 0x1f, 0x4b, 0xe8, 0xb1, 0x10, 0x6a, 0x95, 0xaa, 0x43, 0xa1, - 0x71, 0xaf, 0x90, 0xef, 0xbc, 0xd0, 0x78, 0xf1, 0xaf, 0x10, 0x5e, 0x48, 0x68, 0xf0, 0x1b, 0x88, - 0x4f, 0x1f, 0x0d, 0xb9, 0x4c, 0x64, 0xc8, 0x68, 0xfe, 0x83, 0x65, 0x50, 0x9d, 0xc5, 0xf1, 0xab, - 0x73, 0xf3, 0x25, 0xc2, 0x2b, 0x87, 0xb4, 0x33, 0x8a, 0xe1, 0x66, 0x26, 0x42, 0xae, 0xee, 0x73, - 0xa9, 0xa3, 0x07, 0x95, 0x10, 0x6a, 0xd3, 0xb6, 0xe9, 0xda, 0x0a, 0xed, 0xda, 0xaa, 0x0d, 0xae, - 0x60, 0xaa, 0x06, 0x5b, 0xa6, 0xe7, 0xb0, 0xc4, 0xe7, 0xd9, 0xc6, 0xd0, 0xf4, 0x19, 0xa1, 0x67, - 0x92, 0x54, 0xde, 0x7e, 0x2e, 0x2d, 0xef, 0x04, 0x3e, 0xb7, 0x04, 0x9d, 0xf2, 0x90, 0xce, 0x41, - 0x00, 0x6a, 0x4d, 0x0a, 0xff, 0xff, 0x7e, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xaf, 0x87, 0xb0, 0xb6, - 0x77, 0x0a, 0x00, 0x00, + // 863 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xe3, 0x44, + 0x14, 0x66, 0x5c, 0x58, 0xed, 0xce, 0xf2, 0xa3, 0x3b, 0x54, 0x69, 0x94, 0xd2, 0x34, 0x78, 0x11, + 0xaa, 0x72, 0xb0, 0xd5, 0xc0, 0x65, 0x59, 0x7e, 0x48, 0xdb, 0x38, 0xab, 0x48, 0x9b, 0x34, 0x72, + 0xd2, 0x15, 0x94, 0x83, 0xe5, 0xd4, 0xaf, 0x96, 0x69, 0xe2, 0x31, 0x9e, 0xc9, 0x2e, 0x29, 0xea, + 0xa5, 0xdc, 0xb8, 0x70, 0x40, 0xdc, 0x38, 0x71, 0xe0, 0x80, 0x04, 0xa7, 0xfe, 0x03, 0x1c, 0xf8, + 0x0b, 0x10, 0x37, 0x8e, 0x5c, 0x39, 0x22, 0x71, 0x03, 0x79, 0xec, 0x34, 0xa5, 0x1e, 0xdb, 0x21, + 0xdb, 0x9b, 0xe7, 0xcd, 0x7c, 0xef, 0xbd, 0xef, 0x9b, 0xf7, 0x9e, 0x07, 0xdf, 0x73, 0x29, 0x75, + 0x47, 0xa0, 0x1f, 0x8e, 0xe8, 0xc4, 0xd1, 0x1d, 0xcf, 0x1e, 0x51, 0xf7, 0x68, 0x44, 0x9f, 0xea, + 0x4f, 0x1a, 0x43, 0xe0, 0xf6, 0x8e, 0xce, 0x80, 0x31, 0x8f, 0xfa, 0x16, 0xf8, 0xdc, 0xe3, 0x53, + 0x8b, 0x4f, 0x03, 0xd0, 0x82, 0x90, 0x72, 0x4a, 0xb6, 0x62, 0xa8, 0x26, 0xa0, 0xda, 0x1c, 0xaa, + 0x25, 0xd0, 0xca, 0x6b, 0x89, 0x6f, 0x3b, 0xf0, 0x74, 0xdb, 0xf7, 0x29, 0xb7, 0xb9, 0x47, 0x7d, + 0x16, 0xc3, 0x2b, 0x3b, 0x45, 0x91, 0x53, 0x11, 0x2b, 0x1b, 0x09, 0x44, 0xac, 0x86, 0x93, 0x23, + 0x1d, 0xc6, 0x01, 0x9f, 0x26, 0x9b, 0xb5, 0xab, 0x9b, 0x47, 0x1e, 0x8c, 0x1c, 0x6b, 0x6c, 0xb3, + 0xe3, 0xf8, 0x84, 0xfa, 0x97, 0x82, 0xef, 0xf4, 0x63, 0x3a, 0x86, 0xf0, 0x3d, 0x98, 0x06, 0x40, + 0x08, 0x7e, 0xde, 0xb7, 0xc7, 0x50, 0x46, 0x35, 0xb4, 0x7d, 0xcb, 0x14, 0xdf, 0xe4, 0x29, 0x5e, + 0x4b, 0xa2, 0xd3, 0x27, 0x10, 0x86, 0x9e, 0x03, 0xd6, 0x98, 0x3a, 0x50, 0x56, 0x6a, 0x68, 0xfb, + 0xe5, 0x86, 0xa1, 0x15, 0x30, 0xd7, 0x52, 0x51, 0xb4, 0xf8, 0x73, 0x2f, 0xf1, 0xd6, 0xa1, 0x0e, + 0x98, 0x04, 0x52, 0x36, 0xd2, 0xc5, 0x37, 0x85, 0xd5, 0x03, 0x56, 0x5e, 0xa9, 0xad, 0x6c, 0xdf, + 0x6e, 0x34, 0x0a, 0x83, 0xa5, 0xa2, 0x98, 0x17, 0x3e, 0xd4, 0x33, 0x84, 0x49, 0x3a, 0x34, 0x79, + 0x03, 0xd7, 0x8c, 0xee, 0xa0, 0x3d, 0xf8, 0xc8, 0xda, 0x7b, 0x6c, 0x98, 0x66, 0xbb, 0x69, 0x58, + 0x9d, 0xbd, 0xa6, 0x61, 0xed, 0x77, 0xfb, 0x3d, 0x63, 0xb7, 0xdd, 0x6a, 0x1b, 0xcd, 0xd5, 0xe7, + 0xc8, 0xeb, 0x78, 0x53, 0x7a, 0x6a, 0xb6, 0x5a, 0x45, 0xe4, 0x2e, 0xde, 0x92, 0x1e, 0xe9, 0xef, + 0xf7, 0x7a, 0x8f, 0x8c, 0x8e, 0xd1, 0x1d, 0xac, 0x2a, 0x2a, 0xc3, 0x9b, 0x8f, 0x3c, 0xc6, 0x53, + 0xa2, 0x30, 0x13, 0x3e, 0x9d, 0x00, 0xe3, 0xa4, 0x84, 0x6f, 0x04, 0x76, 0x08, 0x3e, 0x4f, 0x2e, + 0x21, 0x59, 0x91, 0x0d, 0x7c, 0x2b, 0xb0, 0x5d, 0xb0, 0x98, 0x77, 0x12, 0x6b, 0xff, 0x82, 0x79, + 0x33, 0x32, 0xf4, 0xbd, 0x13, 0x20, 0x9b, 0x18, 0x8b, 0x4d, 0x4e, 0x8f, 0xc1, 0x2f, 0xaf, 0x08, + 0xa0, 0x38, 0x3e, 0x88, 0x0c, 0xea, 0x4f, 0x08, 0x57, 0xb3, 0xa2, 0xb2, 0x80, 0xfa, 0x0c, 0x88, + 0x83, 0xd7, 0x24, 0xd5, 0xcd, 0xca, 0x68, 0x41, 0xe1, 0x53, 0xae, 0x4d, 0xc2, 0x52, 0xd1, 0xc8, + 0x9b, 0xf8, 0x15, 0x1f, 0x3e, 0xe3, 0xd6, 0xa5, 0x64, 0x15, 0x91, 0xec, 0x4b, 0x91, 0xb9, 0x77, + 0x91, 0xf0, 0x0e, 0xde, 0x78, 0x08, 0xe9, 0x74, 0x67, 0x1a, 0x49, 0xca, 0x54, 0xfd, 0x16, 0xe1, + 0xea, 0x6e, 0x08, 0x36, 0x87, 0x4c, 0x58, 0x96, 0xb4, 0x43, 0xfc, 0xaa, 0x84, 0xbb, 0xc8, 0x6c, + 0x39, 0xea, 0x77, 0x52, 0xd4, 0xd5, 0x9f, 0x11, 0xae, 0xee, 0x07, 0x4e, 0x5e, 0x7a, 0x19, 0x69, + 0xa0, 0x6b, 0x4c, 0x83, 0xdc, 0xc7, 0xb7, 0x27, 0x22, 0x0b, 0x31, 0x0b, 0x12, 0x8a, 0x95, 0x99, + 0xef, 0xd9, 0xb8, 0xd0, 0x5a, 0xd1, 0xb8, 0xe8, 0xd8, 0xec, 0xd8, 0xc4, 0xf1, 0xf1, 0xe8, 0x5b, + 0x7d, 0x1b, 0x57, 0x9b, 0x30, 0x82, 0x1c, 0x0a, 0x92, 0x8b, 0x69, 0x7c, 0xf5, 0x22, 0x26, 0xe9, + 0xc2, 0x23, 0xdf, 0x2b, 0xb8, 0x24, 0xaf, 0x49, 0xf2, 0x7e, 0x21, 0xd7, 0xdc, 0x16, 0xaa, 0x7c, + 0xb0, 0x34, 0x3e, 0x6e, 0x06, 0xf5, 0x4b, 0x74, 0xf6, 0xeb, 0x1f, 0x5f, 0x2b, 0x5f, 0x20, 0x72, + 0xef, 0x62, 0x02, 0x7f, 0x1e, 0x17, 0xcb, 0x7b, 0x41, 0x48, 0x3f, 0x81, 0x43, 0xce, 0xf4, 0xba, + 0x6e, 0xbb, 0xe0, 0xf3, 0xd9, 0x4f, 0x81, 0xe9, 0xf5, 0xd3, 0x64, 0x4c, 0x0b, 0x67, 0x07, 0x2d, + 0xd2, 0x2c, 0x06, 0x87, 0x13, 0x9f, 0x7b, 0x63, 0x88, 0x0c, 0x19, 0x7e, 0xc8, 0x37, 0x0a, 0x5e, + 0x93, 0x35, 0x03, 0x79, 0xb7, 0x90, 0x66, 0x4e, 0x0f, 0x55, 0x96, 0x28, 0x28, 0xb9, 0x2e, 0xd1, + 0x25, 0xe7, 0xa9, 0x72, 0x99, 0x8c, 0x5e, 0x3f, 0xfd, 0xaf, 0x2e, 0x72, 0xb0, 0x54, 0x95, 0x2b, + 0x7e, 0xc8, 0x2f, 0x0a, 0x5e, 0xcf, 0x68, 0x78, 0x52, 0x5c, 0x01, 0xf9, 0xa3, 0x62, 0x29, 0x75, + 0xce, 0x63, 0x75, 0x7e, 0x44, 0xea, 0xf2, 0x55, 0xf3, 0x8e, 0x6c, 0x04, 0x1c, 0x7c, 0xac, 0x5e, + 0x4b, 0x29, 0x49, 0x9d, 0x93, 0x3f, 0x15, 0xbc, 0x9e, 0x31, 0x99, 0x16, 0xd0, 0x31, 0x7f, 0xa6, + 0x2d, 0xa5, 0xe3, 0xef, 0xb1, 0x8e, 0xbf, 0xa1, 0x46, 0x67, 0xce, 0x5a, 0xf6, 0xf4, 0xfa, 0x9f, + 0x95, 0x27, 0xd7, 0x96, 0x36, 0x3e, 0x5c, 0x26, 0xca, 0x22, 0x25, 0x2a, 0xd7, 0xfb, 0x1f, 0x84, + 0xd7, 0x33, 0xc6, 0xe8, 0x02, 0x7a, 0xe7, 0x0f, 0xe0, 0x4a, 0x29, 0x35, 0xca, 0x8d, 0xe8, 0x59, + 0x38, 0xef, 0xdc, 0xfa, 0xb3, 0x74, 0x6e, 0xfd, 0x5a, 0x3a, 0xf7, 0xc1, 0x39, 0xc2, 0x77, 0x0f, + 0xe9, 0xb8, 0x88, 0xeb, 0x83, 0x52, 0x8a, 0x66, 0x2f, 0x62, 0xd5, 0x43, 0x07, 0xed, 0x04, 0xea, + 0xd2, 0x91, 0xed, 0xbb, 0x1a, 0x0d, 0x5d, 0xdd, 0x05, 0x5f, 0x70, 0xd6, 0xe3, 0x2d, 0x3b, 0xf0, + 0x58, 0xe6, 0x73, 0xfa, 0xfe, 0xdc, 0xf4, 0x37, 0x42, 0xdf, 0x29, 0x4a, 0xb3, 0xf5, 0x83, 0xb2, + 0xf5, 0x30, 0xf6, 0xb9, 0x2b, 0xd2, 0x69, 0xce, 0xd3, 0x79, 0x1c, 0x83, 0x86, 0x37, 0x84, 0xff, + 0xb7, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x65, 0x3a, 0xa2, 0x54, 0x27, 0x0c, 0x00, 0x00, } diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1/cloud_tts.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1/cloud_tts.pb.go new file mode 100644 index 0000000000..aefcc3d4ec --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/cloud/texttospeech/v1beta1/cloud_tts.pb.go @@ -0,0 +1,672 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/cloud/texttospeech/v1beta1/cloud_tts.proto + +/* +Package texttospeech is a generated protocol buffer package. + +It is generated from these files: + google/cloud/texttospeech/v1beta1/cloud_tts.proto + +It has these top-level messages: + ListVoicesRequest + ListVoicesResponse + Voice + SynthesizeSpeechRequest + SynthesisInput + VoiceSelectionParams + AudioConfig + SynthesizeSpeechResponse +*/ +package texttospeech + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Gender of the voice as described in +// [SSML voice element](https://www.w3.org/TR/speech-synthesis11/#edef_voice). +type SsmlVoiceGender int32 + +const ( + // An unspecified gender. + // In VoiceSelectionParams, this means that the client doesn't care which + // gender the selected voice will have. In the Voice field of + // ListVoicesResponse, this may mean that the voice doesn't fit any of the + // other categories in this enum, or that the gender of the voice isn't known. + SsmlVoiceGender_SSML_VOICE_GENDER_UNSPECIFIED SsmlVoiceGender = 0 + // A male voice. + SsmlVoiceGender_MALE SsmlVoiceGender = 1 + // A female voice. + SsmlVoiceGender_FEMALE SsmlVoiceGender = 2 + // A gender-neutral voice. + SsmlVoiceGender_NEUTRAL SsmlVoiceGender = 3 +) + +var SsmlVoiceGender_name = map[int32]string{ + 0: "SSML_VOICE_GENDER_UNSPECIFIED", + 1: "MALE", + 2: "FEMALE", + 3: "NEUTRAL", +} +var SsmlVoiceGender_value = map[string]int32{ + "SSML_VOICE_GENDER_UNSPECIFIED": 0, + "MALE": 1, + "FEMALE": 2, + "NEUTRAL": 3, +} + +func (x SsmlVoiceGender) String() string { + return proto.EnumName(SsmlVoiceGender_name, int32(x)) +} +func (SsmlVoiceGender) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +// Configuration to set up audio encoder. The encoding determines the output +// audio format that we'd like. +type AudioEncoding int32 + +const ( + // Not specified. Will return result [google.rpc.Code.INVALID_ARGUMENT][]. + AudioEncoding_AUDIO_ENCODING_UNSPECIFIED AudioEncoding = 0 + // Uncompressed 16-bit signed little-endian samples (Linear PCM). + // Audio content returned as LINEAR16 also contains a WAV header. + AudioEncoding_LINEAR16 AudioEncoding = 1 + // MP3 audio. + AudioEncoding_MP3 AudioEncoding = 2 + // Opus encoded audio wrapped in an ogg container. The result will be a + // file which can be played natively on Android, and in browsers (at least + // Chrome and Firefox). The quality of the encoding is considerably higher + // than MP3 while using approximately the same bitrate. + AudioEncoding_OGG_OPUS AudioEncoding = 3 +) + +var AudioEncoding_name = map[int32]string{ + 0: "AUDIO_ENCODING_UNSPECIFIED", + 1: "LINEAR16", + 2: "MP3", + 3: "OGG_OPUS", +} +var AudioEncoding_value = map[string]int32{ + "AUDIO_ENCODING_UNSPECIFIED": 0, + "LINEAR16": 1, + "MP3": 2, + "OGG_OPUS": 3, +} + +func (x AudioEncoding) String() string { + return proto.EnumName(AudioEncoding_name, int32(x)) +} +func (AudioEncoding) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +// The top-level message sent by the client for the `ListVoices` method. +type ListVoicesRequest struct { +} + +func (m *ListVoicesRequest) Reset() { *m = ListVoicesRequest{} } +func (m *ListVoicesRequest) String() string { return proto.CompactTextString(m) } +func (*ListVoicesRequest) ProtoMessage() {} +func (*ListVoicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +// The message returned to the client by the `ListVoices` method. +type ListVoicesResponse struct { + // The list of voices. + Voices []*Voice `protobuf:"bytes,1,rep,name=voices" json:"voices,omitempty"` +} + +func (m *ListVoicesResponse) Reset() { *m = ListVoicesResponse{} } +func (m *ListVoicesResponse) String() string { return proto.CompactTextString(m) } +func (*ListVoicesResponse) ProtoMessage() {} +func (*ListVoicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *ListVoicesResponse) GetVoices() []*Voice { + if m != nil { + return m.Voices + } + return nil +} + +// Description of a voice supported by the TTS service. +type Voice struct { + // The languages that this voice supports, expressed as + // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags (e.g. + // "en-US", "es-419", "cmn-tw"). + LanguageCodes []string `protobuf:"bytes,1,rep,name=language_codes,json=languageCodes" json:"language_codes,omitempty"` + // The name of this voice. Each distinct voice has a unique name. + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // The gender of this voice. + SsmlGender SsmlVoiceGender `protobuf:"varint,3,opt,name=ssml_gender,json=ssmlGender,enum=google.cloud.texttospeech.v1beta1.SsmlVoiceGender" json:"ssml_gender,omitempty"` + // The natural sample rate (in hertz) for this voice. + NaturalSampleRateHertz int32 `protobuf:"varint,4,opt,name=natural_sample_rate_hertz,json=naturalSampleRateHertz" json:"natural_sample_rate_hertz,omitempty"` +} + +func (m *Voice) Reset() { *m = Voice{} } +func (m *Voice) String() string { return proto.CompactTextString(m) } +func (*Voice) ProtoMessage() {} +func (*Voice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Voice) GetLanguageCodes() []string { + if m != nil { + return m.LanguageCodes + } + return nil +} + +func (m *Voice) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Voice) GetSsmlGender() SsmlVoiceGender { + if m != nil { + return m.SsmlGender + } + return SsmlVoiceGender_SSML_VOICE_GENDER_UNSPECIFIED +} + +func (m *Voice) GetNaturalSampleRateHertz() int32 { + if m != nil { + return m.NaturalSampleRateHertz + } + return 0 +} + +// The top-level message sent by the client for the `SynthesizeSpeech` method. +type SynthesizeSpeechRequest struct { + // Required. The Synthesizer requires either plain text or SSML as input. + Input *SynthesisInput `protobuf:"bytes,1,opt,name=input" json:"input,omitempty"` + // Required. The desired voice of the synthesized audio. + Voice *VoiceSelectionParams `protobuf:"bytes,2,opt,name=voice" json:"voice,omitempty"` + // Required. The configuration of the synthesized audio. + AudioConfig *AudioConfig `protobuf:"bytes,3,opt,name=audio_config,json=audioConfig" json:"audio_config,omitempty"` +} + +func (m *SynthesizeSpeechRequest) Reset() { *m = SynthesizeSpeechRequest{} } +func (m *SynthesizeSpeechRequest) String() string { return proto.CompactTextString(m) } +func (*SynthesizeSpeechRequest) ProtoMessage() {} +func (*SynthesizeSpeechRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *SynthesizeSpeechRequest) GetInput() *SynthesisInput { + if m != nil { + return m.Input + } + return nil +} + +func (m *SynthesizeSpeechRequest) GetVoice() *VoiceSelectionParams { + if m != nil { + return m.Voice + } + return nil +} + +func (m *SynthesizeSpeechRequest) GetAudioConfig() *AudioConfig { + if m != nil { + return m.AudioConfig + } + return nil +} + +// Contains text input to be synthesized. Either `text` or `ssml` must be +// supplied. Supplying both or neither returns +// [google.rpc.Code.INVALID_ARGUMENT][]. The input size is limited to 5000 +// characters. +type SynthesisInput struct { + // The input source, which is either plain text or SSML. + // + // Types that are valid to be assigned to InputSource: + // *SynthesisInput_Text + // *SynthesisInput_Ssml + InputSource isSynthesisInput_InputSource `protobuf_oneof:"input_source"` +} + +func (m *SynthesisInput) Reset() { *m = SynthesisInput{} } +func (m *SynthesisInput) String() string { return proto.CompactTextString(m) } +func (*SynthesisInput) ProtoMessage() {} +func (*SynthesisInput) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +type isSynthesisInput_InputSource interface { + isSynthesisInput_InputSource() +} + +type SynthesisInput_Text struct { + Text string `protobuf:"bytes,1,opt,name=text,oneof"` +} +type SynthesisInput_Ssml struct { + Ssml string `protobuf:"bytes,2,opt,name=ssml,oneof"` +} + +func (*SynthesisInput_Text) isSynthesisInput_InputSource() {} +func (*SynthesisInput_Ssml) isSynthesisInput_InputSource() {} + +func (m *SynthesisInput) GetInputSource() isSynthesisInput_InputSource { + if m != nil { + return m.InputSource + } + return nil +} + +func (m *SynthesisInput) GetText() string { + if x, ok := m.GetInputSource().(*SynthesisInput_Text); ok { + return x.Text + } + return "" +} + +func (m *SynthesisInput) GetSsml() string { + if x, ok := m.GetInputSource().(*SynthesisInput_Ssml); ok { + return x.Ssml + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*SynthesisInput) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _SynthesisInput_OneofMarshaler, _SynthesisInput_OneofUnmarshaler, _SynthesisInput_OneofSizer, []interface{}{ + (*SynthesisInput_Text)(nil), + (*SynthesisInput_Ssml)(nil), + } +} + +func _SynthesisInput_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*SynthesisInput) + // input_source + switch x := m.InputSource.(type) { + case *SynthesisInput_Text: + b.EncodeVarint(1<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Text) + case *SynthesisInput_Ssml: + b.EncodeVarint(2<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Ssml) + case nil: + default: + return fmt.Errorf("SynthesisInput.InputSource has unexpected type %T", x) + } + return nil +} + +func _SynthesisInput_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*SynthesisInput) + switch tag { + case 1: // input_source.text + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.InputSource = &SynthesisInput_Text{x} + return true, err + case 2: // input_source.ssml + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.InputSource = &SynthesisInput_Ssml{x} + return true, err + default: + return false, nil + } +} + +func _SynthesisInput_OneofSizer(msg proto.Message) (n int) { + m := msg.(*SynthesisInput) + // input_source + switch x := m.InputSource.(type) { + case *SynthesisInput_Text: + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Text))) + n += len(x.Text) + case *SynthesisInput_Ssml: + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Ssml))) + n += len(x.Ssml) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// Description of which voice to use for a synthesis request. +type VoiceSelectionParams struct { + // The language (and optionally also the region) of the voice expressed as a + // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag, e.g. + // "en-US". Required. This should not include a script tag (e.g. use + // "cmn-cn" rather than "cmn-Hant-cn"), because the script will be inferred + // from the input provided in the SynthesisInput. The TTS service + // will use this parameter to help choose an appropriate voice. Note that + // the TTS service may choose a voice with a slightly different language code + // than the one selected; it may substitute a different region + // (e.g. using en-US rather than en-CA if there isn't a Canadian voice + // available), or even a different language, e.g. using "nb" (Norwegian + // Bokmal) instead of "no" (Norwegian)". + LanguageCode string `protobuf:"bytes,1,opt,name=language_code,json=languageCode" json:"language_code,omitempty"` + // The name of the voice. Optional; if not set, the service will choose a + // voice based on the other parameters such as language_code and gender. + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // The preferred gender of the voice. Optional; if not set, the service will + // choose a voice based on the other parameters such as language_code and + // name. Note that this is only a preference, not requirement; if a + // voice of the appropriate gender is not available, the synthesizer should + // substitute a voice with a different gender rather than failing the request. + SsmlGender SsmlVoiceGender `protobuf:"varint,3,opt,name=ssml_gender,json=ssmlGender,enum=google.cloud.texttospeech.v1beta1.SsmlVoiceGender" json:"ssml_gender,omitempty"` +} + +func (m *VoiceSelectionParams) Reset() { *m = VoiceSelectionParams{} } +func (m *VoiceSelectionParams) String() string { return proto.CompactTextString(m) } +func (*VoiceSelectionParams) ProtoMessage() {} +func (*VoiceSelectionParams) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *VoiceSelectionParams) GetLanguageCode() string { + if m != nil { + return m.LanguageCode + } + return "" +} + +func (m *VoiceSelectionParams) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *VoiceSelectionParams) GetSsmlGender() SsmlVoiceGender { + if m != nil { + return m.SsmlGender + } + return SsmlVoiceGender_SSML_VOICE_GENDER_UNSPECIFIED +} + +// Description of audio data to be synthesized. +type AudioConfig struct { + // Required. The format of the requested audio byte stream. + AudioEncoding AudioEncoding `protobuf:"varint,1,opt,name=audio_encoding,json=audioEncoding,enum=google.cloud.texttospeech.v1beta1.AudioEncoding" json:"audio_encoding,omitempty"` + // Optional speaking rate/speed, in the range [0.25, 4.0]. 1.0 is the normal + // native speed supported by the specific voice. 2.0 is twice as fast, and + // 0.5 is half as fast. If unset(0.0), defaults to the native 1.0 speed. Any + // other values < 0.25 or > 4.0 will return an error. + SpeakingRate float64 `protobuf:"fixed64,2,opt,name=speaking_rate,json=speakingRate" json:"speaking_rate,omitempty"` + // Optional speaking pitch, in the range [-20.0, 20.0]. 20 means increase 20 + // semitones from the original pitch. -20 means decrease 20 semitones from the + // original pitch. + Pitch float64 `protobuf:"fixed64,3,opt,name=pitch" json:"pitch,omitempty"` + // Optional volume gain (in dB) of the normal native volume supported by the + // specific voice, in the range [-96.0, 16.0]. If unset, or set to a value of + // 0.0 (dB), will play at normal native signal amplitude. A value of -6.0 (dB) + // will play at approximately half the amplitude of the normal native signal + // amplitude. A value of +6.0 (dB) will play at approximately twice the + // amplitude of the normal native signal amplitude. Strongly recommend not to + // exceed +10 (dB) as there's usually no effective increase in loudness for + // any value greater than that. + VolumeGainDb float64 `protobuf:"fixed64,4,opt,name=volume_gain_db,json=volumeGainDb" json:"volume_gain_db,omitempty"` + // The synthesis sample rate (in hertz) for this audio. Optional. If this is + // different from the voice's natural sample rate, then the synthesizer will + // honor this request by converting to the desired sample rate (which might + // result in worse audio quality), unless the specified sample rate is not + // supported for the encoding chosen, in which case it will fail the request + // and return [google.rpc.Code.INVALID_ARGUMENT][]. + SampleRateHertz int32 `protobuf:"varint,5,opt,name=sample_rate_hertz,json=sampleRateHertz" json:"sample_rate_hertz,omitempty"` +} + +func (m *AudioConfig) Reset() { *m = AudioConfig{} } +func (m *AudioConfig) String() string { return proto.CompactTextString(m) } +func (*AudioConfig) ProtoMessage() {} +func (*AudioConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *AudioConfig) GetAudioEncoding() AudioEncoding { + if m != nil { + return m.AudioEncoding + } + return AudioEncoding_AUDIO_ENCODING_UNSPECIFIED +} + +func (m *AudioConfig) GetSpeakingRate() float64 { + if m != nil { + return m.SpeakingRate + } + return 0 +} + +func (m *AudioConfig) GetPitch() float64 { + if m != nil { + return m.Pitch + } + return 0 +} + +func (m *AudioConfig) GetVolumeGainDb() float64 { + if m != nil { + return m.VolumeGainDb + } + return 0 +} + +func (m *AudioConfig) GetSampleRateHertz() int32 { + if m != nil { + return m.SampleRateHertz + } + return 0 +} + +// The message returned to the client by the `SynthesizeSpeech` method. +type SynthesizeSpeechResponse struct { + // The audio data bytes encoded as specified in the request, including the + // header (For LINEAR16 audio, we include the WAV header). Note: as + // with all bytes fields, protobuffers use a pure binary representation, + // whereas JSON representations use base64. + AudioContent []byte `protobuf:"bytes,1,opt,name=audio_content,json=audioContent,proto3" json:"audio_content,omitempty"` +} + +func (m *SynthesizeSpeechResponse) Reset() { *m = SynthesizeSpeechResponse{} } +func (m *SynthesizeSpeechResponse) String() string { return proto.CompactTextString(m) } +func (*SynthesizeSpeechResponse) ProtoMessage() {} +func (*SynthesizeSpeechResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *SynthesizeSpeechResponse) GetAudioContent() []byte { + if m != nil { + return m.AudioContent + } + return nil +} + +func init() { + proto.RegisterType((*ListVoicesRequest)(nil), "google.cloud.texttospeech.v1beta1.ListVoicesRequest") + proto.RegisterType((*ListVoicesResponse)(nil), "google.cloud.texttospeech.v1beta1.ListVoicesResponse") + proto.RegisterType((*Voice)(nil), "google.cloud.texttospeech.v1beta1.Voice") + proto.RegisterType((*SynthesizeSpeechRequest)(nil), "google.cloud.texttospeech.v1beta1.SynthesizeSpeechRequest") + proto.RegisterType((*SynthesisInput)(nil), "google.cloud.texttospeech.v1beta1.SynthesisInput") + proto.RegisterType((*VoiceSelectionParams)(nil), "google.cloud.texttospeech.v1beta1.VoiceSelectionParams") + proto.RegisterType((*AudioConfig)(nil), "google.cloud.texttospeech.v1beta1.AudioConfig") + proto.RegisterType((*SynthesizeSpeechResponse)(nil), "google.cloud.texttospeech.v1beta1.SynthesizeSpeechResponse") + proto.RegisterEnum("google.cloud.texttospeech.v1beta1.SsmlVoiceGender", SsmlVoiceGender_name, SsmlVoiceGender_value) + proto.RegisterEnum("google.cloud.texttospeech.v1beta1.AudioEncoding", AudioEncoding_name, AudioEncoding_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for TextToSpeech service + +type TextToSpeechClient interface { + // Returns a list of [Voice][google.cloud.texttospeech.v1beta1.Voice] + // supported for synthesis. + ListVoices(ctx context.Context, in *ListVoicesRequest, opts ...grpc.CallOption) (*ListVoicesResponse, error) + // Synthesizes speech synchronously: receive results after all text input + // has been processed. + SynthesizeSpeech(ctx context.Context, in *SynthesizeSpeechRequest, opts ...grpc.CallOption) (*SynthesizeSpeechResponse, error) +} + +type textToSpeechClient struct { + cc *grpc.ClientConn +} + +func NewTextToSpeechClient(cc *grpc.ClientConn) TextToSpeechClient { + return &textToSpeechClient{cc} +} + +func (c *textToSpeechClient) ListVoices(ctx context.Context, in *ListVoicesRequest, opts ...grpc.CallOption) (*ListVoicesResponse, error) { + out := new(ListVoicesResponse) + err := grpc.Invoke(ctx, "/google.cloud.texttospeech.v1beta1.TextToSpeech/ListVoices", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *textToSpeechClient) SynthesizeSpeech(ctx context.Context, in *SynthesizeSpeechRequest, opts ...grpc.CallOption) (*SynthesizeSpeechResponse, error) { + out := new(SynthesizeSpeechResponse) + err := grpc.Invoke(ctx, "/google.cloud.texttospeech.v1beta1.TextToSpeech/SynthesizeSpeech", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for TextToSpeech service + +type TextToSpeechServer interface { + // Returns a list of [Voice][google.cloud.texttospeech.v1beta1.Voice] + // supported for synthesis. + ListVoices(context.Context, *ListVoicesRequest) (*ListVoicesResponse, error) + // Synthesizes speech synchronously: receive results after all text input + // has been processed. + SynthesizeSpeech(context.Context, *SynthesizeSpeechRequest) (*SynthesizeSpeechResponse, error) +} + +func RegisterTextToSpeechServer(s *grpc.Server, srv TextToSpeechServer) { + s.RegisterService(&_TextToSpeech_serviceDesc, srv) +} + +func _TextToSpeech_ListVoices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListVoicesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TextToSpeechServer).ListVoices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.cloud.texttospeech.v1beta1.TextToSpeech/ListVoices", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TextToSpeechServer).ListVoices(ctx, req.(*ListVoicesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TextToSpeech_SynthesizeSpeech_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SynthesizeSpeechRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TextToSpeechServer).SynthesizeSpeech(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.cloud.texttospeech.v1beta1.TextToSpeech/SynthesizeSpeech", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TextToSpeechServer).SynthesizeSpeech(ctx, req.(*SynthesizeSpeechRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _TextToSpeech_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.cloud.texttospeech.v1beta1.TextToSpeech", + HandlerType: (*TextToSpeechServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListVoices", + Handler: _TextToSpeech_ListVoices_Handler, + }, + { + MethodName: "SynthesizeSpeech", + Handler: _TextToSpeech_SynthesizeSpeech_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/cloud/texttospeech/v1beta1/cloud_tts.proto", +} + +func init() { proto.RegisterFile("google/cloud/texttospeech/v1beta1/cloud_tts.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 844 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4d, 0x6f, 0x1b, 0x45, + 0x18, 0xee, 0xd8, 0x71, 0xda, 0xbc, 0x5e, 0x3b, 0xce, 0x10, 0x51, 0x13, 0x51, 0xe4, 0x6e, 0xa8, + 0x64, 0xe5, 0x60, 0x63, 0x97, 0x0f, 0x91, 0x1e, 0xc0, 0xb1, 0xb7, 0xae, 0x25, 0x7f, 0x31, 0x9b, + 0xa4, 0x12, 0x97, 0xd5, 0x64, 0x3d, 0x6c, 0x56, 0xac, 0x67, 0x16, 0xcf, 0x6c, 0x54, 0x7a, 0x44, + 0x9c, 0x39, 0xc0, 0x5f, 0xe0, 0x07, 0xf0, 0x5b, 0x40, 0xe2, 0x17, 0xf0, 0x0f, 0xb8, 0x70, 0x44, + 0x33, 0xbb, 0x71, 0x1d, 0x07, 0x51, 0x97, 0x03, 0xb7, 0x9d, 0x67, 0xfc, 0x3c, 0xf3, 0xbe, 0xcf, + 0x3c, 0x7e, 0x07, 0x5a, 0x81, 0x10, 0x41, 0xc4, 0x9a, 0x7e, 0x24, 0x92, 0x59, 0x53, 0xb1, 0x17, + 0x4a, 0x09, 0x19, 0x33, 0xe6, 0x5f, 0x36, 0xaf, 0x5a, 0x17, 0x4c, 0xd1, 0x56, 0xba, 0xe5, 0x29, + 0x25, 0x1b, 0xf1, 0x42, 0x28, 0x81, 0x1f, 0xa6, 0x94, 0x86, 0xc1, 0x1b, 0xab, 0x94, 0x46, 0x46, + 0x39, 0x78, 0x37, 0x53, 0xa5, 0x71, 0xd8, 0xa4, 0x9c, 0x0b, 0x45, 0x55, 0x28, 0x78, 0x26, 0x60, + 0xbf, 0x05, 0x7b, 0xc3, 0x50, 0xaa, 0x73, 0x11, 0xfa, 0x4c, 0x12, 0xf6, 0x4d, 0xc2, 0xa4, 0xb2, + 0xcf, 0x01, 0xaf, 0x82, 0x32, 0x16, 0x5c, 0x32, 0xfc, 0x39, 0x6c, 0x5f, 0x19, 0xa4, 0x8a, 0x6a, + 0xf9, 0x7a, 0xb1, 0x5d, 0x6f, 0xbc, 0xf6, 0xf0, 0x86, 0x91, 0x20, 0x19, 0xcf, 0xfe, 0x15, 0x41, + 0xc1, 0x20, 0xf8, 0x11, 0x94, 0x23, 0xca, 0x83, 0x84, 0x06, 0xcc, 0xf3, 0xc5, 0x2c, 0xd3, 0xdc, + 0x21, 0xa5, 0x6b, 0xb4, 0xab, 0x41, 0x8c, 0x61, 0x8b, 0xd3, 0x39, 0xab, 0xe6, 0x6a, 0xa8, 0xbe, + 0x43, 0xcc, 0x37, 0x76, 0xa1, 0x28, 0xe5, 0x3c, 0xf2, 0x02, 0xc6, 0x67, 0x6c, 0x51, 0xcd, 0xd7, + 0x50, 0xbd, 0xdc, 0x6e, 0x6f, 0x50, 0x8b, 0x2b, 0xe7, 0x91, 0x39, 0xbd, 0x6f, 0x98, 0x04, 0xb4, + 0x4c, 0xfa, 0x8d, 0x3f, 0x85, 0x77, 0x38, 0x55, 0xc9, 0x82, 0x46, 0x9e, 0xa4, 0xf3, 0x38, 0x62, + 0xde, 0x82, 0x2a, 0xe6, 0x5d, 0xb2, 0x85, 0x7a, 0x59, 0xdd, 0xaa, 0xa1, 0x7a, 0x81, 0xbc, 0x9d, + 0xfd, 0xc0, 0x35, 0xfb, 0x84, 0x2a, 0xf6, 0x4c, 0xef, 0xda, 0xdf, 0xe7, 0xe0, 0xbe, 0xfb, 0x2d, + 0x57, 0x97, 0x4c, 0x86, 0x2f, 0x99, 0x6b, 0xce, 0xcc, 0x8c, 0xc4, 0x7d, 0x28, 0x84, 0x3c, 0x4e, + 0x54, 0x15, 0xd5, 0x50, 0xbd, 0xd8, 0x6e, 0x6d, 0x52, 0x65, 0x26, 0x25, 0x07, 0x9a, 0x48, 0x52, + 0x3e, 0x1e, 0x41, 0xc1, 0x78, 0x68, 0x9c, 0x28, 0xb6, 0x3f, 0xd9, 0xd4, 0x7a, 0x97, 0x45, 0xcc, + 0xd7, 0xf7, 0x3d, 0xa5, 0x0b, 0x3a, 0x97, 0x24, 0x55, 0xc1, 0x5f, 0x80, 0x45, 0x93, 0x59, 0x28, + 0x3c, 0x5f, 0xf0, 0xaf, 0xc2, 0xc0, 0x98, 0x58, 0x6c, 0x37, 0x36, 0x50, 0xed, 0x68, 0x5a, 0xd7, + 0xb0, 0x48, 0x91, 0xbe, 0x5a, 0xd8, 0x43, 0x28, 0xdf, 0x2c, 0x1d, 0xef, 0xc3, 0x96, 0x96, 0x30, + 0xbd, 0xef, 0x3c, 0xbb, 0x43, 0xcc, 0x4a, 0xa3, 0xda, 0xf7, 0xf4, 0x4a, 0x35, 0xaa, 0x57, 0x27, + 0x65, 0xb0, 0x4c, 0xa3, 0x9e, 0x14, 0xc9, 0xc2, 0x67, 0xf6, 0xcf, 0x08, 0xf6, 0xff, 0xa9, 0x01, + 0x7c, 0x08, 0xa5, 0x1b, 0xc1, 0x49, 0xd5, 0x89, 0xb5, 0x9a, 0x9b, 0xff, 0x2d, 0x36, 0xf6, 0x9f, + 0x08, 0x8a, 0x2b, 0x8e, 0xe0, 0xe7, 0x50, 0x4e, 0x7d, 0x65, 0xdc, 0x17, 0xb3, 0x90, 0x07, 0xa6, + 0xbc, 0x72, 0xfb, 0x83, 0x4d, 0x9d, 0x75, 0x32, 0x1e, 0x29, 0xd1, 0xd5, 0xa5, 0x6e, 0x5b, 0xc6, + 0x8c, 0x7e, 0x1d, 0xf2, 0xc0, 0x24, 0xd3, 0xb4, 0x86, 0x88, 0x75, 0x0d, 0xea, 0x38, 0xe2, 0x7d, + 0x28, 0xc4, 0xa1, 0xf2, 0x2f, 0x4d, 0x73, 0x88, 0xa4, 0x0b, 0xfc, 0x3e, 0x94, 0xaf, 0x44, 0x94, + 0xcc, 0x99, 0x17, 0xd0, 0x90, 0x7b, 0xb3, 0x0b, 0x93, 0x67, 0x44, 0xac, 0x14, 0xed, 0xd3, 0x90, + 0xf7, 0x2e, 0xf0, 0x11, 0xec, 0xdd, 0x0e, 0x7e, 0xc1, 0x04, 0x7f, 0x57, 0xae, 0x25, 0xfe, 0x33, + 0xa8, 0xde, 0x0e, 0x7c, 0x36, 0x24, 0x0e, 0xa1, 0xb4, 0x4c, 0x96, 0x62, 0x3c, 0xbd, 0x7d, 0x8b, + 0x58, 0xd7, 0x51, 0xd1, 0xd8, 0xd1, 0x73, 0xd8, 0x5d, 0x73, 0x15, 0x3f, 0x84, 0x07, 0xae, 0x3b, + 0x1a, 0x7a, 0xe7, 0x93, 0x41, 0xd7, 0xf1, 0xfa, 0xce, 0xb8, 0xe7, 0x10, 0xef, 0x6c, 0xec, 0x4e, + 0x9d, 0xee, 0xe0, 0xe9, 0xc0, 0xe9, 0x55, 0xee, 0xe0, 0x7b, 0xb0, 0x35, 0xea, 0x0c, 0x9d, 0x0a, + 0xc2, 0x00, 0xdb, 0x4f, 0x1d, 0xf3, 0x9d, 0xc3, 0x45, 0xb8, 0x3b, 0x76, 0xce, 0x4e, 0x49, 0x67, + 0x58, 0xc9, 0x1f, 0x9d, 0x42, 0xe9, 0x86, 0x8d, 0xf8, 0x3d, 0x38, 0xe8, 0x9c, 0xf5, 0x06, 0x13, + 0xcf, 0x19, 0x77, 0x27, 0xbd, 0xc1, 0xb8, 0xbf, 0xa6, 0x69, 0xc1, 0xbd, 0xe1, 0x60, 0xec, 0x74, + 0x48, 0xeb, 0xe3, 0x0a, 0xc2, 0x77, 0x21, 0x3f, 0x9a, 0x3e, 0xae, 0xe4, 0x34, 0x3c, 0xe9, 0xf7, + 0xbd, 0xc9, 0xf4, 0xcc, 0xad, 0xe4, 0xdb, 0xbf, 0xe7, 0xc0, 0x3a, 0x65, 0x2f, 0xd4, 0xa9, 0x48, + 0x9b, 0xc5, 0x3f, 0x22, 0x80, 0x57, 0x03, 0x12, 0x7f, 0xb8, 0xc1, 0xed, 0xde, 0x1a, 0xb2, 0x07, + 0x1f, 0xbd, 0x21, 0x2b, 0x35, 0xd8, 0xbe, 0xff, 0xdd, 0x6f, 0x7f, 0xfc, 0x94, 0xdb, 0xc3, 0xbb, + 0xcb, 0x37, 0x21, 0x1d, 0xae, 0xf8, 0x17, 0x04, 0x95, 0xf5, 0x6b, 0xc1, 0xc7, 0x6f, 0x30, 0x71, + 0xd6, 0x86, 0xd7, 0xc1, 0x93, 0xff, 0xc4, 0xcd, 0xca, 0x3c, 0x34, 0x65, 0x3e, 0xb0, 0xab, 0xcb, + 0x32, 0x35, 0xff, 0x58, 0x2e, 0x7f, 0x7f, 0x8c, 0x8e, 0x4e, 0x7e, 0x40, 0xf0, 0xc8, 0x17, 0xf3, + 0xd7, 0x9f, 0x73, 0xb2, 0xb7, 0xea, 0xff, 0x54, 0xbf, 0x5c, 0x53, 0xf4, 0xe5, 0x28, 0xe3, 0x05, + 0x42, 0xff, 0xfb, 0x1b, 0x62, 0x11, 0x34, 0x03, 0xc6, 0xcd, 0xbb, 0xd6, 0x4c, 0xb7, 0x68, 0x1c, + 0xca, 0x7f, 0x79, 0x4e, 0x9f, 0xac, 0x82, 0x7f, 0x21, 0x74, 0xb1, 0x6d, 0xc8, 0x8f, 0xff, 0x0e, + 0x00, 0x00, 0xff, 0xff, 0x7f, 0xac, 0x4e, 0x87, 0x8a, 0x07, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/geometry.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/geometry.pb.go new file mode 100644 index 0000000000..470f3423f0 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/geometry.pb.go @@ -0,0 +1,183 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/cloud/vision/v1p2beta1/geometry.proto + +/* +Package vision is a generated protocol buffer package. + +It is generated from these files: + google/cloud/vision/v1p2beta1/geometry.proto + google/cloud/vision/v1p2beta1/image_annotator.proto + google/cloud/vision/v1p2beta1/text_annotation.proto + google/cloud/vision/v1p2beta1/web_detection.proto + +It has these top-level messages: + Vertex + BoundingPoly + Position + Feature + ImageSource + Image + FaceAnnotation + LocationInfo + Property + EntityAnnotation + SafeSearchAnnotation + LatLongRect + ColorInfo + DominantColorsAnnotation + ImageProperties + CropHint + CropHintsAnnotation + CropHintsParams + WebDetectionParams + ImageContext + AnnotateImageRequest + ImageAnnotationContext + AnnotateImageResponse + BatchAnnotateImagesRequest + BatchAnnotateImagesResponse + AsyncAnnotateFileRequest + AsyncAnnotateFileResponse + AsyncBatchAnnotateFilesRequest + AsyncBatchAnnotateFilesResponse + InputConfig + OutputConfig + GcsSource + GcsDestination + OperationMetadata + TextAnnotation + Page + Block + Paragraph + Word + Symbol + WebDetection +*/ +package vision + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// A vertex represents a 2D point in the image. +// NOTE: the vertex coordinates are in the same scale as the original image. +type Vertex struct { + // X coordinate. + X int32 `protobuf:"varint,1,opt,name=x" json:"x,omitempty"` + // Y coordinate. + Y int32 `protobuf:"varint,2,opt,name=y" json:"y,omitempty"` +} + +func (m *Vertex) Reset() { *m = Vertex{} } +func (m *Vertex) String() string { return proto.CompactTextString(m) } +func (*Vertex) ProtoMessage() {} +func (*Vertex) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Vertex) GetX() int32 { + if m != nil { + return m.X + } + return 0 +} + +func (m *Vertex) GetY() int32 { + if m != nil { + return m.Y + } + return 0 +} + +// A bounding polygon for the detected image annotation. +type BoundingPoly struct { + // The bounding polygon vertices. + Vertices []*Vertex `protobuf:"bytes,1,rep,name=vertices" json:"vertices,omitempty"` +} + +func (m *BoundingPoly) Reset() { *m = BoundingPoly{} } +func (m *BoundingPoly) String() string { return proto.CompactTextString(m) } +func (*BoundingPoly) ProtoMessage() {} +func (*BoundingPoly) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *BoundingPoly) GetVertices() []*Vertex { + if m != nil { + return m.Vertices + } + return nil +} + +// A 3D position in the image, used primarily for Face detection landmarks. +// A valid Position must have both x and y coordinates. +// The position coordinates are in the same scale as the original image. +type Position struct { + // X coordinate. + X float32 `protobuf:"fixed32,1,opt,name=x" json:"x,omitempty"` + // Y coordinate. + Y float32 `protobuf:"fixed32,2,opt,name=y" json:"y,omitempty"` + // Z coordinate (or depth). + Z float32 `protobuf:"fixed32,3,opt,name=z" json:"z,omitempty"` +} + +func (m *Position) Reset() { *m = Position{} } +func (m *Position) String() string { return proto.CompactTextString(m) } +func (*Position) ProtoMessage() {} +func (*Position) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Position) GetX() float32 { + if m != nil { + return m.X + } + return 0 +} + +func (m *Position) GetY() float32 { + if m != nil { + return m.Y + } + return 0 +} + +func (m *Position) GetZ() float32 { + if m != nil { + return m.Z + } + return 0 +} + +func init() { + proto.RegisterType((*Vertex)(nil), "google.cloud.vision.v1p2beta1.Vertex") + proto.RegisterType((*BoundingPoly)(nil), "google.cloud.vision.v1p2beta1.BoundingPoly") + proto.RegisterType((*Position)(nil), "google.cloud.vision.v1p2beta1.Position") +} + +func init() { proto.RegisterFile("google/cloud/vision/v1p2beta1/geometry.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 243 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xb1, 0x4b, 0xc3, 0x40, + 0x14, 0x87, 0x79, 0x29, 0x96, 0x72, 0xd6, 0x25, 0x53, 0x16, 0xa1, 0x06, 0x85, 0x0e, 0x72, 0x47, + 0xab, 0x9b, 0x93, 0x71, 0x70, 0x8d, 0x19, 0x1c, 0xdc, 0xd2, 0xf4, 0xf1, 0x38, 0x48, 0xef, 0x85, + 0xcb, 0x35, 0xf4, 0x8a, 0x7f, 0xb8, 0xa3, 0xf4, 0xae, 0x54, 0x1c, 0xda, 0xf1, 0x77, 0xf7, 0x3d, + 0x3e, 0xf8, 0xc4, 0x23, 0x31, 0x53, 0x8b, 0xaa, 0x69, 0x79, 0xbb, 0x56, 0x83, 0xee, 0x35, 0x1b, + 0x35, 0x2c, 0xba, 0xe5, 0x0a, 0x5d, 0xbd, 0x50, 0x84, 0xbc, 0x41, 0x67, 0xbd, 0xec, 0x2c, 0x3b, + 0x4e, 0x6f, 0x23, 0x2d, 0x03, 0x2d, 0x23, 0x2d, 0x4f, 0x74, 0x7e, 0x2f, 0xc6, 0x9f, 0x68, 0x1d, + 0xee, 0xd2, 0xa9, 0x80, 0x5d, 0x06, 0x33, 0x98, 0x5f, 0x55, 0x10, 0x96, 0xcf, 0x92, 0xb8, 0x7c, + 0xfe, 0x21, 0xa6, 0x05, 0x6f, 0xcd, 0x5a, 0x1b, 0x2a, 0xb9, 0xf5, 0xe9, 0xab, 0x98, 0x0c, 0x68, + 0x9d, 0x6e, 0xb0, 0xcf, 0x60, 0x36, 0x9a, 0x5f, 0x2f, 0x1f, 0xe4, 0x45, 0x8f, 0x8c, 0x92, 0xea, + 0x74, 0x96, 0x3f, 0x8b, 0x49, 0xc9, 0xbd, 0x76, 0x9a, 0xcd, 0x9f, 0x3a, 0xf9, 0xa7, 0x4e, 0x2a, + 0xf0, 0x87, 0xb5, 0xcf, 0x46, 0x71, 0xed, 0x8b, 0x6f, 0x71, 0xd7, 0xf0, 0xe6, 0xb2, 0xab, 0xb8, + 0x79, 0x3f, 0x26, 0x28, 0x0f, 0x05, 0x4a, 0xf8, 0x7a, 0x3b, 0xf2, 0xc4, 0x6d, 0x6d, 0x48, 0xb2, + 0x25, 0x45, 0x68, 0x42, 0x1f, 0x15, 0xbf, 0xea, 0x4e, 0xf7, 0x67, 0x82, 0xbe, 0xc4, 0x87, 0x1f, + 0x80, 0xd5, 0x38, 0x9c, 0x3c, 0xfd, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5a, 0xa2, 0xee, 0x2b, 0x82, + 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/image_annotator.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/image_annotator.pb.go new file mode 100644 index 0000000000..e06fe9c7d1 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/image_annotator.pb.go @@ -0,0 +1,1933 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/cloud/vision/v1p2beta1/image_annotator.proto + +package vision + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import google_longrunning "google.golang.org/genproto/googleapis/longrunning" +import google_protobuf3 "github.com/golang/protobuf/ptypes/timestamp" +import google_rpc "google.golang.org/genproto/googleapis/rpc/status" +import google_type "google.golang.org/genproto/googleapis/type/color" +import google_type1 "google.golang.org/genproto/googleapis/type/latlng" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// A bucketized representation of likelihood, which is intended to give clients +// highly stable results across model upgrades. +type Likelihood int32 + +const ( + // Unknown likelihood. + Likelihood_UNKNOWN Likelihood = 0 + // It is very unlikely that the image belongs to the specified vertical. + Likelihood_VERY_UNLIKELY Likelihood = 1 + // It is unlikely that the image belongs to the specified vertical. + Likelihood_UNLIKELY Likelihood = 2 + // It is possible that the image belongs to the specified vertical. + Likelihood_POSSIBLE Likelihood = 3 + // It is likely that the image belongs to the specified vertical. + Likelihood_LIKELY Likelihood = 4 + // It is very likely that the image belongs to the specified vertical. + Likelihood_VERY_LIKELY Likelihood = 5 +) + +var Likelihood_name = map[int32]string{ + 0: "UNKNOWN", + 1: "VERY_UNLIKELY", + 2: "UNLIKELY", + 3: "POSSIBLE", + 4: "LIKELY", + 5: "VERY_LIKELY", +} +var Likelihood_value = map[string]int32{ + "UNKNOWN": 0, + "VERY_UNLIKELY": 1, + "UNLIKELY": 2, + "POSSIBLE": 3, + "LIKELY": 4, + "VERY_LIKELY": 5, +} + +func (x Likelihood) String() string { + return proto.EnumName(Likelihood_name, int32(x)) +} +func (Likelihood) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +// Type of Google Cloud Vision API feature to be extracted. +type Feature_Type int32 + +const ( + // Unspecified feature type. + Feature_TYPE_UNSPECIFIED Feature_Type = 0 + // Run face detection. + Feature_FACE_DETECTION Feature_Type = 1 + // Run landmark detection. + Feature_LANDMARK_DETECTION Feature_Type = 2 + // Run logo detection. + Feature_LOGO_DETECTION Feature_Type = 3 + // Run label detection. + Feature_LABEL_DETECTION Feature_Type = 4 + // Run text detection / optical character recognition (OCR). Text detection + // is optimized for areas of text within a larger image; if the image is + // a document, use `DOCUMENT_TEXT_DETECTION` instead. + Feature_TEXT_DETECTION Feature_Type = 5 + // Run dense text document OCR. Takes precedence when both + // `DOCUMENT_TEXT_DETECTION` and `TEXT_DETECTION` are present. + Feature_DOCUMENT_TEXT_DETECTION Feature_Type = 11 + // Run Safe Search to detect potentially unsafe + // or undesirable content. + Feature_SAFE_SEARCH_DETECTION Feature_Type = 6 + // Compute a set of image properties, such as the + // image's dominant colors. + Feature_IMAGE_PROPERTIES Feature_Type = 7 + // Run crop hints. + Feature_CROP_HINTS Feature_Type = 9 + // Run web detection. + Feature_WEB_DETECTION Feature_Type = 10 +) + +var Feature_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "FACE_DETECTION", + 2: "LANDMARK_DETECTION", + 3: "LOGO_DETECTION", + 4: "LABEL_DETECTION", + 5: "TEXT_DETECTION", + 11: "DOCUMENT_TEXT_DETECTION", + 6: "SAFE_SEARCH_DETECTION", + 7: "IMAGE_PROPERTIES", + 9: "CROP_HINTS", + 10: "WEB_DETECTION", +} +var Feature_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "FACE_DETECTION": 1, + "LANDMARK_DETECTION": 2, + "LOGO_DETECTION": 3, + "LABEL_DETECTION": 4, + "TEXT_DETECTION": 5, + "DOCUMENT_TEXT_DETECTION": 11, + "SAFE_SEARCH_DETECTION": 6, + "IMAGE_PROPERTIES": 7, + "CROP_HINTS": 9, + "WEB_DETECTION": 10, +} + +func (x Feature_Type) String() string { + return proto.EnumName(Feature_Type_name, int32(x)) +} +func (Feature_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0, 0} } + +// Face landmark (feature) type. +// Left and right are defined from the vantage of the viewer of the image +// without considering mirror projections typical of photos. So, `LEFT_EYE`, +// typically, is the person's right eye. +type FaceAnnotation_Landmark_Type int32 + +const ( + // Unknown face landmark detected. Should not be filled. + FaceAnnotation_Landmark_UNKNOWN_LANDMARK FaceAnnotation_Landmark_Type = 0 + // Left eye. + FaceAnnotation_Landmark_LEFT_EYE FaceAnnotation_Landmark_Type = 1 + // Right eye. + FaceAnnotation_Landmark_RIGHT_EYE FaceAnnotation_Landmark_Type = 2 + // Left of left eyebrow. + FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW FaceAnnotation_Landmark_Type = 3 + // Right of left eyebrow. + FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW FaceAnnotation_Landmark_Type = 4 + // Left of right eyebrow. + FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW FaceAnnotation_Landmark_Type = 5 + // Right of right eyebrow. + FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW FaceAnnotation_Landmark_Type = 6 + // Midpoint between eyes. + FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES FaceAnnotation_Landmark_Type = 7 + // Nose tip. + FaceAnnotation_Landmark_NOSE_TIP FaceAnnotation_Landmark_Type = 8 + // Upper lip. + FaceAnnotation_Landmark_UPPER_LIP FaceAnnotation_Landmark_Type = 9 + // Lower lip. + FaceAnnotation_Landmark_LOWER_LIP FaceAnnotation_Landmark_Type = 10 + // Mouth left. + FaceAnnotation_Landmark_MOUTH_LEFT FaceAnnotation_Landmark_Type = 11 + // Mouth right. + FaceAnnotation_Landmark_MOUTH_RIGHT FaceAnnotation_Landmark_Type = 12 + // Mouth center. + FaceAnnotation_Landmark_MOUTH_CENTER FaceAnnotation_Landmark_Type = 13 + // Nose, bottom right. + FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT FaceAnnotation_Landmark_Type = 14 + // Nose, bottom left. + FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT FaceAnnotation_Landmark_Type = 15 + // Nose, bottom center. + FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER FaceAnnotation_Landmark_Type = 16 + // Left eye, top boundary. + FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY FaceAnnotation_Landmark_Type = 17 + // Left eye, right corner. + FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER FaceAnnotation_Landmark_Type = 18 + // Left eye, bottom boundary. + FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY FaceAnnotation_Landmark_Type = 19 + // Left eye, left corner. + FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER FaceAnnotation_Landmark_Type = 20 + // Right eye, top boundary. + FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY FaceAnnotation_Landmark_Type = 21 + // Right eye, right corner. + FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER FaceAnnotation_Landmark_Type = 22 + // Right eye, bottom boundary. + FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY FaceAnnotation_Landmark_Type = 23 + // Right eye, left corner. + FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER FaceAnnotation_Landmark_Type = 24 + // Left eyebrow, upper midpoint. + FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT FaceAnnotation_Landmark_Type = 25 + // Right eyebrow, upper midpoint. + FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT FaceAnnotation_Landmark_Type = 26 + // Left ear tragion. + FaceAnnotation_Landmark_LEFT_EAR_TRAGION FaceAnnotation_Landmark_Type = 27 + // Right ear tragion. + FaceAnnotation_Landmark_RIGHT_EAR_TRAGION FaceAnnotation_Landmark_Type = 28 + // Left eye pupil. + FaceAnnotation_Landmark_LEFT_EYE_PUPIL FaceAnnotation_Landmark_Type = 29 + // Right eye pupil. + FaceAnnotation_Landmark_RIGHT_EYE_PUPIL FaceAnnotation_Landmark_Type = 30 + // Forehead glabella. + FaceAnnotation_Landmark_FOREHEAD_GLABELLA FaceAnnotation_Landmark_Type = 31 + // Chin gnathion. + FaceAnnotation_Landmark_CHIN_GNATHION FaceAnnotation_Landmark_Type = 32 + // Chin left gonion. + FaceAnnotation_Landmark_CHIN_LEFT_GONION FaceAnnotation_Landmark_Type = 33 + // Chin right gonion. + FaceAnnotation_Landmark_CHIN_RIGHT_GONION FaceAnnotation_Landmark_Type = 34 +) + +var FaceAnnotation_Landmark_Type_name = map[int32]string{ + 0: "UNKNOWN_LANDMARK", + 1: "LEFT_EYE", + 2: "RIGHT_EYE", + 3: "LEFT_OF_LEFT_EYEBROW", + 4: "RIGHT_OF_LEFT_EYEBROW", + 5: "LEFT_OF_RIGHT_EYEBROW", + 6: "RIGHT_OF_RIGHT_EYEBROW", + 7: "MIDPOINT_BETWEEN_EYES", + 8: "NOSE_TIP", + 9: "UPPER_LIP", + 10: "LOWER_LIP", + 11: "MOUTH_LEFT", + 12: "MOUTH_RIGHT", + 13: "MOUTH_CENTER", + 14: "NOSE_BOTTOM_RIGHT", + 15: "NOSE_BOTTOM_LEFT", + 16: "NOSE_BOTTOM_CENTER", + 17: "LEFT_EYE_TOP_BOUNDARY", + 18: "LEFT_EYE_RIGHT_CORNER", + 19: "LEFT_EYE_BOTTOM_BOUNDARY", + 20: "LEFT_EYE_LEFT_CORNER", + 21: "RIGHT_EYE_TOP_BOUNDARY", + 22: "RIGHT_EYE_RIGHT_CORNER", + 23: "RIGHT_EYE_BOTTOM_BOUNDARY", + 24: "RIGHT_EYE_LEFT_CORNER", + 25: "LEFT_EYEBROW_UPPER_MIDPOINT", + 26: "RIGHT_EYEBROW_UPPER_MIDPOINT", + 27: "LEFT_EAR_TRAGION", + 28: "RIGHT_EAR_TRAGION", + 29: "LEFT_EYE_PUPIL", + 30: "RIGHT_EYE_PUPIL", + 31: "FOREHEAD_GLABELLA", + 32: "CHIN_GNATHION", + 33: "CHIN_LEFT_GONION", + 34: "CHIN_RIGHT_GONION", +} +var FaceAnnotation_Landmark_Type_value = map[string]int32{ + "UNKNOWN_LANDMARK": 0, + "LEFT_EYE": 1, + "RIGHT_EYE": 2, + "LEFT_OF_LEFT_EYEBROW": 3, + "RIGHT_OF_LEFT_EYEBROW": 4, + "LEFT_OF_RIGHT_EYEBROW": 5, + "RIGHT_OF_RIGHT_EYEBROW": 6, + "MIDPOINT_BETWEEN_EYES": 7, + "NOSE_TIP": 8, + "UPPER_LIP": 9, + "LOWER_LIP": 10, + "MOUTH_LEFT": 11, + "MOUTH_RIGHT": 12, + "MOUTH_CENTER": 13, + "NOSE_BOTTOM_RIGHT": 14, + "NOSE_BOTTOM_LEFT": 15, + "NOSE_BOTTOM_CENTER": 16, + "LEFT_EYE_TOP_BOUNDARY": 17, + "LEFT_EYE_RIGHT_CORNER": 18, + "LEFT_EYE_BOTTOM_BOUNDARY": 19, + "LEFT_EYE_LEFT_CORNER": 20, + "RIGHT_EYE_TOP_BOUNDARY": 21, + "RIGHT_EYE_RIGHT_CORNER": 22, + "RIGHT_EYE_BOTTOM_BOUNDARY": 23, + "RIGHT_EYE_LEFT_CORNER": 24, + "LEFT_EYEBROW_UPPER_MIDPOINT": 25, + "RIGHT_EYEBROW_UPPER_MIDPOINT": 26, + "LEFT_EAR_TRAGION": 27, + "RIGHT_EAR_TRAGION": 28, + "LEFT_EYE_PUPIL": 29, + "RIGHT_EYE_PUPIL": 30, + "FOREHEAD_GLABELLA": 31, + "CHIN_GNATHION": 32, + "CHIN_LEFT_GONION": 33, + "CHIN_RIGHT_GONION": 34, +} + +func (x FaceAnnotation_Landmark_Type) String() string { + return proto.EnumName(FaceAnnotation_Landmark_Type_name, int32(x)) +} +func (FaceAnnotation_Landmark_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor1, []int{3, 0, 0} +} + +// Batch operation states. +type OperationMetadata_State int32 + +const ( + // Invalid. + OperationMetadata_STATE_UNSPECIFIED OperationMetadata_State = 0 + // Request is received. + OperationMetadata_CREATED OperationMetadata_State = 1 + // Request is actively being processed. + OperationMetadata_RUNNING OperationMetadata_State = 2 + // The batch processing is done. + OperationMetadata_DONE OperationMetadata_State = 3 + // The batch processing was cancelled. + OperationMetadata_CANCELLED OperationMetadata_State = 4 +) + +var OperationMetadata_State_name = map[int32]string{ + 0: "STATE_UNSPECIFIED", + 1: "CREATED", + 2: "RUNNING", + 3: "DONE", + 4: "CANCELLED", +} +var OperationMetadata_State_value = map[string]int32{ + "STATE_UNSPECIFIED": 0, + "CREATED": 1, + "RUNNING": 2, + "DONE": 3, + "CANCELLED": 4, +} + +func (x OperationMetadata_State) String() string { + return proto.EnumName(OperationMetadata_State_name, int32(x)) +} +func (OperationMetadata_State) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{30, 0} } + +// The type of Google Cloud Vision API detection to perform, and the maximum +// number of results to return for that type. Multiple `Feature` objects can +// be specified in the `features` list. +type Feature struct { + // The feature type. + Type Feature_Type `protobuf:"varint,1,opt,name=type,enum=google.cloud.vision.v1p2beta1.Feature_Type" json:"type,omitempty"` + // Maximum number of results of this type. Does not apply to + // `TEXT_DETECTION`, `DOCUMENT_TEXT_DETECTION`, or `CROP_HINTS`. + MaxResults int32 `protobuf:"varint,2,opt,name=max_results,json=maxResults" json:"max_results,omitempty"` + // Model to use for the feature. + // Supported values: "builtin/stable" (the default if unset) and + // "builtin/latest". + Model string `protobuf:"bytes,3,opt,name=model" json:"model,omitempty"` +} + +func (m *Feature) Reset() { *m = Feature{} } +func (m *Feature) String() string { return proto.CompactTextString(m) } +func (*Feature) ProtoMessage() {} +func (*Feature) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *Feature) GetType() Feature_Type { + if m != nil { + return m.Type + } + return Feature_TYPE_UNSPECIFIED +} + +func (m *Feature) GetMaxResults() int32 { + if m != nil { + return m.MaxResults + } + return 0 +} + +func (m *Feature) GetModel() string { + if m != nil { + return m.Model + } + return "" +} + +// External image source (Google Cloud Storage or web URL image location). +type ImageSource struct { + // **Use `image_uri` instead.** + // + // The Google Cloud Storage URI of the form + // `gs://bucket_name/object_name`. Object versioning is not supported. See + // [Google Cloud Storage Request + // URIs](https://cloud.google.com/storage/docs/reference-uris) for more info. + GcsImageUri string `protobuf:"bytes,1,opt,name=gcs_image_uri,json=gcsImageUri" json:"gcs_image_uri,omitempty"` + // The URI of the source image. Can be either: + // + // 1. A Google Cloud Storage URI of the form + // `gs://bucket_name/object_name`. Object versioning is not supported. See + // [Google Cloud Storage Request + // URIs](https://cloud.google.com/storage/docs/reference-uris) for more + // info. + // + // 2. A publicly-accessible image HTTP/HTTPS URL. When fetching images from + // HTTP/HTTPS URLs, Google cannot guarantee that the request will be + // completed. Your request may fail if the specified host denies the + // request (e.g. due to request throttling or DOS prevention), or if Google + // throttles requests to the site for abuse prevention. You should not + // depend on externally-hosted images for production applications. + // + // When both `gcs_image_uri` and `image_uri` are specified, `image_uri` takes + // precedence. + ImageUri string `protobuf:"bytes,2,opt,name=image_uri,json=imageUri" json:"image_uri,omitempty"` +} + +func (m *ImageSource) Reset() { *m = ImageSource{} } +func (m *ImageSource) String() string { return proto.CompactTextString(m) } +func (*ImageSource) ProtoMessage() {} +func (*ImageSource) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *ImageSource) GetGcsImageUri() string { + if m != nil { + return m.GcsImageUri + } + return "" +} + +func (m *ImageSource) GetImageUri() string { + if m != nil { + return m.ImageUri + } + return "" +} + +// Client image to perform Google Cloud Vision API tasks over. +type Image struct { + // Image content, represented as a stream of bytes. + // Note: As with all `bytes` fields, protobuffers use a pure binary + // representation, whereas JSON representations use base64. + Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + // Google Cloud Storage image location, or publicly-accessible image + // URL. If both `content` and `source` are provided for an image, `content` + // takes precedence and is used to perform the image annotation request. + Source *ImageSource `protobuf:"bytes,2,opt,name=source" json:"source,omitempty"` +} + +func (m *Image) Reset() { *m = Image{} } +func (m *Image) String() string { return proto.CompactTextString(m) } +func (*Image) ProtoMessage() {} +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } + +func (m *Image) GetContent() []byte { + if m != nil { + return m.Content + } + return nil +} + +func (m *Image) GetSource() *ImageSource { + if m != nil { + return m.Source + } + return nil +} + +// A face annotation object contains the results of face detection. +type FaceAnnotation struct { + // The bounding polygon around the face. The coordinates of the bounding box + // are in the original image's scale, as returned in `ImageParams`. + // The bounding box is computed to "frame" the face in accordance with human + // expectations. It is based on the landmarker results. + // Note that one or more x and/or y coordinates may not be generated in the + // `BoundingPoly` (the polygon will be unbounded) if only a partial face + // appears in the image to be annotated. + BoundingPoly *BoundingPoly `protobuf:"bytes,1,opt,name=bounding_poly,json=boundingPoly" json:"bounding_poly,omitempty"` + // The `fd_bounding_poly` bounding polygon is tighter than the + // `boundingPoly`, and encloses only the skin part of the face. Typically, it + // is used to eliminate the face from any image analysis that detects the + // "amount of skin" visible in an image. It is not based on the + // landmarker results, only on the initial face detection, hence + // the fd (face detection) prefix. + FdBoundingPoly *BoundingPoly `protobuf:"bytes,2,opt,name=fd_bounding_poly,json=fdBoundingPoly" json:"fd_bounding_poly,omitempty"` + // Detected face landmarks. + Landmarks []*FaceAnnotation_Landmark `protobuf:"bytes,3,rep,name=landmarks" json:"landmarks,omitempty"` + // Roll angle, which indicates the amount of clockwise/anti-clockwise rotation + // of the face relative to the image vertical about the axis perpendicular to + // the face. Range [-180,180]. + RollAngle float32 `protobuf:"fixed32,4,opt,name=roll_angle,json=rollAngle" json:"roll_angle,omitempty"` + // Yaw angle, which indicates the leftward/rightward angle that the face is + // pointing relative to the vertical plane perpendicular to the image. Range + // [-180,180]. + PanAngle float32 `protobuf:"fixed32,5,opt,name=pan_angle,json=panAngle" json:"pan_angle,omitempty"` + // Pitch angle, which indicates the upwards/downwards angle that the face is + // pointing relative to the image's horizontal plane. Range [-180,180]. + TiltAngle float32 `protobuf:"fixed32,6,opt,name=tilt_angle,json=tiltAngle" json:"tilt_angle,omitempty"` + // Detection confidence. Range [0, 1]. + DetectionConfidence float32 `protobuf:"fixed32,7,opt,name=detection_confidence,json=detectionConfidence" json:"detection_confidence,omitempty"` + // Face landmarking confidence. Range [0, 1]. + LandmarkingConfidence float32 `protobuf:"fixed32,8,opt,name=landmarking_confidence,json=landmarkingConfidence" json:"landmarking_confidence,omitempty"` + // Joy likelihood. + JoyLikelihood Likelihood `protobuf:"varint,9,opt,name=joy_likelihood,json=joyLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"joy_likelihood,omitempty"` + // Sorrow likelihood. + SorrowLikelihood Likelihood `protobuf:"varint,10,opt,name=sorrow_likelihood,json=sorrowLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"sorrow_likelihood,omitempty"` + // Anger likelihood. + AngerLikelihood Likelihood `protobuf:"varint,11,opt,name=anger_likelihood,json=angerLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"anger_likelihood,omitempty"` + // Surprise likelihood. + SurpriseLikelihood Likelihood `protobuf:"varint,12,opt,name=surprise_likelihood,json=surpriseLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"surprise_likelihood,omitempty"` + // Under-exposed likelihood. + UnderExposedLikelihood Likelihood `protobuf:"varint,13,opt,name=under_exposed_likelihood,json=underExposedLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"under_exposed_likelihood,omitempty"` + // Blurred likelihood. + BlurredLikelihood Likelihood `protobuf:"varint,14,opt,name=blurred_likelihood,json=blurredLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"blurred_likelihood,omitempty"` + // Headwear likelihood. + HeadwearLikelihood Likelihood `protobuf:"varint,15,opt,name=headwear_likelihood,json=headwearLikelihood,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"headwear_likelihood,omitempty"` +} + +func (m *FaceAnnotation) Reset() { *m = FaceAnnotation{} } +func (m *FaceAnnotation) String() string { return proto.CompactTextString(m) } +func (*FaceAnnotation) ProtoMessage() {} +func (*FaceAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } + +func (m *FaceAnnotation) GetBoundingPoly() *BoundingPoly { + if m != nil { + return m.BoundingPoly + } + return nil +} + +func (m *FaceAnnotation) GetFdBoundingPoly() *BoundingPoly { + if m != nil { + return m.FdBoundingPoly + } + return nil +} + +func (m *FaceAnnotation) GetLandmarks() []*FaceAnnotation_Landmark { + if m != nil { + return m.Landmarks + } + return nil +} + +func (m *FaceAnnotation) GetRollAngle() float32 { + if m != nil { + return m.RollAngle + } + return 0 +} + +func (m *FaceAnnotation) GetPanAngle() float32 { + if m != nil { + return m.PanAngle + } + return 0 +} + +func (m *FaceAnnotation) GetTiltAngle() float32 { + if m != nil { + return m.TiltAngle + } + return 0 +} + +func (m *FaceAnnotation) GetDetectionConfidence() float32 { + if m != nil { + return m.DetectionConfidence + } + return 0 +} + +func (m *FaceAnnotation) GetLandmarkingConfidence() float32 { + if m != nil { + return m.LandmarkingConfidence + } + return 0 +} + +func (m *FaceAnnotation) GetJoyLikelihood() Likelihood { + if m != nil { + return m.JoyLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetSorrowLikelihood() Likelihood { + if m != nil { + return m.SorrowLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetAngerLikelihood() Likelihood { + if m != nil { + return m.AngerLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetSurpriseLikelihood() Likelihood { + if m != nil { + return m.SurpriseLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetUnderExposedLikelihood() Likelihood { + if m != nil { + return m.UnderExposedLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetBlurredLikelihood() Likelihood { + if m != nil { + return m.BlurredLikelihood + } + return Likelihood_UNKNOWN +} + +func (m *FaceAnnotation) GetHeadwearLikelihood() Likelihood { + if m != nil { + return m.HeadwearLikelihood + } + return Likelihood_UNKNOWN +} + +// A face-specific landmark (for example, a face feature). +type FaceAnnotation_Landmark struct { + // Face landmark type. + Type FaceAnnotation_Landmark_Type `protobuf:"varint,3,opt,name=type,enum=google.cloud.vision.v1p2beta1.FaceAnnotation_Landmark_Type" json:"type,omitempty"` + // Face landmark position. + Position *Position `protobuf:"bytes,4,opt,name=position" json:"position,omitempty"` +} + +func (m *FaceAnnotation_Landmark) Reset() { *m = FaceAnnotation_Landmark{} } +func (m *FaceAnnotation_Landmark) String() string { return proto.CompactTextString(m) } +func (*FaceAnnotation_Landmark) ProtoMessage() {} +func (*FaceAnnotation_Landmark) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3, 0} } + +func (m *FaceAnnotation_Landmark) GetType() FaceAnnotation_Landmark_Type { + if m != nil { + return m.Type + } + return FaceAnnotation_Landmark_UNKNOWN_LANDMARK +} + +func (m *FaceAnnotation_Landmark) GetPosition() *Position { + if m != nil { + return m.Position + } + return nil +} + +// Detected entity location information. +type LocationInfo struct { + // lat/long location coordinates. + LatLng *google_type1.LatLng `protobuf:"bytes,1,opt,name=lat_lng,json=latLng" json:"lat_lng,omitempty"` +} + +func (m *LocationInfo) Reset() { *m = LocationInfo{} } +func (m *LocationInfo) String() string { return proto.CompactTextString(m) } +func (*LocationInfo) ProtoMessage() {} +func (*LocationInfo) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } + +func (m *LocationInfo) GetLatLng() *google_type1.LatLng { + if m != nil { + return m.LatLng + } + return nil +} + +// A `Property` consists of a user-supplied name/value pair. +type Property struct { + // Name of the property. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Value of the property. + Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + // Value of numeric properties. + Uint64Value uint64 `protobuf:"varint,3,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"` +} + +func (m *Property) Reset() { *m = Property{} } +func (m *Property) String() string { return proto.CompactTextString(m) } +func (*Property) ProtoMessage() {} +func (*Property) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } + +func (m *Property) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Property) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *Property) GetUint64Value() uint64 { + if m != nil { + return m.Uint64Value + } + return 0 +} + +// Set of detected entity features. +type EntityAnnotation struct { + // Opaque entity ID. Some IDs may be available in + // [Google Knowledge Graph Search + // API](https://developers.google.com/knowledge-graph/). + Mid string `protobuf:"bytes,1,opt,name=mid" json:"mid,omitempty"` + // The language code for the locale in which the entity textual + // `description` is expressed. + Locale string `protobuf:"bytes,2,opt,name=locale" json:"locale,omitempty"` + // Entity textual description, expressed in its `locale` language. + Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` + // Overall score of the result. Range [0, 1]. + Score float32 `protobuf:"fixed32,4,opt,name=score" json:"score,omitempty"` + // **Deprecated. Use `score` instead.** + // The accuracy of the entity detection in an image. + // For example, for an image in which the "Eiffel Tower" entity is detected, + // this field represents the confidence that there is a tower in the query + // image. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,5,opt,name=confidence" json:"confidence,omitempty"` + // The relevancy of the ICA (Image Content Annotation) label to the + // image. For example, the relevancy of "tower" is likely higher to an image + // containing the detected "Eiffel Tower" than to an image containing a + // detected distant towering building, even though the confidence that + // there is a tower in each image may be the same. Range [0, 1]. + Topicality float32 `protobuf:"fixed32,6,opt,name=topicality" json:"topicality,omitempty"` + // Image region to which this entity belongs. Not produced + // for `LABEL_DETECTION` features. + BoundingPoly *BoundingPoly `protobuf:"bytes,7,opt,name=bounding_poly,json=boundingPoly" json:"bounding_poly,omitempty"` + // The location information for the detected entity. Multiple + // `LocationInfo` elements can be present because one location may + // indicate the location of the scene in the image, and another location + // may indicate the location of the place where the image was taken. + // Location information is usually present for landmarks. + Locations []*LocationInfo `protobuf:"bytes,8,rep,name=locations" json:"locations,omitempty"` + // Some entities may have optional user-supplied `Property` (name/value) + // fields, such a score or string that qualifies the entity. + Properties []*Property `protobuf:"bytes,9,rep,name=properties" json:"properties,omitempty"` +} + +func (m *EntityAnnotation) Reset() { *m = EntityAnnotation{} } +func (m *EntityAnnotation) String() string { return proto.CompactTextString(m) } +func (*EntityAnnotation) ProtoMessage() {} +func (*EntityAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } + +func (m *EntityAnnotation) GetMid() string { + if m != nil { + return m.Mid + } + return "" +} + +func (m *EntityAnnotation) GetLocale() string { + if m != nil { + return m.Locale + } + return "" +} + +func (m *EntityAnnotation) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *EntityAnnotation) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *EntityAnnotation) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +func (m *EntityAnnotation) GetTopicality() float32 { + if m != nil { + return m.Topicality + } + return 0 +} + +func (m *EntityAnnotation) GetBoundingPoly() *BoundingPoly { + if m != nil { + return m.BoundingPoly + } + return nil +} + +func (m *EntityAnnotation) GetLocations() []*LocationInfo { + if m != nil { + return m.Locations + } + return nil +} + +func (m *EntityAnnotation) GetProperties() []*Property { + if m != nil { + return m.Properties + } + return nil +} + +// Set of features pertaining to the image, computed by computer vision +// methods over safe-search verticals (for example, adult, spoof, medical, +// violence). +type SafeSearchAnnotation struct { + // Represents the adult content likelihood for the image. Adult content may + // contain elements such as nudity, pornographic images or cartoons, or + // sexual activities. + Adult Likelihood `protobuf:"varint,1,opt,name=adult,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"adult,omitempty"` + // Spoof likelihood. The likelihood that an modification + // was made to the image's canonical version to make it appear + // funny or offensive. + Spoof Likelihood `protobuf:"varint,2,opt,name=spoof,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"spoof,omitempty"` + // Likelihood that this is a medical image. + Medical Likelihood `protobuf:"varint,3,opt,name=medical,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"medical,omitempty"` + // Likelihood that this image contains violent content. + Violence Likelihood `protobuf:"varint,4,opt,name=violence,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"violence,omitempty"` + // Likelihood that the request image contains racy content. Racy content may + // include (but is not limited to) skimpy or sheer clothing, strategically + // covered nudity, lewd or provocative poses, or close-ups of sensitive + // body areas. + Racy Likelihood `protobuf:"varint,9,opt,name=racy,enum=google.cloud.vision.v1p2beta1.Likelihood" json:"racy,omitempty"` +} + +func (m *SafeSearchAnnotation) Reset() { *m = SafeSearchAnnotation{} } +func (m *SafeSearchAnnotation) String() string { return proto.CompactTextString(m) } +func (*SafeSearchAnnotation) ProtoMessage() {} +func (*SafeSearchAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} } + +func (m *SafeSearchAnnotation) GetAdult() Likelihood { + if m != nil { + return m.Adult + } + return Likelihood_UNKNOWN +} + +func (m *SafeSearchAnnotation) GetSpoof() Likelihood { + if m != nil { + return m.Spoof + } + return Likelihood_UNKNOWN +} + +func (m *SafeSearchAnnotation) GetMedical() Likelihood { + if m != nil { + return m.Medical + } + return Likelihood_UNKNOWN +} + +func (m *SafeSearchAnnotation) GetViolence() Likelihood { + if m != nil { + return m.Violence + } + return Likelihood_UNKNOWN +} + +func (m *SafeSearchAnnotation) GetRacy() Likelihood { + if m != nil { + return m.Racy + } + return Likelihood_UNKNOWN +} + +// Rectangle determined by min and max `LatLng` pairs. +type LatLongRect struct { + // Min lat/long pair. + MinLatLng *google_type1.LatLng `protobuf:"bytes,1,opt,name=min_lat_lng,json=minLatLng" json:"min_lat_lng,omitempty"` + // Max lat/long pair. + MaxLatLng *google_type1.LatLng `protobuf:"bytes,2,opt,name=max_lat_lng,json=maxLatLng" json:"max_lat_lng,omitempty"` +} + +func (m *LatLongRect) Reset() { *m = LatLongRect{} } +func (m *LatLongRect) String() string { return proto.CompactTextString(m) } +func (*LatLongRect) ProtoMessage() {} +func (*LatLongRect) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} } + +func (m *LatLongRect) GetMinLatLng() *google_type1.LatLng { + if m != nil { + return m.MinLatLng + } + return nil +} + +func (m *LatLongRect) GetMaxLatLng() *google_type1.LatLng { + if m != nil { + return m.MaxLatLng + } + return nil +} + +// Color information consists of RGB channels, score, and the fraction of +// the image that the color occupies in the image. +type ColorInfo struct { + // RGB components of the color. + Color *google_type.Color `protobuf:"bytes,1,opt,name=color" json:"color,omitempty"` + // Image-specific score for this color. Value in range [0, 1]. + Score float32 `protobuf:"fixed32,2,opt,name=score" json:"score,omitempty"` + // The fraction of pixels the color occupies in the image. + // Value in range [0, 1]. + PixelFraction float32 `protobuf:"fixed32,3,opt,name=pixel_fraction,json=pixelFraction" json:"pixel_fraction,omitempty"` +} + +func (m *ColorInfo) Reset() { *m = ColorInfo{} } +func (m *ColorInfo) String() string { return proto.CompactTextString(m) } +func (*ColorInfo) ProtoMessage() {} +func (*ColorInfo) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} } + +func (m *ColorInfo) GetColor() *google_type.Color { + if m != nil { + return m.Color + } + return nil +} + +func (m *ColorInfo) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *ColorInfo) GetPixelFraction() float32 { + if m != nil { + return m.PixelFraction + } + return 0 +} + +// Set of dominant colors and their corresponding scores. +type DominantColorsAnnotation struct { + // RGB color values with their score and pixel fraction. + Colors []*ColorInfo `protobuf:"bytes,1,rep,name=colors" json:"colors,omitempty"` +} + +func (m *DominantColorsAnnotation) Reset() { *m = DominantColorsAnnotation{} } +func (m *DominantColorsAnnotation) String() string { return proto.CompactTextString(m) } +func (*DominantColorsAnnotation) ProtoMessage() {} +func (*DominantColorsAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{10} } + +func (m *DominantColorsAnnotation) GetColors() []*ColorInfo { + if m != nil { + return m.Colors + } + return nil +} + +// Stores image properties, such as dominant colors. +type ImageProperties struct { + // If present, dominant colors completed successfully. + DominantColors *DominantColorsAnnotation `protobuf:"bytes,1,opt,name=dominant_colors,json=dominantColors" json:"dominant_colors,omitempty"` +} + +func (m *ImageProperties) Reset() { *m = ImageProperties{} } +func (m *ImageProperties) String() string { return proto.CompactTextString(m) } +func (*ImageProperties) ProtoMessage() {} +func (*ImageProperties) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{11} } + +func (m *ImageProperties) GetDominantColors() *DominantColorsAnnotation { + if m != nil { + return m.DominantColors + } + return nil +} + +// Single crop hint that is used to generate a new crop when serving an image. +type CropHint struct { + // The bounding polygon for the crop region. The coordinates of the bounding + // box are in the original image's scale, as returned in `ImageParams`. + BoundingPoly *BoundingPoly `protobuf:"bytes,1,opt,name=bounding_poly,json=boundingPoly" json:"bounding_poly,omitempty"` + // Confidence of this being a salient region. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,2,opt,name=confidence" json:"confidence,omitempty"` + // Fraction of importance of this salient region with respect to the original + // image. + ImportanceFraction float32 `protobuf:"fixed32,3,opt,name=importance_fraction,json=importanceFraction" json:"importance_fraction,omitempty"` +} + +func (m *CropHint) Reset() { *m = CropHint{} } +func (m *CropHint) String() string { return proto.CompactTextString(m) } +func (*CropHint) ProtoMessage() {} +func (*CropHint) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{12} } + +func (m *CropHint) GetBoundingPoly() *BoundingPoly { + if m != nil { + return m.BoundingPoly + } + return nil +} + +func (m *CropHint) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +func (m *CropHint) GetImportanceFraction() float32 { + if m != nil { + return m.ImportanceFraction + } + return 0 +} + +// Set of crop hints that are used to generate new crops when serving images. +type CropHintsAnnotation struct { + // Crop hint results. + CropHints []*CropHint `protobuf:"bytes,1,rep,name=crop_hints,json=cropHints" json:"crop_hints,omitempty"` +} + +func (m *CropHintsAnnotation) Reset() { *m = CropHintsAnnotation{} } +func (m *CropHintsAnnotation) String() string { return proto.CompactTextString(m) } +func (*CropHintsAnnotation) ProtoMessage() {} +func (*CropHintsAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{13} } + +func (m *CropHintsAnnotation) GetCropHints() []*CropHint { + if m != nil { + return m.CropHints + } + return nil +} + +// Parameters for crop hints annotation request. +type CropHintsParams struct { + // Aspect ratios in floats, representing the ratio of the width to the height + // of the image. For example, if the desired aspect ratio is 4/3, the + // corresponding float value should be 1.33333. If not specified, the + // best possible crop is returned. The number of provided aspect ratios is + // limited to a maximum of 16; any aspect ratios provided after the 16th are + // ignored. + AspectRatios []float32 `protobuf:"fixed32,1,rep,packed,name=aspect_ratios,json=aspectRatios" json:"aspect_ratios,omitempty"` +} + +func (m *CropHintsParams) Reset() { *m = CropHintsParams{} } +func (m *CropHintsParams) String() string { return proto.CompactTextString(m) } +func (*CropHintsParams) ProtoMessage() {} +func (*CropHintsParams) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{14} } + +func (m *CropHintsParams) GetAspectRatios() []float32 { + if m != nil { + return m.AspectRatios + } + return nil +} + +// Parameters for web detection request. +type WebDetectionParams struct { + // Whether to include results derived from the geo information in the image. + IncludeGeoResults bool `protobuf:"varint,2,opt,name=include_geo_results,json=includeGeoResults" json:"include_geo_results,omitempty"` +} + +func (m *WebDetectionParams) Reset() { *m = WebDetectionParams{} } +func (m *WebDetectionParams) String() string { return proto.CompactTextString(m) } +func (*WebDetectionParams) ProtoMessage() {} +func (*WebDetectionParams) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{15} } + +func (m *WebDetectionParams) GetIncludeGeoResults() bool { + if m != nil { + return m.IncludeGeoResults + } + return false +} + +// Image context and/or feature-specific parameters. +type ImageContext struct { + // lat/long rectangle that specifies the location of the image. + LatLongRect *LatLongRect `protobuf:"bytes,1,opt,name=lat_long_rect,json=latLongRect" json:"lat_long_rect,omitempty"` + // List of languages to use for TEXT_DETECTION. In most cases, an empty value + // yields the best results since it enables automatic language detection. For + // languages based on the Latin alphabet, setting `language_hints` is not + // needed. In rare cases, when the language of the text in the image is known, + // setting a hint will help get better results (although it will be a + // significant hindrance if the hint is wrong). Text detection returns an + // error if one or more of the specified languages is not one of the + // [supported languages](/vision/docs/languages). + LanguageHints []string `protobuf:"bytes,2,rep,name=language_hints,json=languageHints" json:"language_hints,omitempty"` + // Parameters for crop hints annotation request. + CropHintsParams *CropHintsParams `protobuf:"bytes,4,opt,name=crop_hints_params,json=cropHintsParams" json:"crop_hints_params,omitempty"` + // Parameters for web detection. + WebDetectionParams *WebDetectionParams `protobuf:"bytes,6,opt,name=web_detection_params,json=webDetectionParams" json:"web_detection_params,omitempty"` +} + +func (m *ImageContext) Reset() { *m = ImageContext{} } +func (m *ImageContext) String() string { return proto.CompactTextString(m) } +func (*ImageContext) ProtoMessage() {} +func (*ImageContext) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{16} } + +func (m *ImageContext) GetLatLongRect() *LatLongRect { + if m != nil { + return m.LatLongRect + } + return nil +} + +func (m *ImageContext) GetLanguageHints() []string { + if m != nil { + return m.LanguageHints + } + return nil +} + +func (m *ImageContext) GetCropHintsParams() *CropHintsParams { + if m != nil { + return m.CropHintsParams + } + return nil +} + +func (m *ImageContext) GetWebDetectionParams() *WebDetectionParams { + if m != nil { + return m.WebDetectionParams + } + return nil +} + +// Request for performing Google Cloud Vision API tasks over a user-provided +// image, with user-requested features. +type AnnotateImageRequest struct { + // The image to be processed. + Image *Image `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"` + // Requested features. + Features []*Feature `protobuf:"bytes,2,rep,name=features" json:"features,omitempty"` + // Additional context that may accompany the image. + ImageContext *ImageContext `protobuf:"bytes,3,opt,name=image_context,json=imageContext" json:"image_context,omitempty"` +} + +func (m *AnnotateImageRequest) Reset() { *m = AnnotateImageRequest{} } +func (m *AnnotateImageRequest) String() string { return proto.CompactTextString(m) } +func (*AnnotateImageRequest) ProtoMessage() {} +func (*AnnotateImageRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{17} } + +func (m *AnnotateImageRequest) GetImage() *Image { + if m != nil { + return m.Image + } + return nil +} + +func (m *AnnotateImageRequest) GetFeatures() []*Feature { + if m != nil { + return m.Features + } + return nil +} + +func (m *AnnotateImageRequest) GetImageContext() *ImageContext { + if m != nil { + return m.ImageContext + } + return nil +} + +// If an image was produced from a file (e.g. a PDF), this message gives +// information about the source of that image. +type ImageAnnotationContext struct { + // The URI of the file used to produce the image. + Uri string `protobuf:"bytes,1,opt,name=uri" json:"uri,omitempty"` + // If the file was a PDF or TIFF, this field gives the page number within + // the file used to produce the image. + PageNumber int32 `protobuf:"varint,2,opt,name=page_number,json=pageNumber" json:"page_number,omitempty"` +} + +func (m *ImageAnnotationContext) Reset() { *m = ImageAnnotationContext{} } +func (m *ImageAnnotationContext) String() string { return proto.CompactTextString(m) } +func (*ImageAnnotationContext) ProtoMessage() {} +func (*ImageAnnotationContext) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{18} } + +func (m *ImageAnnotationContext) GetUri() string { + if m != nil { + return m.Uri + } + return "" +} + +func (m *ImageAnnotationContext) GetPageNumber() int32 { + if m != nil { + return m.PageNumber + } + return 0 +} + +// Response to an image annotation request. +type AnnotateImageResponse struct { + // If present, face detection has completed successfully. + FaceAnnotations []*FaceAnnotation `protobuf:"bytes,1,rep,name=face_annotations,json=faceAnnotations" json:"face_annotations,omitempty"` + // If present, landmark detection has completed successfully. + LandmarkAnnotations []*EntityAnnotation `protobuf:"bytes,2,rep,name=landmark_annotations,json=landmarkAnnotations" json:"landmark_annotations,omitempty"` + // If present, logo detection has completed successfully. + LogoAnnotations []*EntityAnnotation `protobuf:"bytes,3,rep,name=logo_annotations,json=logoAnnotations" json:"logo_annotations,omitempty"` + // If present, label detection has completed successfully. + LabelAnnotations []*EntityAnnotation `protobuf:"bytes,4,rep,name=label_annotations,json=labelAnnotations" json:"label_annotations,omitempty"` + // If present, text (OCR) detection has completed successfully. + TextAnnotations []*EntityAnnotation `protobuf:"bytes,5,rep,name=text_annotations,json=textAnnotations" json:"text_annotations,omitempty"` + // If present, text (OCR) detection or document (OCR) text detection has + // completed successfully. + // This annotation provides the structural hierarchy for the OCR detected + // text. + FullTextAnnotation *TextAnnotation `protobuf:"bytes,12,opt,name=full_text_annotation,json=fullTextAnnotation" json:"full_text_annotation,omitempty"` + // If present, safe-search annotation has completed successfully. + SafeSearchAnnotation *SafeSearchAnnotation `protobuf:"bytes,6,opt,name=safe_search_annotation,json=safeSearchAnnotation" json:"safe_search_annotation,omitempty"` + // If present, image properties were extracted successfully. + ImagePropertiesAnnotation *ImageProperties `protobuf:"bytes,8,opt,name=image_properties_annotation,json=imagePropertiesAnnotation" json:"image_properties_annotation,omitempty"` + // If present, crop hints have completed successfully. + CropHintsAnnotation *CropHintsAnnotation `protobuf:"bytes,11,opt,name=crop_hints_annotation,json=cropHintsAnnotation" json:"crop_hints_annotation,omitempty"` + // If present, web detection has completed successfully. + WebDetection *WebDetection `protobuf:"bytes,13,opt,name=web_detection,json=webDetection" json:"web_detection,omitempty"` + // If set, represents the error message for the operation. + // Note that filled-in image annotations are guaranteed to be + // correct, even when `error` is set. + Error *google_rpc.Status `protobuf:"bytes,9,opt,name=error" json:"error,omitempty"` + // If present, contextual information is needed to understand where this image + // comes from. + Context *ImageAnnotationContext `protobuf:"bytes,21,opt,name=context" json:"context,omitempty"` +} + +func (m *AnnotateImageResponse) Reset() { *m = AnnotateImageResponse{} } +func (m *AnnotateImageResponse) String() string { return proto.CompactTextString(m) } +func (*AnnotateImageResponse) ProtoMessage() {} +func (*AnnotateImageResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{19} } + +func (m *AnnotateImageResponse) GetFaceAnnotations() []*FaceAnnotation { + if m != nil { + return m.FaceAnnotations + } + return nil +} + +func (m *AnnotateImageResponse) GetLandmarkAnnotations() []*EntityAnnotation { + if m != nil { + return m.LandmarkAnnotations + } + return nil +} + +func (m *AnnotateImageResponse) GetLogoAnnotations() []*EntityAnnotation { + if m != nil { + return m.LogoAnnotations + } + return nil +} + +func (m *AnnotateImageResponse) GetLabelAnnotations() []*EntityAnnotation { + if m != nil { + return m.LabelAnnotations + } + return nil +} + +func (m *AnnotateImageResponse) GetTextAnnotations() []*EntityAnnotation { + if m != nil { + return m.TextAnnotations + } + return nil +} + +func (m *AnnotateImageResponse) GetFullTextAnnotation() *TextAnnotation { + if m != nil { + return m.FullTextAnnotation + } + return nil +} + +func (m *AnnotateImageResponse) GetSafeSearchAnnotation() *SafeSearchAnnotation { + if m != nil { + return m.SafeSearchAnnotation + } + return nil +} + +func (m *AnnotateImageResponse) GetImagePropertiesAnnotation() *ImageProperties { + if m != nil { + return m.ImagePropertiesAnnotation + } + return nil +} + +func (m *AnnotateImageResponse) GetCropHintsAnnotation() *CropHintsAnnotation { + if m != nil { + return m.CropHintsAnnotation + } + return nil +} + +func (m *AnnotateImageResponse) GetWebDetection() *WebDetection { + if m != nil { + return m.WebDetection + } + return nil +} + +func (m *AnnotateImageResponse) GetError() *google_rpc.Status { + if m != nil { + return m.Error + } + return nil +} + +func (m *AnnotateImageResponse) GetContext() *ImageAnnotationContext { + if m != nil { + return m.Context + } + return nil +} + +// Multiple image annotation requests are batched into a single service call. +type BatchAnnotateImagesRequest struct { + // Individual image annotation requests for this batch. + Requests []*AnnotateImageRequest `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"` +} + +func (m *BatchAnnotateImagesRequest) Reset() { *m = BatchAnnotateImagesRequest{} } +func (m *BatchAnnotateImagesRequest) String() string { return proto.CompactTextString(m) } +func (*BatchAnnotateImagesRequest) ProtoMessage() {} +func (*BatchAnnotateImagesRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{20} } + +func (m *BatchAnnotateImagesRequest) GetRequests() []*AnnotateImageRequest { + if m != nil { + return m.Requests + } + return nil +} + +// Response to a batch image annotation request. +type BatchAnnotateImagesResponse struct { + // Individual responses to image annotation requests within the batch. + Responses []*AnnotateImageResponse `protobuf:"bytes,1,rep,name=responses" json:"responses,omitempty"` +} + +func (m *BatchAnnotateImagesResponse) Reset() { *m = BatchAnnotateImagesResponse{} } +func (m *BatchAnnotateImagesResponse) String() string { return proto.CompactTextString(m) } +func (*BatchAnnotateImagesResponse) ProtoMessage() {} +func (*BatchAnnotateImagesResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{21} } + +func (m *BatchAnnotateImagesResponse) GetResponses() []*AnnotateImageResponse { + if m != nil { + return m.Responses + } + return nil +} + +// An offline file annotation request. +type AsyncAnnotateFileRequest struct { + // Required. Information about the input file. + InputConfig *InputConfig `protobuf:"bytes,1,opt,name=input_config,json=inputConfig" json:"input_config,omitempty"` + // Required. Requested features. + Features []*Feature `protobuf:"bytes,2,rep,name=features" json:"features,omitempty"` + // Additional context that may accompany the image(s) in the file. + ImageContext *ImageContext `protobuf:"bytes,3,opt,name=image_context,json=imageContext" json:"image_context,omitempty"` + // Required. The desired output location and metadata (e.g. format). + OutputConfig *OutputConfig `protobuf:"bytes,4,opt,name=output_config,json=outputConfig" json:"output_config,omitempty"` +} + +func (m *AsyncAnnotateFileRequest) Reset() { *m = AsyncAnnotateFileRequest{} } +func (m *AsyncAnnotateFileRequest) String() string { return proto.CompactTextString(m) } +func (*AsyncAnnotateFileRequest) ProtoMessage() {} +func (*AsyncAnnotateFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{22} } + +func (m *AsyncAnnotateFileRequest) GetInputConfig() *InputConfig { + if m != nil { + return m.InputConfig + } + return nil +} + +func (m *AsyncAnnotateFileRequest) GetFeatures() []*Feature { + if m != nil { + return m.Features + } + return nil +} + +func (m *AsyncAnnotateFileRequest) GetImageContext() *ImageContext { + if m != nil { + return m.ImageContext + } + return nil +} + +func (m *AsyncAnnotateFileRequest) GetOutputConfig() *OutputConfig { + if m != nil { + return m.OutputConfig + } + return nil +} + +// The response for a single offline file annotation request. +type AsyncAnnotateFileResponse struct { + // The output location and metadata from AsyncAnnotateFileRequest. + OutputConfig *OutputConfig `protobuf:"bytes,1,opt,name=output_config,json=outputConfig" json:"output_config,omitempty"` +} + +func (m *AsyncAnnotateFileResponse) Reset() { *m = AsyncAnnotateFileResponse{} } +func (m *AsyncAnnotateFileResponse) String() string { return proto.CompactTextString(m) } +func (*AsyncAnnotateFileResponse) ProtoMessage() {} +func (*AsyncAnnotateFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{23} } + +func (m *AsyncAnnotateFileResponse) GetOutputConfig() *OutputConfig { + if m != nil { + return m.OutputConfig + } + return nil +} + +// Multiple async file annotation requests are batched into a single service +// call. +type AsyncBatchAnnotateFilesRequest struct { + // Individual async file annotation requests for this batch. + Requests []*AsyncAnnotateFileRequest `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"` +} + +func (m *AsyncBatchAnnotateFilesRequest) Reset() { *m = AsyncBatchAnnotateFilesRequest{} } +func (m *AsyncBatchAnnotateFilesRequest) String() string { return proto.CompactTextString(m) } +func (*AsyncBatchAnnotateFilesRequest) ProtoMessage() {} +func (*AsyncBatchAnnotateFilesRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{24} } + +func (m *AsyncBatchAnnotateFilesRequest) GetRequests() []*AsyncAnnotateFileRequest { + if m != nil { + return m.Requests + } + return nil +} + +// Response to an async batch file annotation request. +type AsyncBatchAnnotateFilesResponse struct { + // The list of file annotation responses, one for each request in + // AsyncBatchAnnotateFilesRequest. + Responses []*AsyncAnnotateFileResponse `protobuf:"bytes,1,rep,name=responses" json:"responses,omitempty"` +} + +func (m *AsyncBatchAnnotateFilesResponse) Reset() { *m = AsyncBatchAnnotateFilesResponse{} } +func (m *AsyncBatchAnnotateFilesResponse) String() string { return proto.CompactTextString(m) } +func (*AsyncBatchAnnotateFilesResponse) ProtoMessage() {} +func (*AsyncBatchAnnotateFilesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor1, []int{25} +} + +func (m *AsyncBatchAnnotateFilesResponse) GetResponses() []*AsyncAnnotateFileResponse { + if m != nil { + return m.Responses + } + return nil +} + +// The desired input location and metadata. +type InputConfig struct { + // The Google Cloud Storage location to read the input from. + GcsSource *GcsSource `protobuf:"bytes,1,opt,name=gcs_source,json=gcsSource" json:"gcs_source,omitempty"` + // The type of the file. Currently only "application/pdf" and "image/tiff" + // are supported. Wildcards are not supported. + MimeType string `protobuf:"bytes,2,opt,name=mime_type,json=mimeType" json:"mime_type,omitempty"` +} + +func (m *InputConfig) Reset() { *m = InputConfig{} } +func (m *InputConfig) String() string { return proto.CompactTextString(m) } +func (*InputConfig) ProtoMessage() {} +func (*InputConfig) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{26} } + +func (m *InputConfig) GetGcsSource() *GcsSource { + if m != nil { + return m.GcsSource + } + return nil +} + +func (m *InputConfig) GetMimeType() string { + if m != nil { + return m.MimeType + } + return "" +} + +// The desired output location and metadata. +type OutputConfig struct { + // The Google Cloud Storage location to write the output(s) to. + GcsDestination *GcsDestination `protobuf:"bytes,1,opt,name=gcs_destination,json=gcsDestination" json:"gcs_destination,omitempty"` + // The max number of response protos to put into each output JSON file on GCS. + // The valid range is [1, 100]. If not specified, the default value is 20. + // + // For example, for one pdf file with 100 pages, 100 response protos will + // be generated. If `batch_size` = 20, then 5 json files each + // containing 20 response protos will be written under the prefix + // `gcs_destination`.`uri`. + // + // Currently, batch_size only applies to GcsDestination, with potential future + // support for other output configurations. + BatchSize int32 `protobuf:"varint,2,opt,name=batch_size,json=batchSize" json:"batch_size,omitempty"` +} + +func (m *OutputConfig) Reset() { *m = OutputConfig{} } +func (m *OutputConfig) String() string { return proto.CompactTextString(m) } +func (*OutputConfig) ProtoMessage() {} +func (*OutputConfig) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{27} } + +func (m *OutputConfig) GetGcsDestination() *GcsDestination { + if m != nil { + return m.GcsDestination + } + return nil +} + +func (m *OutputConfig) GetBatchSize() int32 { + if m != nil { + return m.BatchSize + } + return 0 +} + +// The Google Cloud Storage location where the input will be read from. +type GcsSource struct { + // Google Cloud Storage URI for the input file. This must only be a GCS + // object. Wildcards are not currently supported. + Uri string `protobuf:"bytes,1,opt,name=uri" json:"uri,omitempty"` +} + +func (m *GcsSource) Reset() { *m = GcsSource{} } +func (m *GcsSource) String() string { return proto.CompactTextString(m) } +func (*GcsSource) ProtoMessage() {} +func (*GcsSource) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{28} } + +func (m *GcsSource) GetUri() string { + if m != nil { + return m.Uri + } + return "" +} + +// The Google Cloud Storage location where the output will be written to. +type GcsDestination struct { + // Google Cloud Storage URI where the results will be stored. Results will + // be in JSON format and preceded by its corresponding input URI. This field + // can either represent a single file, or a prefix for multiple outputs. + // Prefixes must end in a `/`. + // + // Examples: + // + // * File: gs://bucket-name/filename.json + // * Prefix: gs://bucket-name/prefix/here/ + // * File: gs://bucket-name/prefix/here + // + // If multiple outputs, each response is still AnnotateFileResponse, each of + // which contains some subset of the full list of AnnotateImageResponse. + // Multiple outputs can happen if, for example, the output JSON is too large + // and overflows into multiple sharded files. + Uri string `protobuf:"bytes,1,opt,name=uri" json:"uri,omitempty"` +} + +func (m *GcsDestination) Reset() { *m = GcsDestination{} } +func (m *GcsDestination) String() string { return proto.CompactTextString(m) } +func (*GcsDestination) ProtoMessage() {} +func (*GcsDestination) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{29} } + +func (m *GcsDestination) GetUri() string { + if m != nil { + return m.Uri + } + return "" +} + +// Contains metadata for the BatchAnnotateImages operation. +type OperationMetadata struct { + // Current state of the batch operation. + State OperationMetadata_State `protobuf:"varint,1,opt,name=state,enum=google.cloud.vision.v1p2beta1.OperationMetadata_State" json:"state,omitempty"` + // The time when the batch request was received. + CreateTime *google_protobuf3.Timestamp `protobuf:"bytes,5,opt,name=create_time,json=createTime" json:"create_time,omitempty"` + // The time when the operation result was last updated. + UpdateTime *google_protobuf3.Timestamp `protobuf:"bytes,6,opt,name=update_time,json=updateTime" json:"update_time,omitempty"` +} + +func (m *OperationMetadata) Reset() { *m = OperationMetadata{} } +func (m *OperationMetadata) String() string { return proto.CompactTextString(m) } +func (*OperationMetadata) ProtoMessage() {} +func (*OperationMetadata) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{30} } + +func (m *OperationMetadata) GetState() OperationMetadata_State { + if m != nil { + return m.State + } + return OperationMetadata_STATE_UNSPECIFIED +} + +func (m *OperationMetadata) GetCreateTime() *google_protobuf3.Timestamp { + if m != nil { + return m.CreateTime + } + return nil +} + +func (m *OperationMetadata) GetUpdateTime() *google_protobuf3.Timestamp { + if m != nil { + return m.UpdateTime + } + return nil +} + +func init() { + proto.RegisterType((*Feature)(nil), "google.cloud.vision.v1p2beta1.Feature") + proto.RegisterType((*ImageSource)(nil), "google.cloud.vision.v1p2beta1.ImageSource") + proto.RegisterType((*Image)(nil), "google.cloud.vision.v1p2beta1.Image") + proto.RegisterType((*FaceAnnotation)(nil), "google.cloud.vision.v1p2beta1.FaceAnnotation") + proto.RegisterType((*FaceAnnotation_Landmark)(nil), "google.cloud.vision.v1p2beta1.FaceAnnotation.Landmark") + proto.RegisterType((*LocationInfo)(nil), "google.cloud.vision.v1p2beta1.LocationInfo") + proto.RegisterType((*Property)(nil), "google.cloud.vision.v1p2beta1.Property") + proto.RegisterType((*EntityAnnotation)(nil), "google.cloud.vision.v1p2beta1.EntityAnnotation") + proto.RegisterType((*SafeSearchAnnotation)(nil), "google.cloud.vision.v1p2beta1.SafeSearchAnnotation") + proto.RegisterType((*LatLongRect)(nil), "google.cloud.vision.v1p2beta1.LatLongRect") + proto.RegisterType((*ColorInfo)(nil), "google.cloud.vision.v1p2beta1.ColorInfo") + proto.RegisterType((*DominantColorsAnnotation)(nil), "google.cloud.vision.v1p2beta1.DominantColorsAnnotation") + proto.RegisterType((*ImageProperties)(nil), "google.cloud.vision.v1p2beta1.ImageProperties") + proto.RegisterType((*CropHint)(nil), "google.cloud.vision.v1p2beta1.CropHint") + proto.RegisterType((*CropHintsAnnotation)(nil), "google.cloud.vision.v1p2beta1.CropHintsAnnotation") + proto.RegisterType((*CropHintsParams)(nil), "google.cloud.vision.v1p2beta1.CropHintsParams") + proto.RegisterType((*WebDetectionParams)(nil), "google.cloud.vision.v1p2beta1.WebDetectionParams") + proto.RegisterType((*ImageContext)(nil), "google.cloud.vision.v1p2beta1.ImageContext") + proto.RegisterType((*AnnotateImageRequest)(nil), "google.cloud.vision.v1p2beta1.AnnotateImageRequest") + proto.RegisterType((*ImageAnnotationContext)(nil), "google.cloud.vision.v1p2beta1.ImageAnnotationContext") + proto.RegisterType((*AnnotateImageResponse)(nil), "google.cloud.vision.v1p2beta1.AnnotateImageResponse") + proto.RegisterType((*BatchAnnotateImagesRequest)(nil), "google.cloud.vision.v1p2beta1.BatchAnnotateImagesRequest") + proto.RegisterType((*BatchAnnotateImagesResponse)(nil), "google.cloud.vision.v1p2beta1.BatchAnnotateImagesResponse") + proto.RegisterType((*AsyncAnnotateFileRequest)(nil), "google.cloud.vision.v1p2beta1.AsyncAnnotateFileRequest") + proto.RegisterType((*AsyncAnnotateFileResponse)(nil), "google.cloud.vision.v1p2beta1.AsyncAnnotateFileResponse") + proto.RegisterType((*AsyncBatchAnnotateFilesRequest)(nil), "google.cloud.vision.v1p2beta1.AsyncBatchAnnotateFilesRequest") + proto.RegisterType((*AsyncBatchAnnotateFilesResponse)(nil), "google.cloud.vision.v1p2beta1.AsyncBatchAnnotateFilesResponse") + proto.RegisterType((*InputConfig)(nil), "google.cloud.vision.v1p2beta1.InputConfig") + proto.RegisterType((*OutputConfig)(nil), "google.cloud.vision.v1p2beta1.OutputConfig") + proto.RegisterType((*GcsSource)(nil), "google.cloud.vision.v1p2beta1.GcsSource") + proto.RegisterType((*GcsDestination)(nil), "google.cloud.vision.v1p2beta1.GcsDestination") + proto.RegisterType((*OperationMetadata)(nil), "google.cloud.vision.v1p2beta1.OperationMetadata") + proto.RegisterEnum("google.cloud.vision.v1p2beta1.Likelihood", Likelihood_name, Likelihood_value) + proto.RegisterEnum("google.cloud.vision.v1p2beta1.Feature_Type", Feature_Type_name, Feature_Type_value) + proto.RegisterEnum("google.cloud.vision.v1p2beta1.FaceAnnotation_Landmark_Type", FaceAnnotation_Landmark_Type_name, FaceAnnotation_Landmark_Type_value) + proto.RegisterEnum("google.cloud.vision.v1p2beta1.OperationMetadata_State", OperationMetadata_State_name, OperationMetadata_State_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for ImageAnnotator service + +type ImageAnnotatorClient interface { + // Run image detection and annotation for a batch of images. + BatchAnnotateImages(ctx context.Context, in *BatchAnnotateImagesRequest, opts ...grpc.CallOption) (*BatchAnnotateImagesResponse, error) + // Run async image detection and annotation for a list of generic files (e.g. + // PDF) which may contain multiple pages and multiple images per page. + // Progress and results can be retrieved through the + // `google.longrunning.Operations` interface. + // `Operation.metadata` contains `OperationMetadata` (metadata). + // `Operation.response` contains `AsyncBatchAnnotateFilesResponse` (results). + AsyncBatchAnnotateFiles(ctx context.Context, in *AsyncBatchAnnotateFilesRequest, opts ...grpc.CallOption) (*google_longrunning.Operation, error) +} + +type imageAnnotatorClient struct { + cc *grpc.ClientConn +} + +func NewImageAnnotatorClient(cc *grpc.ClientConn) ImageAnnotatorClient { + return &imageAnnotatorClient{cc} +} + +func (c *imageAnnotatorClient) BatchAnnotateImages(ctx context.Context, in *BatchAnnotateImagesRequest, opts ...grpc.CallOption) (*BatchAnnotateImagesResponse, error) { + out := new(BatchAnnotateImagesResponse) + err := grpc.Invoke(ctx, "/google.cloud.vision.v1p2beta1.ImageAnnotator/BatchAnnotateImages", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *imageAnnotatorClient) AsyncBatchAnnotateFiles(ctx context.Context, in *AsyncBatchAnnotateFilesRequest, opts ...grpc.CallOption) (*google_longrunning.Operation, error) { + out := new(google_longrunning.Operation) + err := grpc.Invoke(ctx, "/google.cloud.vision.v1p2beta1.ImageAnnotator/AsyncBatchAnnotateFiles", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for ImageAnnotator service + +type ImageAnnotatorServer interface { + // Run image detection and annotation for a batch of images. + BatchAnnotateImages(context.Context, *BatchAnnotateImagesRequest) (*BatchAnnotateImagesResponse, error) + // Run async image detection and annotation for a list of generic files (e.g. + // PDF) which may contain multiple pages and multiple images per page. + // Progress and results can be retrieved through the + // `google.longrunning.Operations` interface. + // `Operation.metadata` contains `OperationMetadata` (metadata). + // `Operation.response` contains `AsyncBatchAnnotateFilesResponse` (results). + AsyncBatchAnnotateFiles(context.Context, *AsyncBatchAnnotateFilesRequest) (*google_longrunning.Operation, error) +} + +func RegisterImageAnnotatorServer(s *grpc.Server, srv ImageAnnotatorServer) { + s.RegisterService(&_ImageAnnotator_serviceDesc, srv) +} + +func _ImageAnnotator_BatchAnnotateImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchAnnotateImagesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ImageAnnotatorServer).BatchAnnotateImages(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.cloud.vision.v1p2beta1.ImageAnnotator/BatchAnnotateImages", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ImageAnnotatorServer).BatchAnnotateImages(ctx, req.(*BatchAnnotateImagesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ImageAnnotator_AsyncBatchAnnotateFiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AsyncBatchAnnotateFilesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ImageAnnotatorServer).AsyncBatchAnnotateFiles(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.cloud.vision.v1p2beta1.ImageAnnotator/AsyncBatchAnnotateFiles", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ImageAnnotatorServer).AsyncBatchAnnotateFiles(ctx, req.(*AsyncBatchAnnotateFilesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ImageAnnotator_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.cloud.vision.v1p2beta1.ImageAnnotator", + HandlerType: (*ImageAnnotatorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "BatchAnnotateImages", + Handler: _ImageAnnotator_BatchAnnotateImages_Handler, + }, + { + MethodName: "AsyncBatchAnnotateFiles", + Handler: _ImageAnnotator_AsyncBatchAnnotateFiles_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/cloud/vision/v1p2beta1/image_annotator.proto", +} + +func init() { + proto.RegisterFile("google/cloud/vision/v1p2beta1/image_annotator.proto", fileDescriptor1) +} + +var fileDescriptor1 = []byte{ + // 2880 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcf, 0x73, 0xdb, 0xc6, + 0xf5, 0x0f, 0xa9, 0x5f, 0xe4, 0x23, 0x25, 0x41, 0xab, 0x1f, 0xa6, 0x65, 0x2b, 0x56, 0x90, 0x6f, + 0xbe, 0x5f, 0x7d, 0xdd, 0x94, 0x1a, 0xcb, 0x49, 0xda, 0x3a, 0xcd, 0xa4, 0x14, 0x09, 0x49, 0x1c, + 0x53, 0x24, 0xbb, 0x84, 0xec, 0xd8, 0x93, 0x0e, 0x0a, 0x81, 0x4b, 0x1a, 0x09, 0x08, 0x20, 0x00, + 0x68, 0x8b, 0x39, 0x66, 0xa6, 0x7f, 0x41, 0x6f, 0xbd, 0x77, 0x7a, 0x6a, 0x2f, 0xed, 0xdf, 0xd0, + 0x7b, 0xa7, 0x87, 0x5e, 0x7a, 0x6b, 0x0f, 0x3d, 0xf6, 0xd4, 0xe9, 0xf4, 0xd4, 0xd9, 0x1f, 0x00, + 0x17, 0x94, 0x64, 0x8a, 0xce, 0x74, 0xa6, 0x27, 0x62, 0xdf, 0xdb, 0xcf, 0xe7, 0x2d, 0xde, 0xbe, + 0x7d, 0xfb, 0x76, 0x41, 0x78, 0xd8, 0xf7, 0xbc, 0xbe, 0x43, 0xf6, 0x2d, 0xc7, 0x1b, 0x76, 0xf7, + 0x5f, 0xda, 0xa1, 0xed, 0xb9, 0xfb, 0x2f, 0x1f, 0xf8, 0x07, 0xe7, 0x24, 0x32, 0x1f, 0xec, 0xdb, + 0x03, 0xb3, 0x4f, 0x0c, 0xd3, 0x75, 0xbd, 0xc8, 0x8c, 0xbc, 0xa0, 0xec, 0x07, 0x5e, 0xe4, 0xa1, + 0x1d, 0x0e, 0x2a, 0x33, 0x50, 0x99, 0x83, 0xca, 0x09, 0x68, 0xfb, 0xae, 0xe0, 0x34, 0x7d, 0x7b, + 0x5f, 0x40, 0x6d, 0xcf, 0x0d, 0x39, 0x78, 0xfb, 0xfd, 0xd7, 0x5b, 0xec, 0x13, 0x6f, 0x40, 0xa2, + 0x60, 0x24, 0x7a, 0x4f, 0x19, 0x5f, 0x44, 0x2e, 0x22, 0x63, 0x6c, 0x43, 0x80, 0x1e, 0xbc, 0x1e, + 0xf4, 0x8a, 0x9c, 0x1b, 0x5d, 0x12, 0x11, 0x4b, 0x82, 0xbc, 0x2b, 0x20, 0x8e, 0xe7, 0xf6, 0x83, + 0xa1, 0xeb, 0xda, 0x6e, 0x7f, 0xdf, 0xf3, 0x49, 0x90, 0x1a, 0xfa, 0x3d, 0xd1, 0x89, 0xb5, 0xce, + 0x87, 0xbd, 0xfd, 0xc8, 0x1e, 0x90, 0x30, 0x32, 0x07, 0xbe, 0xe8, 0x70, 0x4b, 0x74, 0x08, 0x7c, + 0x6b, 0x3f, 0x8c, 0xcc, 0x68, 0x18, 0x4e, 0x28, 0xa2, 0x91, 0x4f, 0xf6, 0x2d, 0xcf, 0x89, 0x5d, + 0xb9, 0x5d, 0x92, 0x15, 0x8e, 0x19, 0x39, 0x6e, 0x9f, 0x6b, 0xd4, 0x7f, 0x65, 0x61, 0xe9, 0x88, + 0x98, 0xd1, 0x30, 0x20, 0xe8, 0x53, 0x98, 0xa7, 0x1d, 0x4a, 0x99, 0xdd, 0xcc, 0xde, 0xca, 0xc1, + 0x77, 0xca, 0xaf, 0xf5, 0x7f, 0x59, 0xa0, 0xca, 0xfa, 0xc8, 0x27, 0x98, 0x01, 0xd1, 0x3d, 0x28, + 0x0c, 0xcc, 0x0b, 0x23, 0x20, 0xe1, 0xd0, 0x89, 0xc2, 0x52, 0x76, 0x37, 0xb3, 0xb7, 0x80, 0x61, + 0x60, 0x5e, 0x60, 0x2e, 0x41, 0x1b, 0xb0, 0x30, 0xf0, 0xba, 0xc4, 0x29, 0xcd, 0xed, 0x66, 0xf6, + 0xf2, 0x98, 0x37, 0xd4, 0x7f, 0x64, 0x60, 0x9e, 0xb2, 0xa0, 0x0d, 0x50, 0xf4, 0x67, 0x6d, 0xcd, + 0x38, 0x6b, 0x76, 0xda, 0x5a, 0xb5, 0x7e, 0x54, 0xd7, 0x6a, 0xca, 0x5b, 0x08, 0xc1, 0xca, 0x51, + 0xa5, 0xaa, 0x19, 0x35, 0x4d, 0xd7, 0xaa, 0x7a, 0xbd, 0xd5, 0x54, 0x32, 0x68, 0x0b, 0x50, 0xa3, + 0xd2, 0xac, 0x9d, 0x56, 0xf0, 0x63, 0x49, 0x9e, 0xa5, 0x7d, 0x1b, 0xad, 0xe3, 0x96, 0x24, 0x9b, + 0x43, 0xeb, 0xb0, 0xda, 0xa8, 0x1c, 0x6a, 0x0d, 0x49, 0x38, 0x4f, 0x3b, 0xea, 0xda, 0x67, 0xba, + 0x24, 0x5b, 0x40, 0x77, 0xe0, 0x56, 0xad, 0x55, 0x3d, 0x3b, 0xd5, 0x9a, 0xba, 0x31, 0xa1, 0x2c, + 0xa0, 0xdb, 0xb0, 0xd9, 0xa9, 0x1c, 0x69, 0x46, 0x47, 0xab, 0xe0, 0xea, 0x89, 0xa4, 0x5a, 0xa4, + 0xc3, 0xae, 0x9f, 0x56, 0x8e, 0x35, 0xa3, 0x8d, 0x5b, 0x6d, 0x0d, 0xeb, 0x75, 0xad, 0xa3, 0x2c, + 0xa1, 0x15, 0x80, 0x2a, 0x6e, 0xb5, 0x8d, 0x93, 0x7a, 0x53, 0xef, 0x28, 0x79, 0xb4, 0x06, 0xcb, + 0x4f, 0xb5, 0x43, 0x09, 0x08, 0x6a, 0x13, 0x0a, 0x75, 0x1a, 0xfa, 0x1d, 0x6f, 0x18, 0x58, 0x04, + 0xa9, 0xb0, 0xdc, 0xb7, 0x42, 0x83, 0xaf, 0x86, 0x61, 0x60, 0xb3, 0x89, 0xc8, 0xe3, 0x42, 0xdf, + 0x0a, 0x59, 0xb7, 0xb3, 0xc0, 0x46, 0x77, 0x20, 0x3f, 0xd6, 0x67, 0x99, 0x3e, 0x67, 0x0b, 0xa5, + 0x4a, 0x60, 0x81, 0x75, 0x44, 0x25, 0x58, 0xb2, 0x3c, 0x37, 0x22, 0x6e, 0xc4, 0x38, 0x8a, 0x38, + 0x6e, 0xa2, 0x43, 0x58, 0x0c, 0x99, 0x35, 0x06, 0x2e, 0x1c, 0xdc, 0x9f, 0x32, 0xcb, 0xd2, 0xf8, + 0xb0, 0x40, 0xaa, 0xbf, 0x54, 0x60, 0xe5, 0xc8, 0xb4, 0x48, 0x25, 0x59, 0x11, 0xa8, 0x0d, 0xcb, + 0xe7, 0xde, 0xd0, 0xed, 0xda, 0x6e, 0xdf, 0xf0, 0x3d, 0x67, 0xc4, 0xcc, 0x16, 0xa6, 0xc6, 0xd0, + 0xa1, 0xc0, 0xb4, 0x3d, 0x67, 0x84, 0x8b, 0xe7, 0x52, 0x0b, 0x9d, 0x81, 0xd2, 0xeb, 0x1a, 0x69, + 0xd2, 0xec, 0xec, 0xa4, 0x2b, 0xbd, 0xae, 0xdc, 0x46, 0x3a, 0xe4, 0x1d, 0xd3, 0xed, 0x0e, 0xcc, + 0xe0, 0xcb, 0xb0, 0x34, 0xb7, 0x3b, 0xb7, 0x57, 0x38, 0xf8, 0x68, 0x5a, 0xa0, 0xa7, 0x5e, 0xb5, + 0xdc, 0x10, 0x70, 0x3c, 0x26, 0x42, 0x3b, 0x00, 0x81, 0xe7, 0x38, 0x86, 0xe9, 0xf6, 0x1d, 0x52, + 0x9a, 0xdf, 0xcd, 0xec, 0x65, 0x71, 0x9e, 0x4a, 0x2a, 0x54, 0x40, 0x27, 0xcd, 0x37, 0x5d, 0xa1, + 0x5d, 0x60, 0xda, 0x9c, 0x6f, 0xba, 0x5c, 0xb9, 0x03, 0x10, 0xd9, 0x4e, 0x24, 0xb4, 0x8b, 0x1c, + 0x4b, 0x25, 0x5c, 0xfd, 0x00, 0x36, 0x92, 0x2c, 0x62, 0x58, 0x9e, 0xdb, 0xb3, 0xbb, 0xc4, 0xb5, + 0x48, 0x69, 0x89, 0x75, 0x5c, 0x4f, 0x74, 0xd5, 0x44, 0x85, 0x3e, 0x84, 0xad, 0x78, 0x68, 0xd4, + 0x75, 0x12, 0x28, 0xc7, 0x40, 0x9b, 0x92, 0x56, 0x82, 0xb5, 0x61, 0xe5, 0x0b, 0x6f, 0x64, 0x38, + 0xf6, 0x97, 0xc4, 0xb1, 0x5f, 0x78, 0x5e, 0xb7, 0x94, 0x67, 0x89, 0xe0, 0xff, 0xa7, 0xf8, 0xa7, + 0x91, 0x00, 0xf0, 0xf2, 0x17, 0xde, 0x68, 0xdc, 0x44, 0x4f, 0x60, 0x2d, 0xf4, 0x82, 0xc0, 0x7b, + 0x25, 0x93, 0xc2, 0xac, 0xa4, 0x0a, 0xe7, 0x90, 0x78, 0x75, 0x50, 0x4c, 0xb7, 0x4f, 0x02, 0x99, + 0xb6, 0x30, 0x2b, 0xed, 0x2a, 0xa3, 0x90, 0x58, 0x9f, 0xc3, 0x7a, 0x38, 0x0c, 0xfc, 0xc0, 0x0e, + 0x89, 0x4c, 0x5c, 0x9c, 0x95, 0x18, 0xc5, 0x2c, 0x12, 0xb7, 0x05, 0xa5, 0xa1, 0xdb, 0x25, 0x81, + 0x41, 0x2e, 0x7c, 0x2f, 0x24, 0x5d, 0xd9, 0xc0, 0xf2, 0xac, 0x06, 0xb6, 0x18, 0x95, 0xc6, 0x99, + 0x24, 0x23, 0x9f, 0x01, 0x3a, 0x77, 0x86, 0x41, 0x90, 0xa6, 0x5f, 0x99, 0x95, 0x7e, 0x4d, 0x90, + 0xa4, 0x5d, 0xf3, 0x82, 0x98, 0xdd, 0x57, 0xc4, 0x4c, 0xf9, 0x7c, 0x75, 0x66, 0xd7, 0xc4, 0x2c, + 0x63, 0xd9, 0xf6, 0x9f, 0x96, 0x20, 0x17, 0xaf, 0x29, 0xd4, 0x12, 0x5b, 0xd0, 0x1c, 0x63, 0xfe, + 0xf8, 0xcd, 0x56, 0xa6, 0xbc, 0x25, 0x55, 0x21, 0xe7, 0x7b, 0xa1, 0x4d, 0xf5, 0x6c, 0x5d, 0x16, + 0x0e, 0xfe, 0x6f, 0x0a, 0x69, 0x5b, 0x74, 0xc7, 0x09, 0x50, 0xfd, 0xdd, 0xe2, 0x78, 0x83, 0x3a, + 0x6b, 0x3e, 0x6e, 0xb6, 0x9e, 0x36, 0x8d, 0x78, 0xfb, 0x51, 0xde, 0x42, 0x45, 0xc8, 0x35, 0xb4, + 0x23, 0xdd, 0xd0, 0x9e, 0x69, 0x4a, 0x06, 0x2d, 0x43, 0x1e, 0xd7, 0x8f, 0x4f, 0x78, 0x33, 0x8b, + 0x4a, 0xb0, 0xc1, 0x94, 0xad, 0x23, 0x23, 0xee, 0x74, 0x88, 0x5b, 0x4f, 0x95, 0x39, 0xba, 0xa3, + 0xf0, 0x8e, 0x93, 0xaa, 0x79, 0xaa, 0x8a, 0x41, 0x09, 0x17, 0x53, 0x2d, 0xa0, 0x6d, 0xd8, 0x4a, + 0x50, 0x69, 0xdd, 0x22, 0x85, 0x9d, 0xd6, 0x6b, 0xed, 0x56, 0xbd, 0xa9, 0x1b, 0x87, 0x9a, 0xfe, + 0x54, 0xd3, 0x9a, 0x54, 0x4b, 0x77, 0xa3, 0x22, 0xe4, 0x9a, 0xad, 0x8e, 0x66, 0xe8, 0xf5, 0xb6, + 0x92, 0xa3, 0x63, 0x3c, 0x6b, 0xb7, 0x35, 0x6c, 0x34, 0xea, 0x6d, 0x25, 0x4f, 0x9b, 0x8d, 0xd6, + 0x53, 0xd1, 0x04, 0xba, 0x73, 0x9d, 0xb6, 0xce, 0xf4, 0x13, 0x36, 0x2a, 0xa5, 0x80, 0x56, 0xa1, + 0xc0, 0xdb, 0xcc, 0x9e, 0x52, 0x44, 0x0a, 0x14, 0xb9, 0xa0, 0xaa, 0x35, 0x75, 0x0d, 0x2b, 0xcb, + 0x68, 0x13, 0xd6, 0x18, 0xfd, 0x61, 0x4b, 0xd7, 0x5b, 0xa7, 0xa2, 0xe3, 0x0a, 0xf5, 0x97, 0x2c, + 0x66, 0x7c, 0xab, 0x74, 0xf3, 0x96, 0xa5, 0x82, 0x44, 0x49, 0xde, 0x5a, 0x7b, 0xa6, 0x19, 0x7a, + 0xab, 0x6d, 0x1c, 0xb6, 0xce, 0x9a, 0xb5, 0x0a, 0x7e, 0xa6, 0xac, 0xa5, 0x54, 0xfc, 0xad, 0xab, + 0x2d, 0xdc, 0xd4, 0xb0, 0x82, 0xd0, 0x5d, 0x28, 0x25, 0x2a, 0xc1, 0x98, 0x00, 0xd7, 0x13, 0xf7, + 0x53, 0x2d, 0x7b, 0x10, 0xb8, 0x8d, 0xb1, 0x23, 0x2f, 0x99, 0xdb, 0x4c, 0xeb, 0x52, 0xf6, 0xb6, + 0xd0, 0x0e, 0xdc, 0x1e, 0xeb, 0x26, 0x0d, 0xde, 0x1a, 0xcf, 0xea, 0xa4, 0xc5, 0x12, 0xba, 0x07, + 0x77, 0xe4, 0x79, 0x36, 0xf8, 0x14, 0xc4, 0x33, 0xa6, 0xdc, 0x46, 0xbb, 0x70, 0x37, 0x35, 0xa5, + 0x93, 0x3d, 0xb6, 0xa9, 0x43, 0x39, 0x45, 0x05, 0x1b, 0x3a, 0xae, 0x1c, 0xd3, 0x3a, 0xe2, 0x0e, + 0xf5, 0xbe, 0xc0, 0x49, 0xe2, 0xbb, 0xac, 0x18, 0x8a, 0xdf, 0xbd, 0x7d, 0xd6, 0xae, 0x37, 0x94, + 0x1d, 0x5a, 0x0c, 0x8d, 0x87, 0xc7, 0x85, 0x6f, 0x53, 0xfc, 0x51, 0x0b, 0x6b, 0x27, 0x5a, 0xa5, + 0x66, 0x1c, 0xb3, 0x5a, 0xa9, 0x51, 0x51, 0xee, 0xd1, 0x8a, 0xa5, 0x7a, 0x52, 0x6f, 0x1a, 0xc7, + 0xcd, 0x8a, 0x7e, 0x42, 0x29, 0x77, 0xa9, 0x7d, 0x26, 0x62, 0xbc, 0xc7, 0xad, 0x26, 0x95, 0xbe, + 0x43, 0xf1, 0x4c, 0xca, 0x99, 0x85, 0x58, 0x55, 0x7f, 0x08, 0xc5, 0x86, 0x67, 0xb1, 0xb5, 0x59, + 0x77, 0x7b, 0x1e, 0x7a, 0x1f, 0x96, 0x1c, 0x33, 0x32, 0x1c, 0xb7, 0x2f, 0xca, 0x83, 0xf5, 0x78, + 0x29, 0xd2, 0xa5, 0x5a, 0x6e, 0x98, 0x51, 0xc3, 0xed, 0xe3, 0x45, 0x87, 0xfd, 0xaa, 0x4f, 0x21, + 0xd7, 0x0e, 0x68, 0x71, 0x1c, 0x8d, 0x10, 0x82, 0x79, 0xd7, 0x1c, 0x10, 0x51, 0x10, 0xb1, 0x67, + 0x5a, 0x4b, 0xbe, 0x34, 0x9d, 0x21, 0x11, 0x55, 0x10, 0x6f, 0xa0, 0x77, 0xa0, 0x38, 0xb4, 0xdd, + 0xe8, 0xa3, 0x0f, 0x0c, 0xae, 0xa4, 0x89, 0x64, 0x1e, 0x17, 0xb8, 0xec, 0x09, 0x15, 0xa9, 0xbf, + 0x98, 0x03, 0x45, 0x73, 0x23, 0x3b, 0x1a, 0x49, 0x05, 0x8c, 0x02, 0x73, 0x03, 0xbb, 0x2b, 0x0c, + 0xd0, 0x47, 0xb4, 0x05, 0x8b, 0x8e, 0x67, 0x99, 0x4e, 0x6c, 0x40, 0xb4, 0xd0, 0x2e, 0x14, 0xba, + 0x24, 0xb4, 0x02, 0xdb, 0x67, 0x49, 0x85, 0x57, 0xb2, 0xb2, 0x88, 0x8e, 0x2c, 0xb4, 0xbc, 0x20, + 0x2e, 0x04, 0x78, 0x03, 0xbd, 0x0d, 0x20, 0xed, 0xc4, 0xbc, 0x0a, 0x90, 0x24, 0x54, 0x1f, 0x79, + 0xbe, 0x6d, 0x99, 0x8e, 0x1d, 0x8d, 0x44, 0x1d, 0x20, 0x49, 0x2e, 0x97, 0x58, 0x4b, 0xdf, 0xb6, + 0xc4, 0xaa, 0x43, 0xde, 0x11, 0xf3, 0x13, 0x96, 0x72, 0xac, 0x16, 0x9a, 0xc6, 0x26, 0xcf, 0x27, + 0x1e, 0xa3, 0xd1, 0x31, 0x80, 0xcf, 0x27, 0xcb, 0x26, 0x61, 0x29, 0xcf, 0xb8, 0xa6, 0x26, 0x5a, + 0x31, 0xbb, 0x58, 0x82, 0xaa, 0x7f, 0xc9, 0xc2, 0x46, 0xc7, 0xec, 0x91, 0x0e, 0x31, 0x03, 0xeb, + 0x85, 0x34, 0x41, 0x9f, 0xc2, 0x82, 0xd9, 0x1d, 0x3a, 0x91, 0x38, 0x9d, 0xcc, 0xb0, 0xe9, 0x70, + 0x1c, 0x25, 0x08, 0x7d, 0xcf, 0xeb, 0xb1, 0xe9, 0x9c, 0x8d, 0x80, 0xe1, 0x50, 0x15, 0x96, 0x06, + 0xa4, 0x4b, 0xa7, 0x43, 0x6c, 0x4f, 0x33, 0x50, 0xc4, 0x48, 0xa4, 0x41, 0xee, 0xa5, 0xed, 0x39, + 0x2c, 0x06, 0xe6, 0x67, 0x65, 0x49, 0xa0, 0xe8, 0x13, 0x98, 0x0f, 0x4c, 0x6b, 0x34, 0x7b, 0x85, + 0xc6, 0x60, 0xea, 0x2b, 0x28, 0xd0, 0xd5, 0xe6, 0xb9, 0x7d, 0x4c, 0xac, 0x08, 0x3d, 0x84, 0xc2, + 0xc0, 0x76, 0x8d, 0x1b, 0x2c, 0xce, 0xfc, 0xc0, 0x76, 0xf9, 0x23, 0x03, 0x99, 0x17, 0x09, 0x28, + 0xfb, 0x3a, 0x90, 0x79, 0xc1, 0x1f, 0xd5, 0x00, 0xf2, 0x55, 0x7a, 0x2e, 0x65, 0xf9, 0x60, 0x0f, + 0x16, 0xd8, 0x21, 0x55, 0x18, 0x44, 0x29, 0x2c, 0xeb, 0x86, 0x79, 0x87, 0xf1, 0x8a, 0xca, 0xca, + 0x2b, 0xea, 0x3d, 0x58, 0xf1, 0xed, 0x0b, 0xe2, 0x18, 0xbd, 0xc0, 0xb4, 0x92, 0xc5, 0x98, 0xc5, + 0xcb, 0x4c, 0x7a, 0x24, 0x84, 0xea, 0xe7, 0x50, 0xaa, 0x79, 0x03, 0xdb, 0x35, 0xdd, 0x88, 0x91, + 0x86, 0x52, 0x54, 0xfd, 0x08, 0x16, 0x99, 0x85, 0xb0, 0x94, 0x61, 0x31, 0xbb, 0x37, 0xc5, 0x93, + 0xc9, 0xe0, 0xb1, 0xc0, 0xa9, 0x21, 0xac, 0xb2, 0x33, 0x52, 0x3b, 0x89, 0x61, 0xf4, 0x53, 0x58, + 0xed, 0x0a, 0x83, 0x46, 0xc2, 0x4e, 0xdf, 0xf0, 0x7b, 0x53, 0xd8, 0xaf, 0x1b, 0x26, 0x5e, 0xe9, + 0xa6, 0x34, 0xea, 0xaf, 0x33, 0x90, 0xab, 0x06, 0x9e, 0x7f, 0x62, 0xbb, 0xd1, 0x7f, 0xe0, 0xec, + 0x95, 0x4e, 0x55, 0xd9, 0x4b, 0xa9, 0x6a, 0x1f, 0xd6, 0xed, 0x81, 0xef, 0x05, 0x91, 0xe9, 0x5a, + 0x64, 0xd2, 0xfb, 0x68, 0xac, 0x4a, 0xa6, 0xe0, 0x27, 0xb0, 0x1e, 0x0f, 0x57, 0xf6, 0xfe, 0x11, + 0x80, 0x15, 0x78, 0xbe, 0xf1, 0x82, 0xca, 0xc5, 0x0c, 0x4c, 0xcb, 0x1a, 0x31, 0x0f, 0xce, 0x5b, + 0x31, 0xa3, 0xfa, 0x11, 0xac, 0x26, 0xf4, 0x6d, 0x33, 0x30, 0x07, 0x21, 0x7a, 0x17, 0x96, 0xcd, + 0xd0, 0x27, 0x56, 0x64, 0xb0, 0xcb, 0x15, 0xce, 0x9e, 0xc5, 0x45, 0x2e, 0xc4, 0x4c, 0xa6, 0xd6, + 0x00, 0x3d, 0x25, 0xe7, 0xb5, 0xf8, 0x08, 0x25, 0xa0, 0x65, 0x58, 0xb7, 0x5d, 0xcb, 0x19, 0x76, + 0x89, 0xd1, 0x27, 0x5e, 0xea, 0x36, 0x23, 0x87, 0xd7, 0x84, 0xea, 0x98, 0x78, 0xe2, 0x52, 0x43, + 0xfd, 0x7d, 0x16, 0x8a, 0x2c, 0x04, 0xaa, 0xf4, 0x8c, 0x7d, 0x11, 0xa1, 0x26, 0x2c, 0xb3, 0x55, + 0xe1, 0xb9, 0x7d, 0x23, 0x20, 0x56, 0x24, 0x26, 0x64, 0xda, 0x51, 0x5b, 0x5a, 0x91, 0xb8, 0xe0, + 0x48, 0xcb, 0xf3, 0x3d, 0x58, 0x71, 0x4c, 0xb7, 0x3f, 0xa4, 0xc7, 0x7e, 0xee, 0xaa, 0xec, 0xee, + 0xdc, 0x5e, 0x1e, 0x2f, 0xc7, 0x52, 0xf6, 0xe2, 0xe8, 0x39, 0xac, 0x8d, 0xbd, 0x69, 0xf8, 0xec, + 0x65, 0x44, 0xcd, 0x5b, 0xbe, 0xa1, 0x53, 0x85, 0xf7, 0xf0, 0xaa, 0x35, 0xe1, 0x4e, 0x0b, 0x36, + 0x52, 0xf7, 0x59, 0x31, 0xfd, 0x22, 0xa3, 0x7f, 0x30, 0x85, 0xfe, 0xb2, 0x93, 0x31, 0x7a, 0x75, + 0x49, 0xa6, 0xfe, 0x2d, 0x03, 0x1b, 0x22, 0x3a, 0x08, 0x73, 0x28, 0x26, 0x5f, 0x0d, 0x49, 0x18, + 0xa1, 0x47, 0xb0, 0xc0, 0xee, 0x38, 0x84, 0x23, 0xff, 0xe7, 0x26, 0x77, 0x16, 0x98, 0x43, 0xd0, + 0x21, 0xe4, 0x7a, 0xfc, 0xa6, 0x8a, 0xbb, 0xad, 0x70, 0xf0, 0xbf, 0x37, 0xbb, 0xd8, 0xc2, 0x09, + 0x8e, 0xae, 0x30, 0x7e, 0xe9, 0x62, 0xf1, 0x19, 0x66, 0x91, 0x3e, 0x7d, 0x85, 0xc9, 0x41, 0x81, + 0x8b, 0xb6, 0xd4, 0x52, 0x1f, 0xc3, 0x16, 0xd3, 0x8e, 0x17, 0x43, 0x1c, 0x3c, 0x0a, 0xcc, 0x8d, + 0xaf, 0x7e, 0xe8, 0x23, 0xba, 0x07, 0x05, 0x9f, 0x1a, 0x77, 0x87, 0x83, 0x73, 0x12, 0xc4, 0xb7, + 0x6a, 0x54, 0xd4, 0x64, 0x12, 0xf5, 0xcf, 0x39, 0xd8, 0x9c, 0xf0, 0x5b, 0xe8, 0x7b, 0x6e, 0x48, + 0xd0, 0x67, 0xa0, 0xf4, 0x4c, 0x8b, 0x48, 0x77, 0x97, 0xf1, 0x32, 0xfb, 0xee, 0x4c, 0x47, 0x2b, + 0xbc, 0xda, 0x4b, 0xb5, 0x43, 0x74, 0x0e, 0x1b, 0xf1, 0x2d, 0x42, 0x8a, 0x9d, 0xbb, 0x78, 0x7f, + 0x0a, 0xfb, 0x64, 0xf9, 0x85, 0xd7, 0x63, 0x32, 0xd9, 0xc6, 0x73, 0x50, 0x1c, 0xaf, 0xef, 0xa5, + 0xf8, 0xe7, 0xde, 0x8c, 0x7f, 0x95, 0x12, 0xc9, 0xdc, 0x9f, 0xc3, 0x9a, 0x63, 0x9e, 0x13, 0x27, + 0x45, 0x3e, 0xff, 0x66, 0xe4, 0x0a, 0x63, 0x9a, 0x18, 0xf9, 0xc4, 0x9d, 0x71, 0x58, 0x5a, 0x78, + 0xc3, 0x91, 0x53, 0x22, 0x99, 0xdb, 0x80, 0x8d, 0xde, 0xd0, 0x71, 0x8c, 0x09, 0x03, 0xec, 0x9e, + 0x62, 0xfa, 0xbc, 0xea, 0x29, 0x36, 0x8c, 0x28, 0x55, 0x5a, 0x86, 0x6c, 0xd8, 0x0a, 0xcd, 0x1e, + 0x31, 0x42, 0x56, 0x82, 0xc9, 0x26, 0xf8, 0x6a, 0x7f, 0x38, 0xc5, 0xc4, 0x55, 0xe5, 0x1b, 0xde, + 0x08, 0xaf, 0x2a, 0xea, 0x5c, 0xb8, 0xc3, 0x17, 0xd6, 0xb8, 0x02, 0x94, 0xed, 0xe5, 0x6e, 0x94, + 0xbc, 0x26, 0xb6, 0x5f, 0x7c, 0xdb, 0x4e, 0x0b, 0x24, 0x7b, 0x3d, 0xd8, 0x94, 0x52, 0xa4, 0x64, + 0xa9, 0xc0, 0x2c, 0x1d, 0xdc, 0x34, 0x4d, 0xca, 0x91, 0x6b, 0x5d, 0xb1, 0xb1, 0xb5, 0x61, 0x39, + 0x95, 0x2e, 0xd9, 0x1d, 0xcf, 0xf4, 0x84, 0x21, 0xe7, 0x49, 0x5c, 0x94, 0x33, 0x24, 0xad, 0x95, + 0x48, 0x10, 0x78, 0x01, 0xab, 0xf8, 0xa4, 0x5a, 0x29, 0xf0, 0xad, 0x72, 0x87, 0x7d, 0x03, 0xc0, + 0xbc, 0x03, 0x6a, 0x89, 0xbb, 0xdf, 0x8b, 0xa8, 0xb4, 0xc9, 0xfa, 0x7e, 0x78, 0x13, 0xff, 0x5d, + 0x4a, 0x44, 0x38, 0x66, 0x51, 0x07, 0xb0, 0x7d, 0x68, 0x46, 0xc9, 0xbc, 0xf1, 0x14, 0x13, 0xc6, + 0xb9, 0xb9, 0x05, 0xb9, 0x80, 0x3f, 0xc6, 0xa9, 0x65, 0x5a, 0x7c, 0x5c, 0x95, 0xe2, 0x71, 0x42, + 0xa2, 0x7e, 0x05, 0x77, 0xae, 0x34, 0x27, 0x52, 0x1a, 0x86, 0x7c, 0x20, 0x9e, 0x63, 0x83, 0x1f, + 0xcc, 0x66, 0x90, 0x83, 0xf1, 0x98, 0x46, 0xfd, 0x43, 0x16, 0x4a, 0x95, 0x70, 0xe4, 0x5a, 0x71, + 0xcf, 0x23, 0xdb, 0x49, 0x36, 0x9f, 0x53, 0x28, 0xda, 0xae, 0x3f, 0x8c, 0xf8, 0x3d, 0x6a, 0xff, + 0x86, 0x9b, 0x79, 0x9d, 0x42, 0xd8, 0xe5, 0x6a, 0x1f, 0x17, 0xec, 0x71, 0xe3, 0xbf, 0x73, 0x3f, + 0xa2, 0x8c, 0xde, 0x30, 0x92, 0xde, 0x72, 0xfe, 0x46, 0x8c, 0x2d, 0x86, 0x11, 0xaf, 0x59, 0xf4, + 0xa4, 0x96, 0x3a, 0x80, 0xdb, 0x57, 0xb8, 0x54, 0x4c, 0xe2, 0x25, 0x73, 0x99, 0x6f, 0x6b, 0x6e, + 0x08, 0x6f, 0x33, 0x73, 0xa9, 0xd0, 0xa1, 0x36, 0x93, 0x40, 0xed, 0x5c, 0x0a, 0xd4, 0x69, 0xe5, + 0xf8, 0x75, 0x21, 0x21, 0x05, 0xeb, 0x08, 0xee, 0x5d, 0x6b, 0x56, 0xbc, 0xeb, 0x93, 0xcb, 0x01, + 0xfb, 0xfd, 0xd9, 0x0d, 0x5f, 0x0e, 0xda, 0x10, 0x0a, 0x52, 0x90, 0xd1, 0x13, 0x78, 0xdf, 0x0a, + 0x0d, 0xf1, 0x71, 0x87, 0xfb, 0x73, 0xda, 0x69, 0xe6, 0xd8, 0x0a, 0xc5, 0xa7, 0x9d, 0x7c, 0x3f, + 0x7e, 0x44, 0x77, 0x20, 0x3f, 0xb0, 0x07, 0xc4, 0x60, 0xf7, 0xb0, 0xe2, 0x0b, 0x13, 0x15, 0xe8, + 0x23, 0x9f, 0xa8, 0x3f, 0xcb, 0x40, 0x51, 0x9e, 0x05, 0xf4, 0x04, 0x56, 0xa9, 0xd9, 0x2e, 0x09, + 0x23, 0xdb, 0xe5, 0xb9, 0x34, 0x73, 0xa3, 0x8d, 0xe8, 0xd8, 0x0a, 0x6b, 0x63, 0x10, 0x5e, 0xe9, + 0xa7, 0xda, 0x68, 0x07, 0xe0, 0x9c, 0xfa, 0xd4, 0x08, 0xed, 0xaf, 0x89, 0xa8, 0x79, 0xf2, 0x4c, + 0xd2, 0xb1, 0xbf, 0x26, 0xea, 0x0e, 0xe4, 0x93, 0xc1, 0x5f, 0x2e, 0x99, 0x54, 0x15, 0x56, 0xd2, + 0xfc, 0x57, 0xf4, 0xf9, 0x4d, 0x16, 0xd6, 0x5a, 0xf1, 0xb7, 0xd7, 0x53, 0x12, 0x99, 0x5d, 0x33, + 0x32, 0x51, 0x03, 0x16, 0x42, 0xea, 0x75, 0x71, 0xcd, 0x30, 0xed, 0xdb, 0xd0, 0x25, 0x02, 0x96, + 0x8c, 0x09, 0xe6, 0x24, 0xe8, 0x63, 0x28, 0x58, 0x01, 0x31, 0x23, 0x62, 0x44, 0xf6, 0x80, 0x5f, + 0xfa, 0x14, 0x0e, 0xb6, 0x63, 0xce, 0xf8, 0x03, 0x6f, 0x59, 0x8f, 0x3f, 0xf0, 0x62, 0xe0, 0xdd, + 0xa9, 0x80, 0x82, 0x87, 0x7e, 0x37, 0x01, 0x2f, 0x4e, 0x07, 0xf3, 0xee, 0x54, 0xa0, 0xfe, 0x18, + 0x16, 0xd8, 0x48, 0xd0, 0x26, 0xac, 0x75, 0xf4, 0x8a, 0x3e, 0xf9, 0x51, 0xb5, 0x00, 0x4b, 0x55, + 0xac, 0x55, 0x74, 0xad, 0xa6, 0x64, 0x68, 0x03, 0x9f, 0x35, 0x9b, 0xf5, 0xe6, 0xb1, 0x92, 0x45, + 0x39, 0x98, 0xaf, 0xb5, 0x9a, 0x9a, 0x32, 0x87, 0x96, 0x21, 0x5f, 0xad, 0x34, 0xab, 0x5a, 0xa3, + 0xa1, 0xd5, 0x94, 0xf9, 0xfb, 0x04, 0x40, 0xfa, 0x24, 0x50, 0x80, 0x25, 0x71, 0x15, 0xae, 0xbc, + 0x85, 0xd6, 0x60, 0xf9, 0x89, 0x86, 0x9f, 0x19, 0x67, 0xcd, 0x46, 0xfd, 0xb1, 0xd6, 0x78, 0xa6, + 0x64, 0x50, 0x11, 0x72, 0x49, 0x2b, 0x4b, 0x5b, 0xed, 0x56, 0xa7, 0x53, 0x3f, 0x6c, 0x50, 0x62, + 0x80, 0x45, 0xa1, 0x99, 0x47, 0xab, 0x50, 0x60, 0x50, 0x21, 0x58, 0x38, 0xf8, 0x7b, 0x16, 0x56, + 0xe4, 0x2d, 0xc9, 0x0b, 0xd0, 0x6f, 0x33, 0xb0, 0x7e, 0xc5, 0x9e, 0x80, 0x7e, 0x30, 0xed, 0x88, + 0x7b, 0xed, 0xb6, 0xb5, 0xfd, 0xe8, 0x4d, 0xa0, 0x7c, 0xe9, 0xa9, 0xef, 0x7d, 0xf3, 0xc7, 0xbf, + 0xfe, 0x3c, 0x7b, 0x4f, 0xdd, 0x9e, 0xfc, 0x0b, 0x43, 0xf8, 0x48, 0x94, 0x14, 0xe4, 0x51, 0xe6, + 0x3e, 0xfa, 0x55, 0x06, 0x6e, 0x5d, 0x93, 0x1c, 0xd0, 0x27, 0x37, 0xc9, 0x00, 0xd7, 0xe6, 0xb2, + 0xed, 0x9d, 0x18, 0x2e, 0xfd, 0x91, 0x60, 0x1c, 0x8b, 0x6a, 0x99, 0x0d, 0x70, 0x4f, 0x7d, 0x57, + 0x1a, 0x60, 0x8f, 0xe2, 0x1f, 0x99, 0x97, 0x78, 0x1f, 0x65, 0xee, 0x1f, 0x7e, 0x93, 0x81, 0x77, + 0x2c, 0x6f, 0xf0, 0xfa, 0x31, 0x1d, 0xae, 0xa7, 0x67, 0xa5, 0x4d, 0x03, 0xb0, 0x9d, 0x79, 0x5e, + 0x15, 0xa8, 0xbe, 0x47, 0x8f, 0xa3, 0x65, 0x2f, 0xe8, 0xef, 0xf7, 0x89, 0xcb, 0xc2, 0x73, 0x9f, + 0xab, 0x4c, 0xdf, 0x0e, 0xaf, 0xf9, 0x97, 0xc4, 0xc7, 0x5c, 0xf0, 0xcf, 0x4c, 0xe6, 0x7c, 0x91, + 0x41, 0x1e, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x49, 0x4b, 0x80, 0x49, 0x2c, 0x22, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/text_annotation.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/text_annotation.pb.go new file mode 100644 index 0000000000..bea7c74efd --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/text_annotation.pb.go @@ -0,0 +1,593 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/cloud/vision/v1p2beta1/text_annotation.proto + +package vision + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Enum to denote the type of break found. New line, space etc. +type TextAnnotation_DetectedBreak_BreakType int32 + +const ( + // Unknown break label type. + TextAnnotation_DetectedBreak_UNKNOWN TextAnnotation_DetectedBreak_BreakType = 0 + // Regular space. + TextAnnotation_DetectedBreak_SPACE TextAnnotation_DetectedBreak_BreakType = 1 + // Sure space (very wide). + TextAnnotation_DetectedBreak_SURE_SPACE TextAnnotation_DetectedBreak_BreakType = 2 + // Line-wrapping break. + TextAnnotation_DetectedBreak_EOL_SURE_SPACE TextAnnotation_DetectedBreak_BreakType = 3 + // End-line hyphen that is not present in text; does not co-occur with + // `SPACE`, `LEADER_SPACE`, or `LINE_BREAK`. + TextAnnotation_DetectedBreak_HYPHEN TextAnnotation_DetectedBreak_BreakType = 4 + // Line break that ends a paragraph. + TextAnnotation_DetectedBreak_LINE_BREAK TextAnnotation_DetectedBreak_BreakType = 5 +) + +var TextAnnotation_DetectedBreak_BreakType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SPACE", + 2: "SURE_SPACE", + 3: "EOL_SURE_SPACE", + 4: "HYPHEN", + 5: "LINE_BREAK", +} +var TextAnnotation_DetectedBreak_BreakType_value = map[string]int32{ + "UNKNOWN": 0, + "SPACE": 1, + "SURE_SPACE": 2, + "EOL_SURE_SPACE": 3, + "HYPHEN": 4, + "LINE_BREAK": 5, +} + +func (x TextAnnotation_DetectedBreak_BreakType) String() string { + return proto.EnumName(TextAnnotation_DetectedBreak_BreakType_name, int32(x)) +} +func (TextAnnotation_DetectedBreak_BreakType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor2, []int{0, 1, 0} +} + +// Type of a block (text, image etc) as identified by OCR. +type Block_BlockType int32 + +const ( + // Unknown block type. + Block_UNKNOWN Block_BlockType = 0 + // Regular text block. + Block_TEXT Block_BlockType = 1 + // Table block. + Block_TABLE Block_BlockType = 2 + // Image block. + Block_PICTURE Block_BlockType = 3 + // Horizontal/vertical line box. + Block_RULER Block_BlockType = 4 + // Barcode block. + Block_BARCODE Block_BlockType = 5 +) + +var Block_BlockType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "TEXT", + 2: "TABLE", + 3: "PICTURE", + 4: "RULER", + 5: "BARCODE", +} +var Block_BlockType_value = map[string]int32{ + "UNKNOWN": 0, + "TEXT": 1, + "TABLE": 2, + "PICTURE": 3, + "RULER": 4, + "BARCODE": 5, +} + +func (x Block_BlockType) String() string { + return proto.EnumName(Block_BlockType_name, int32(x)) +} +func (Block_BlockType) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{2, 0} } + +// TextAnnotation contains a structured representation of OCR extracted text. +// The hierarchy of an OCR extracted text structure is like this: +// TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol +// Each structural component, starting from Page, may further have their own +// properties. Properties describe detected languages, breaks etc.. Please refer +// to the [TextAnnotation.TextProperty][google.cloud.vision.v1p2beta1.TextAnnotation.TextProperty] message definition below for more +// detail. +type TextAnnotation struct { + // List of pages detected by OCR. + Pages []*Page `protobuf:"bytes,1,rep,name=pages" json:"pages,omitempty"` + // UTF-8 text detected on the pages. + Text string `protobuf:"bytes,2,opt,name=text" json:"text,omitempty"` +} + +func (m *TextAnnotation) Reset() { *m = TextAnnotation{} } +func (m *TextAnnotation) String() string { return proto.CompactTextString(m) } +func (*TextAnnotation) ProtoMessage() {} +func (*TextAnnotation) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } + +func (m *TextAnnotation) GetPages() []*Page { + if m != nil { + return m.Pages + } + return nil +} + +func (m *TextAnnotation) GetText() string { + if m != nil { + return m.Text + } + return "" +} + +// Detected language for a structural component. +type TextAnnotation_DetectedLanguage struct { + // The BCP-47 language code, such as "en-US" or "sr-Latn". For more + // information, see + // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + LanguageCode string `protobuf:"bytes,1,opt,name=language_code,json=languageCode" json:"language_code,omitempty"` + // Confidence of detected language. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,2,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *TextAnnotation_DetectedLanguage) Reset() { *m = TextAnnotation_DetectedLanguage{} } +func (m *TextAnnotation_DetectedLanguage) String() string { return proto.CompactTextString(m) } +func (*TextAnnotation_DetectedLanguage) ProtoMessage() {} +func (*TextAnnotation_DetectedLanguage) Descriptor() ([]byte, []int) { + return fileDescriptor2, []int{0, 0} +} + +func (m *TextAnnotation_DetectedLanguage) GetLanguageCode() string { + if m != nil { + return m.LanguageCode + } + return "" +} + +func (m *TextAnnotation_DetectedLanguage) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +// Detected start or end of a structural component. +type TextAnnotation_DetectedBreak struct { + // Detected break type. + Type TextAnnotation_DetectedBreak_BreakType `protobuf:"varint,1,opt,name=type,enum=google.cloud.vision.v1p2beta1.TextAnnotation_DetectedBreak_BreakType" json:"type,omitempty"` + // True if break prepends the element. + IsPrefix bool `protobuf:"varint,2,opt,name=is_prefix,json=isPrefix" json:"is_prefix,omitempty"` +} + +func (m *TextAnnotation_DetectedBreak) Reset() { *m = TextAnnotation_DetectedBreak{} } +func (m *TextAnnotation_DetectedBreak) String() string { return proto.CompactTextString(m) } +func (*TextAnnotation_DetectedBreak) ProtoMessage() {} +func (*TextAnnotation_DetectedBreak) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0, 1} } + +func (m *TextAnnotation_DetectedBreak) GetType() TextAnnotation_DetectedBreak_BreakType { + if m != nil { + return m.Type + } + return TextAnnotation_DetectedBreak_UNKNOWN +} + +func (m *TextAnnotation_DetectedBreak) GetIsPrefix() bool { + if m != nil { + return m.IsPrefix + } + return false +} + +// Additional information detected on the structural component. +type TextAnnotation_TextProperty struct { + // A list of detected languages together with confidence. + DetectedLanguages []*TextAnnotation_DetectedLanguage `protobuf:"bytes,1,rep,name=detected_languages,json=detectedLanguages" json:"detected_languages,omitempty"` + // Detected start or end of a text segment. + DetectedBreak *TextAnnotation_DetectedBreak `protobuf:"bytes,2,opt,name=detected_break,json=detectedBreak" json:"detected_break,omitempty"` +} + +func (m *TextAnnotation_TextProperty) Reset() { *m = TextAnnotation_TextProperty{} } +func (m *TextAnnotation_TextProperty) String() string { return proto.CompactTextString(m) } +func (*TextAnnotation_TextProperty) ProtoMessage() {} +func (*TextAnnotation_TextProperty) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0, 2} } + +func (m *TextAnnotation_TextProperty) GetDetectedLanguages() []*TextAnnotation_DetectedLanguage { + if m != nil { + return m.DetectedLanguages + } + return nil +} + +func (m *TextAnnotation_TextProperty) GetDetectedBreak() *TextAnnotation_DetectedBreak { + if m != nil { + return m.DetectedBreak + } + return nil +} + +// Detected page from OCR. +type Page struct { + // Additional information detected on the page. + Property *TextAnnotation_TextProperty `protobuf:"bytes,1,opt,name=property" json:"property,omitempty"` + // Page width. For PDFs the unit is points. For images (including + // TIFFs) the unit is pixels. + Width int32 `protobuf:"varint,2,opt,name=width" json:"width,omitempty"` + // Page height. For PDFs the unit is points. For images (including + // TIFFs) the unit is pixels. + Height int32 `protobuf:"varint,3,opt,name=height" json:"height,omitempty"` + // List of blocks of text, images etc on this page. + Blocks []*Block `protobuf:"bytes,4,rep,name=blocks" json:"blocks,omitempty"` + // Confidence of the OCR results on the page. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,5,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *Page) Reset() { *m = Page{} } +func (m *Page) String() string { return proto.CompactTextString(m) } +func (*Page) ProtoMessage() {} +func (*Page) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } + +func (m *Page) GetProperty() *TextAnnotation_TextProperty { + if m != nil { + return m.Property + } + return nil +} + +func (m *Page) GetWidth() int32 { + if m != nil { + return m.Width + } + return 0 +} + +func (m *Page) GetHeight() int32 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *Page) GetBlocks() []*Block { + if m != nil { + return m.Blocks + } + return nil +} + +func (m *Page) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +// Logical element on the page. +type Block struct { + // Additional information detected for the block. + Property *TextAnnotation_TextProperty `protobuf:"bytes,1,opt,name=property" json:"property,omitempty"` + // The bounding box for the block. + // The vertices are in the order of top-left, top-right, bottom-right, + // bottom-left. When a rotation of the bounding box is detected the rotation + // is represented as around the top-left corner as defined when the text is + // read in the 'natural' orientation. + // For example: + // + // * when the text is horizontal it might look like: + // + // 0----1 + // | | + // 3----2 + // + // * when it's rotated 180 degrees around the top-left corner it becomes: + // + // 2----3 + // | | + // 1----0 + // + // and the vertice order will still be (0, 1, 2, 3). + BoundingBox *BoundingPoly `protobuf:"bytes,2,opt,name=bounding_box,json=boundingBox" json:"bounding_box,omitempty"` + // List of paragraphs in this block (if this blocks is of type text). + Paragraphs []*Paragraph `protobuf:"bytes,3,rep,name=paragraphs" json:"paragraphs,omitempty"` + // Detected block type (text, image etc) for this block. + BlockType Block_BlockType `protobuf:"varint,4,opt,name=block_type,json=blockType,enum=google.cloud.vision.v1p2beta1.Block_BlockType" json:"block_type,omitempty"` + // Confidence of the OCR results on the block. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,5,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *Block) Reset() { *m = Block{} } +func (m *Block) String() string { return proto.CompactTextString(m) } +func (*Block) ProtoMessage() {} +func (*Block) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} } + +func (m *Block) GetProperty() *TextAnnotation_TextProperty { + if m != nil { + return m.Property + } + return nil +} + +func (m *Block) GetBoundingBox() *BoundingPoly { + if m != nil { + return m.BoundingBox + } + return nil +} + +func (m *Block) GetParagraphs() []*Paragraph { + if m != nil { + return m.Paragraphs + } + return nil +} + +func (m *Block) GetBlockType() Block_BlockType { + if m != nil { + return m.BlockType + } + return Block_UNKNOWN +} + +func (m *Block) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +// Structural unit of text representing a number of words in certain order. +type Paragraph struct { + // Additional information detected for the paragraph. + Property *TextAnnotation_TextProperty `protobuf:"bytes,1,opt,name=property" json:"property,omitempty"` + // The bounding box for the paragraph. + // The vertices are in the order of top-left, top-right, bottom-right, + // bottom-left. When a rotation of the bounding box is detected the rotation + // is represented as around the top-left corner as defined when the text is + // read in the 'natural' orientation. + // For example: + // * when the text is horizontal it might look like: + // 0----1 + // | | + // 3----2 + // * when it's rotated 180 degrees around the top-left corner it becomes: + // 2----3 + // | | + // 1----0 + // and the vertice order will still be (0, 1, 2, 3). + BoundingBox *BoundingPoly `protobuf:"bytes,2,opt,name=bounding_box,json=boundingBox" json:"bounding_box,omitempty"` + // List of words in this paragraph. + Words []*Word `protobuf:"bytes,3,rep,name=words" json:"words,omitempty"` + // Confidence of the OCR results for the paragraph. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,4,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *Paragraph) Reset() { *m = Paragraph{} } +func (m *Paragraph) String() string { return proto.CompactTextString(m) } +func (*Paragraph) ProtoMessage() {} +func (*Paragraph) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{3} } + +func (m *Paragraph) GetProperty() *TextAnnotation_TextProperty { + if m != nil { + return m.Property + } + return nil +} + +func (m *Paragraph) GetBoundingBox() *BoundingPoly { + if m != nil { + return m.BoundingBox + } + return nil +} + +func (m *Paragraph) GetWords() []*Word { + if m != nil { + return m.Words + } + return nil +} + +func (m *Paragraph) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +// A word representation. +type Word struct { + // Additional information detected for the word. + Property *TextAnnotation_TextProperty `protobuf:"bytes,1,opt,name=property" json:"property,omitempty"` + // The bounding box for the word. + // The vertices are in the order of top-left, top-right, bottom-right, + // bottom-left. When a rotation of the bounding box is detected the rotation + // is represented as around the top-left corner as defined when the text is + // read in the 'natural' orientation. + // For example: + // * when the text is horizontal it might look like: + // 0----1 + // | | + // 3----2 + // * when it's rotated 180 degrees around the top-left corner it becomes: + // 2----3 + // | | + // 1----0 + // and the vertice order will still be (0, 1, 2, 3). + BoundingBox *BoundingPoly `protobuf:"bytes,2,opt,name=bounding_box,json=boundingBox" json:"bounding_box,omitempty"` + // List of symbols in the word. + // The order of the symbols follows the natural reading order. + Symbols []*Symbol `protobuf:"bytes,3,rep,name=symbols" json:"symbols,omitempty"` + // Confidence of the OCR results for the word. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,4,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *Word) Reset() { *m = Word{} } +func (m *Word) String() string { return proto.CompactTextString(m) } +func (*Word) ProtoMessage() {} +func (*Word) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{4} } + +func (m *Word) GetProperty() *TextAnnotation_TextProperty { + if m != nil { + return m.Property + } + return nil +} + +func (m *Word) GetBoundingBox() *BoundingPoly { + if m != nil { + return m.BoundingBox + } + return nil +} + +func (m *Word) GetSymbols() []*Symbol { + if m != nil { + return m.Symbols + } + return nil +} + +func (m *Word) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +// A single symbol representation. +type Symbol struct { + // Additional information detected for the symbol. + Property *TextAnnotation_TextProperty `protobuf:"bytes,1,opt,name=property" json:"property,omitempty"` + // The bounding box for the symbol. + // The vertices are in the order of top-left, top-right, bottom-right, + // bottom-left. When a rotation of the bounding box is detected the rotation + // is represented as around the top-left corner as defined when the text is + // read in the 'natural' orientation. + // For example: + // * when the text is horizontal it might look like: + // 0----1 + // | | + // 3----2 + // * when it's rotated 180 degrees around the top-left corner it becomes: + // 2----3 + // | | + // 1----0 + // and the vertice order will still be (0, 1, 2, 3). + BoundingBox *BoundingPoly `protobuf:"bytes,2,opt,name=bounding_box,json=boundingBox" json:"bounding_box,omitempty"` + // The actual UTF-8 representation of the symbol. + Text string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` + // Confidence of the OCR results for the symbol. Range [0, 1]. + Confidence float32 `protobuf:"fixed32,4,opt,name=confidence" json:"confidence,omitempty"` +} + +func (m *Symbol) Reset() { *m = Symbol{} } +func (m *Symbol) String() string { return proto.CompactTextString(m) } +func (*Symbol) ProtoMessage() {} +func (*Symbol) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{5} } + +func (m *Symbol) GetProperty() *TextAnnotation_TextProperty { + if m != nil { + return m.Property + } + return nil +} + +func (m *Symbol) GetBoundingBox() *BoundingPoly { + if m != nil { + return m.BoundingBox + } + return nil +} + +func (m *Symbol) GetText() string { + if m != nil { + return m.Text + } + return "" +} + +func (m *Symbol) GetConfidence() float32 { + if m != nil { + return m.Confidence + } + return 0 +} + +func init() { + proto.RegisterType((*TextAnnotation)(nil), "google.cloud.vision.v1p2beta1.TextAnnotation") + proto.RegisterType((*TextAnnotation_DetectedLanguage)(nil), "google.cloud.vision.v1p2beta1.TextAnnotation.DetectedLanguage") + proto.RegisterType((*TextAnnotation_DetectedBreak)(nil), "google.cloud.vision.v1p2beta1.TextAnnotation.DetectedBreak") + proto.RegisterType((*TextAnnotation_TextProperty)(nil), "google.cloud.vision.v1p2beta1.TextAnnotation.TextProperty") + proto.RegisterType((*Page)(nil), "google.cloud.vision.v1p2beta1.Page") + proto.RegisterType((*Block)(nil), "google.cloud.vision.v1p2beta1.Block") + proto.RegisterType((*Paragraph)(nil), "google.cloud.vision.v1p2beta1.Paragraph") + proto.RegisterType((*Word)(nil), "google.cloud.vision.v1p2beta1.Word") + proto.RegisterType((*Symbol)(nil), "google.cloud.vision.v1p2beta1.Symbol") + proto.RegisterEnum("google.cloud.vision.v1p2beta1.TextAnnotation_DetectedBreak_BreakType", TextAnnotation_DetectedBreak_BreakType_name, TextAnnotation_DetectedBreak_BreakType_value) + proto.RegisterEnum("google.cloud.vision.v1p2beta1.Block_BlockType", Block_BlockType_name, Block_BlockType_value) +} + +func init() { + proto.RegisterFile("google/cloud/vision/v1p2beta1/text_annotation.proto", fileDescriptor2) +} + +var fileDescriptor2 = []byte{ + // 774 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xd3, 0x48, + 0x14, 0x5f, 0x27, 0x76, 0x1a, 0xbf, 0xb4, 0x91, 0x77, 0x76, 0xb5, 0x8a, 0xb2, 0xbb, 0xa8, 0xa4, + 0x20, 0x55, 0x02, 0x39, 0x6a, 0x7a, 0x2a, 0x45, 0xa0, 0x38, 0xb5, 0xd4, 0xaa, 0x21, 0xb5, 0xa6, + 0x09, 0xa5, 0x5c, 0x2c, 0xff, 0x99, 0x3a, 0x56, 0x13, 0x8f, 0x65, 0xbb, 0x6d, 0x72, 0xe5, 0x8a, + 0x04, 0x5f, 0x88, 0x2f, 0x83, 0xc4, 0x09, 0xf1, 0x01, 0x38, 0x22, 0x8f, 0xed, 0x34, 0x09, 0xa2, + 0xe6, 0x8f, 0x38, 0xf4, 0x12, 0xcd, 0x7b, 0x79, 0xbf, 0x37, 0xef, 0xf7, 0x7b, 0xf3, 0x3c, 0x03, + 0xdb, 0x0e, 0xa5, 0xce, 0x88, 0x34, 0xad, 0x11, 0xbd, 0xb0, 0x9b, 0x97, 0x6e, 0xe8, 0x52, 0xaf, + 0x79, 0xb9, 0xe5, 0xb7, 0x4c, 0x12, 0x19, 0x5b, 0xcd, 0x88, 0x4c, 0x22, 0xdd, 0xf0, 0x3c, 0x1a, + 0x19, 0x91, 0x4b, 0x3d, 0xd9, 0x0f, 0x68, 0x44, 0xd1, 0xff, 0x09, 0x48, 0x66, 0x20, 0x39, 0x01, + 0xc9, 0x33, 0x50, 0xfd, 0xbf, 0x34, 0xa7, 0xe1, 0xbb, 0xcd, 0x6b, 0x6c, 0x98, 0x80, 0xeb, 0x0f, + 0x6f, 0xde, 0xd1, 0x21, 0x74, 0x4c, 0xa2, 0x60, 0x9a, 0x44, 0x37, 0x5e, 0x0b, 0x50, 0xed, 0x93, + 0x49, 0xd4, 0x9e, 0xe5, 0x41, 0x3b, 0x20, 0xf8, 0x86, 0x43, 0xc2, 0x1a, 0xb7, 0x5e, 0xdc, 0xac, + 0xb4, 0x36, 0xe4, 0x1b, 0xab, 0x91, 0x35, 0xc3, 0x21, 0x38, 0x41, 0x20, 0x04, 0x7c, 0xcc, 0xa8, + 0x56, 0x58, 0xe7, 0x36, 0x45, 0xcc, 0xd6, 0xf5, 0x13, 0x90, 0xf6, 0x48, 0x44, 0xac, 0x88, 0xd8, + 0x5d, 0xc3, 0x73, 0x2e, 0x0c, 0x87, 0xa0, 0x0d, 0x58, 0x1b, 0xa5, 0x6b, 0xdd, 0xa2, 0x36, 0xa9, + 0x71, 0x0c, 0xb0, 0x9a, 0x39, 0x3b, 0xd4, 0x26, 0xe8, 0x0e, 0x80, 0x45, 0xbd, 0x33, 0xd7, 0x26, + 0x9e, 0x45, 0x58, 0xca, 0x02, 0x9e, 0xf3, 0xd4, 0x3f, 0x71, 0xb0, 0x96, 0x65, 0x56, 0x02, 0x62, + 0x9c, 0xa3, 0x53, 0xe0, 0xa3, 0xa9, 0x9f, 0x64, 0xab, 0xb6, 0xd4, 0x9c, 0xc2, 0x17, 0x69, 0xcb, + 0x0b, 0xa9, 0x64, 0xf6, 0xdb, 0x9f, 0xfa, 0x04, 0xb3, 0x94, 0xe8, 0x5f, 0x10, 0xdd, 0x50, 0xf7, + 0x03, 0x72, 0xe6, 0x4e, 0x58, 0x2d, 0x65, 0x5c, 0x76, 0x43, 0x8d, 0xd9, 0x0d, 0x0b, 0xc4, 0x59, + 0x3c, 0xaa, 0xc0, 0xca, 0xa0, 0x77, 0xd8, 0x3b, 0x3a, 0xe9, 0x49, 0x7f, 0x20, 0x11, 0x84, 0x63, + 0xad, 0xdd, 0x51, 0x25, 0x0e, 0x55, 0x01, 0x8e, 0x07, 0x58, 0xd5, 0x13, 0xbb, 0x80, 0x10, 0x54, + 0xd5, 0xa3, 0xae, 0x3e, 0xe7, 0x2b, 0x22, 0x80, 0xd2, 0xfe, 0xa9, 0xb6, 0xaf, 0xf6, 0x24, 0x3e, + 0x8e, 0xef, 0x1e, 0xf4, 0x54, 0x5d, 0xc1, 0x6a, 0xfb, 0x50, 0x12, 0xea, 0xef, 0x39, 0x58, 0x8d, + 0x4b, 0xd6, 0x02, 0xea, 0x93, 0x20, 0x9a, 0xa2, 0x31, 0x20, 0x3b, 0xad, 0x59, 0xcf, 0x84, 0xcb, + 0x9a, 0xf6, 0xe4, 0xe7, 0xb8, 0x67, 0x0d, 0xc2, 0x7f, 0xda, 0x4b, 0x9e, 0x10, 0x99, 0x50, 0x9d, + 0x6d, 0x67, 0xc6, 0x6c, 0x99, 0x0c, 0x95, 0xd6, 0xee, 0x2f, 0xc8, 0x8c, 0xd7, 0xec, 0x79, 0xb3, + 0xf1, 0x91, 0x03, 0x3e, 0x3e, 0x4f, 0xe8, 0x39, 0x94, 0xfd, 0x94, 0x27, 0xeb, 0x66, 0xa5, 0xf5, + 0xe8, 0xc7, 0xb6, 0x99, 0x57, 0x0a, 0xcf, 0x72, 0xa1, 0xbf, 0x41, 0xb8, 0x72, 0xed, 0x68, 0xc8, + 0x6a, 0x17, 0x70, 0x62, 0xa0, 0x7f, 0xa0, 0x34, 0x24, 0xae, 0x33, 0x8c, 0x6a, 0x45, 0xe6, 0x4e, + 0x2d, 0xf4, 0x18, 0x4a, 0xe6, 0x88, 0x5a, 0xe7, 0x61, 0x8d, 0x67, 0xaa, 0xde, 0xcb, 0xa9, 0x41, + 0x89, 0x83, 0x71, 0x8a, 0x59, 0x3a, 0xbf, 0xc2, 0xf2, 0xf9, 0x6d, 0xbc, 0x2b, 0x82, 0xc0, 0x10, + 0xbf, 0x8d, 0x6d, 0x0f, 0x56, 0x4d, 0x7a, 0xe1, 0xd9, 0xae, 0xe7, 0xe8, 0x26, 0x9d, 0xa4, 0x0d, + 0x7b, 0x90, 0xc7, 0x22, 0x85, 0x68, 0x74, 0x34, 0xc5, 0x95, 0x2c, 0x81, 0x42, 0x27, 0x68, 0x1f, + 0xc0, 0x37, 0x02, 0xc3, 0x09, 0x0c, 0x7f, 0x18, 0xd6, 0x8a, 0x4c, 0x93, 0xcd, 0xdc, 0xcf, 0x43, + 0x0a, 0xc0, 0x73, 0x58, 0xf4, 0x0c, 0x80, 0xa9, 0xa4, 0xb3, 0x79, 0xe5, 0xd9, 0xbc, 0xca, 0xdf, + 0xa3, 0x6e, 0xf2, 0xcb, 0x06, 0x53, 0x34, 0xb3, 0x65, 0xae, 0xd4, 0x18, 0xc4, 0x19, 0x6e, 0x71, + 0x40, 0xcb, 0xc0, 0xf7, 0xd5, 0x17, 0x7d, 0x89, 0x8b, 0x47, 0xb5, 0xdf, 0x56, 0xba, 0xf1, 0x68, + 0x56, 0x60, 0x45, 0x3b, 0xe8, 0xf4, 0x07, 0x38, 0x9e, 0x49, 0x11, 0x04, 0x3c, 0xe8, 0xaa, 0x58, + 0xe2, 0x63, 0xbf, 0xd2, 0xc6, 0x9d, 0xa3, 0x3d, 0x55, 0x12, 0x1a, 0x6f, 0x0a, 0x20, 0xce, 0xc8, + 0xdd, 0x9a, 0x16, 0xee, 0x80, 0x70, 0x45, 0x03, 0x3b, 0xeb, 0x5e, 0xde, 0xc7, 0xfd, 0x84, 0x06, + 0x36, 0x4e, 0x10, 0x4b, 0x22, 0xf3, 0x5f, 0x89, 0xfc, 0xb6, 0x00, 0x7c, 0x1c, 0x7f, 0x6b, 0xb4, + 0x78, 0x0a, 0x2b, 0xe1, 0x74, 0x6c, 0xd2, 0x51, 0xa6, 0xc6, 0xfd, 0x9c, 0x54, 0xc7, 0x2c, 0x1a, + 0x67, 0xa8, 0x5c, 0x45, 0x3e, 0x70, 0x50, 0x4a, 0x30, 0xb7, 0x46, 0x93, 0xec, 0x06, 0x2f, 0x5e, + 0xdf, 0xe0, 0x79, 0x34, 0x95, 0x57, 0x1c, 0xdc, 0xb5, 0xe8, 0xf8, 0xe6, 0x3d, 0x95, 0xbf, 0x16, + 0x09, 0x69, 0xf1, 0xf3, 0x43, 0xe3, 0x5e, 0x76, 0x52, 0x94, 0x43, 0xe3, 0x3b, 0x4c, 0xa6, 0x81, + 0xd3, 0x74, 0x88, 0xc7, 0x1e, 0x27, 0xcd, 0xe4, 0x2f, 0xc3, 0x77, 0xc3, 0x6f, 0xbc, 0x66, 0x76, + 0x13, 0xc7, 0x67, 0x8e, 0x33, 0x4b, 0x0c, 0xb2, 0xfd, 0x25, 0x00, 0x00, 0xff, 0xff, 0xce, 0x91, + 0x71, 0x97, 0x71, 0x09, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/web_detection.pb.go b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/web_detection.pb.go new file mode 100644 index 0000000000..9185111e60 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/cloud/vision/v1p2beta1/web_detection.pb.go @@ -0,0 +1,278 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/cloud/vision/v1p2beta1/web_detection.proto + +package vision + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Relevant information for the image from the Internet. +type WebDetection struct { + // Deduced entities from similar images on the Internet. + WebEntities []*WebDetection_WebEntity `protobuf:"bytes,1,rep,name=web_entities,json=webEntities" json:"web_entities,omitempty"` + // Fully matching images from the Internet. + // Can include resized copies of the query image. + FullMatchingImages []*WebDetection_WebImage `protobuf:"bytes,2,rep,name=full_matching_images,json=fullMatchingImages" json:"full_matching_images,omitempty"` + // Partial matching images from the Internet. + // Those images are similar enough to share some key-point features. For + // example an original image will likely have partial matching for its crops. + PartialMatchingImages []*WebDetection_WebImage `protobuf:"bytes,3,rep,name=partial_matching_images,json=partialMatchingImages" json:"partial_matching_images,omitempty"` + // Web pages containing the matching images from the Internet. + PagesWithMatchingImages []*WebDetection_WebPage `protobuf:"bytes,4,rep,name=pages_with_matching_images,json=pagesWithMatchingImages" json:"pages_with_matching_images,omitempty"` + // The visually similar image results. + VisuallySimilarImages []*WebDetection_WebImage `protobuf:"bytes,6,rep,name=visually_similar_images,json=visuallySimilarImages" json:"visually_similar_images,omitempty"` + // The service's best guess as to the topic of the request image. + // Inferred from similar images on the open web. + BestGuessLabels []*WebDetection_WebLabel `protobuf:"bytes,8,rep,name=best_guess_labels,json=bestGuessLabels" json:"best_guess_labels,omitempty"` +} + +func (m *WebDetection) Reset() { *m = WebDetection{} } +func (m *WebDetection) String() string { return proto.CompactTextString(m) } +func (*WebDetection) ProtoMessage() {} +func (*WebDetection) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } + +func (m *WebDetection) GetWebEntities() []*WebDetection_WebEntity { + if m != nil { + return m.WebEntities + } + return nil +} + +func (m *WebDetection) GetFullMatchingImages() []*WebDetection_WebImage { + if m != nil { + return m.FullMatchingImages + } + return nil +} + +func (m *WebDetection) GetPartialMatchingImages() []*WebDetection_WebImage { + if m != nil { + return m.PartialMatchingImages + } + return nil +} + +func (m *WebDetection) GetPagesWithMatchingImages() []*WebDetection_WebPage { + if m != nil { + return m.PagesWithMatchingImages + } + return nil +} + +func (m *WebDetection) GetVisuallySimilarImages() []*WebDetection_WebImage { + if m != nil { + return m.VisuallySimilarImages + } + return nil +} + +func (m *WebDetection) GetBestGuessLabels() []*WebDetection_WebLabel { + if m != nil { + return m.BestGuessLabels + } + return nil +} + +// Entity deduced from similar images on the Internet. +type WebDetection_WebEntity struct { + // Opaque entity ID. + EntityId string `protobuf:"bytes,1,opt,name=entity_id,json=entityId" json:"entity_id,omitempty"` + // Overall relevancy score for the entity. + // Not normalized and not comparable across different image queries. + Score float32 `protobuf:"fixed32,2,opt,name=score" json:"score,omitempty"` + // Canonical description of the entity, in English. + Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` +} + +func (m *WebDetection_WebEntity) Reset() { *m = WebDetection_WebEntity{} } +func (m *WebDetection_WebEntity) String() string { return proto.CompactTextString(m) } +func (*WebDetection_WebEntity) ProtoMessage() {} +func (*WebDetection_WebEntity) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 0} } + +func (m *WebDetection_WebEntity) GetEntityId() string { + if m != nil { + return m.EntityId + } + return "" +} + +func (m *WebDetection_WebEntity) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *WebDetection_WebEntity) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +// Metadata for online images. +type WebDetection_WebImage struct { + // The result image URL. + Url string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + // (Deprecated) Overall relevancy score for the image. + Score float32 `protobuf:"fixed32,2,opt,name=score" json:"score,omitempty"` +} + +func (m *WebDetection_WebImage) Reset() { *m = WebDetection_WebImage{} } +func (m *WebDetection_WebImage) String() string { return proto.CompactTextString(m) } +func (*WebDetection_WebImage) ProtoMessage() {} +func (*WebDetection_WebImage) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 1} } + +func (m *WebDetection_WebImage) GetUrl() string { + if m != nil { + return m.Url + } + return "" +} + +func (m *WebDetection_WebImage) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +// Metadata for web pages. +type WebDetection_WebPage struct { + // The result web page URL. + Url string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + // (Deprecated) Overall relevancy score for the web page. + Score float32 `protobuf:"fixed32,2,opt,name=score" json:"score,omitempty"` + // Title for the web page, may contain HTML markups. + PageTitle string `protobuf:"bytes,3,opt,name=page_title,json=pageTitle" json:"page_title,omitempty"` + // Fully matching images on the page. + // Can include resized copies of the query image. + FullMatchingImages []*WebDetection_WebImage `protobuf:"bytes,4,rep,name=full_matching_images,json=fullMatchingImages" json:"full_matching_images,omitempty"` + // Partial matching images on the page. + // Those images are similar enough to share some key-point features. For + // example an original image will likely have partial matching for its + // crops. + PartialMatchingImages []*WebDetection_WebImage `protobuf:"bytes,5,rep,name=partial_matching_images,json=partialMatchingImages" json:"partial_matching_images,omitempty"` +} + +func (m *WebDetection_WebPage) Reset() { *m = WebDetection_WebPage{} } +func (m *WebDetection_WebPage) String() string { return proto.CompactTextString(m) } +func (*WebDetection_WebPage) ProtoMessage() {} +func (*WebDetection_WebPage) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 2} } + +func (m *WebDetection_WebPage) GetUrl() string { + if m != nil { + return m.Url + } + return "" +} + +func (m *WebDetection_WebPage) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *WebDetection_WebPage) GetPageTitle() string { + if m != nil { + return m.PageTitle + } + return "" +} + +func (m *WebDetection_WebPage) GetFullMatchingImages() []*WebDetection_WebImage { + if m != nil { + return m.FullMatchingImages + } + return nil +} + +func (m *WebDetection_WebPage) GetPartialMatchingImages() []*WebDetection_WebImage { + if m != nil { + return m.PartialMatchingImages + } + return nil +} + +// Label to provide extra metadata for the web detection. +type WebDetection_WebLabel struct { + // Label for extra metadata. + Label string `protobuf:"bytes,1,opt,name=label" json:"label,omitempty"` + // The BCP-47 language code for `label`, such as "en-US" or "sr-Latn". + // For more information, see + // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + LanguageCode string `protobuf:"bytes,2,opt,name=language_code,json=languageCode" json:"language_code,omitempty"` +} + +func (m *WebDetection_WebLabel) Reset() { *m = WebDetection_WebLabel{} } +func (m *WebDetection_WebLabel) String() string { return proto.CompactTextString(m) } +func (*WebDetection_WebLabel) ProtoMessage() {} +func (*WebDetection_WebLabel) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 3} } + +func (m *WebDetection_WebLabel) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + +func (m *WebDetection_WebLabel) GetLanguageCode() string { + if m != nil { + return m.LanguageCode + } + return "" +} + +func init() { + proto.RegisterType((*WebDetection)(nil), "google.cloud.vision.v1p2beta1.WebDetection") + proto.RegisterType((*WebDetection_WebEntity)(nil), "google.cloud.vision.v1p2beta1.WebDetection.WebEntity") + proto.RegisterType((*WebDetection_WebImage)(nil), "google.cloud.vision.v1p2beta1.WebDetection.WebImage") + proto.RegisterType((*WebDetection_WebPage)(nil), "google.cloud.vision.v1p2beta1.WebDetection.WebPage") + proto.RegisterType((*WebDetection_WebLabel)(nil), "google.cloud.vision.v1p2beta1.WebDetection.WebLabel") +} + +func init() { proto.RegisterFile("google/cloud/vision/v1p2beta1/web_detection.proto", fileDescriptor3) } + +var fileDescriptor3 = []byte{ + // 511 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0x95, 0x76, 0x1b, 0x8d, 0x5b, 0x04, 0xb3, 0x86, 0x16, 0x05, 0x26, 0x15, 0xb8, 0xf4, + 0x94, 0xa8, 0x1d, 0x9c, 0xb8, 0x6d, 0x4c, 0x68, 0x12, 0x48, 0x55, 0x40, 0x1a, 0xe2, 0x92, 0x39, + 0x89, 0x97, 0xbe, 0x92, 0x1b, 0x47, 0xb1, 0xd3, 0xaa, 0x37, 0x4e, 0x7c, 0x14, 0x3e, 0x23, 0x47, + 0xf4, 0xda, 0xee, 0x54, 0x51, 0x36, 0x31, 0x86, 0xb8, 0xf9, 0x7d, 0xac, 0xe7, 0xf9, 0xd9, 0xaf, + 0xff, 0x90, 0x71, 0x29, 0x65, 0x29, 0x78, 0x9c, 0x0b, 0xd9, 0x16, 0xf1, 0x02, 0x14, 0xc8, 0x2a, + 0x5e, 0x8c, 0xeb, 0x49, 0xc6, 0x35, 0x1b, 0xc7, 0x4b, 0x9e, 0xa5, 0x05, 0xd7, 0x3c, 0xd7, 0x20, + 0xab, 0xa8, 0x6e, 0xa4, 0x96, 0xf4, 0xc8, 0x5a, 0x22, 0x63, 0x89, 0xac, 0x25, 0xba, 0xb6, 0x84, + 0xcf, 0x5c, 0x22, 0xab, 0x21, 0x66, 0x55, 0x25, 0x35, 0x43, 0xaf, 0xb2, 0xe6, 0x17, 0xdf, 0x7c, + 0x32, 0xb8, 0xe0, 0xd9, 0xdb, 0x75, 0x26, 0xfd, 0x4c, 0x06, 0x08, 0xe1, 0x95, 0x06, 0x0d, 0x5c, + 0x05, 0xde, 0xb0, 0x3b, 0xea, 0x4f, 0x5e, 0x47, 0xb7, 0x42, 0xa2, 0xcd, 0x08, 0x2c, 0xce, 0xd0, + 0xbe, 0x4a, 0xfa, 0x4b, 0x37, 0x04, 0xae, 0xe8, 0x15, 0x39, 0xb8, 0x6a, 0x85, 0x48, 0xe7, 0x4c, + 0xe7, 0x33, 0xa8, 0xca, 0x14, 0xe6, 0xac, 0xe4, 0x2a, 0xe8, 0x18, 0xc2, 0xab, 0x3b, 0x12, 0xce, + 0xd1, 0x9c, 0x50, 0x4c, 0xfc, 0xe0, 0x02, 0x8d, 0xa4, 0xa8, 0x20, 0x87, 0x35, 0x6b, 0x34, 0xb0, + 0x6d, 0x54, 0xf7, 0x1e, 0xa8, 0x27, 0x2e, 0xf4, 0x17, 0x5a, 0x4d, 0xc2, 0x1a, 0x07, 0xe9, 0x12, + 0xf4, 0x6c, 0x0b, 0xb8, 0x63, 0x80, 0xc7, 0x77, 0x04, 0x4e, 0x91, 0x77, 0x68, 0x62, 0x2f, 0x40, + 0xcf, 0xb6, 0xf7, 0xb7, 0x00, 0xd5, 0x32, 0x21, 0x56, 0xa9, 0x82, 0x39, 0x08, 0xd6, 0xac, 0x71, + 0x7b, 0xf7, 0xd9, 0xdf, 0x3a, 0xf4, 0xa3, 0xcd, 0x74, 0xb4, 0x4b, 0xb2, 0x9f, 0x71, 0xa5, 0xd3, + 0xb2, 0xe5, 0x4a, 0xa5, 0x82, 0x65, 0x5c, 0xa8, 0xa0, 0xf7, 0x57, 0x9c, 0xf7, 0x68, 0x4e, 0x1e, + 0x61, 0xdc, 0x3b, 0x4c, 0x33, 0xb5, 0x0a, 0x2f, 0x89, 0x7f, 0x7d, 0x63, 0xe8, 0x53, 0xe2, 0x9b, + 0xab, 0xb7, 0x4a, 0xa1, 0x08, 0xbc, 0xa1, 0x37, 0xf2, 0x93, 0x9e, 0x15, 0xce, 0x0b, 0x7a, 0x40, + 0x76, 0x55, 0x2e, 0x1b, 0x1e, 0x74, 0x86, 0xde, 0xa8, 0x93, 0xd8, 0x82, 0x0e, 0x49, 0xbf, 0xe0, + 0x2a, 0x6f, 0xa0, 0x46, 0x50, 0xd0, 0x35, 0xa6, 0x4d, 0x29, 0x9c, 0x90, 0xde, 0x7a, 0x9b, 0xf4, + 0x31, 0xe9, 0xb6, 0x8d, 0x70, 0xd1, 0x38, 0xfc, 0x7d, 0x6a, 0xf8, 0xbd, 0x43, 0x1e, 0xb8, 0xa3, + 0xf8, 0x53, 0x0f, 0x3d, 0x22, 0x04, 0x0f, 0x2d, 0xd5, 0xa0, 0x05, 0x77, 0x0b, 0xf1, 0x51, 0xf9, + 0x84, 0xc2, 0x8d, 0x0f, 0x60, 0xe7, 0xff, 0x3d, 0x80, 0xdd, 0x7f, 0xfe, 0x00, 0xc2, 0x33, 0xd3, + 0x5c, 0x73, 0x96, 0xd8, 0x16, 0x73, 0x43, 0x5c, 0xab, 0x6c, 0x41, 0x5f, 0x92, 0x87, 0x82, 0x55, + 0x65, 0x8b, 0xad, 0xc9, 0x65, 0x61, 0x9b, 0xe6, 0x27, 0x83, 0xb5, 0x78, 0x2a, 0x0b, 0x7e, 0xf2, + 0xd5, 0x23, 0xcf, 0x73, 0x39, 0xbf, 0x7d, 0x65, 0x27, 0xfb, 0x9b, 0x4b, 0x9b, 0xe2, 0x0f, 0x36, + 0xf5, 0xbe, 0x9c, 0x3a, 0x4f, 0x29, 0x31, 0x31, 0x92, 0x4d, 0x19, 0x97, 0xbc, 0x32, 0xff, 0x5b, + 0x6c, 0xa7, 0x58, 0x0d, 0xea, 0x86, 0x2f, 0xf5, 0x8d, 0x15, 0x7e, 0x78, 0x5e, 0xb6, 0x67, 0x2c, + 0xc7, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x66, 0x62, 0xaa, 0xcd, 0x84, 0x05, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go new file mode 100644 index 0000000000..61570e2a18 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert.pb.go @@ -0,0 +1,904 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/monitoring/v3/alert.proto + +/* +Package monitoring is a generated protocol buffer package. + +It is generated from these files: + google/monitoring/v3/alert.proto + google/monitoring/v3/alert_service.proto + google/monitoring/v3/common.proto + google/monitoring/v3/group.proto + google/monitoring/v3/group_service.proto + google/monitoring/v3/metric.proto + google/monitoring/v3/metric_service.proto + google/monitoring/v3/mutation_record.proto + google/monitoring/v3/notification.proto + google/monitoring/v3/notification_service.proto + google/monitoring/v3/uptime.proto + google/monitoring/v3/uptime_service.proto + +It has these top-level messages: + AlertPolicy + CreateAlertPolicyRequest + GetAlertPolicyRequest + ListAlertPoliciesRequest + ListAlertPoliciesResponse + UpdateAlertPolicyRequest + DeleteAlertPolicyRequest + TypedValue + TimeInterval + Aggregation + Group + ListGroupsRequest + ListGroupsResponse + GetGroupRequest + CreateGroupRequest + UpdateGroupRequest + DeleteGroupRequest + ListGroupMembersRequest + ListGroupMembersResponse + Point + TimeSeries + ListMonitoredResourceDescriptorsRequest + ListMonitoredResourceDescriptorsResponse + GetMonitoredResourceDescriptorRequest + ListMetricDescriptorsRequest + ListMetricDescriptorsResponse + GetMetricDescriptorRequest + CreateMetricDescriptorRequest + DeleteMetricDescriptorRequest + ListTimeSeriesRequest + ListTimeSeriesResponse + CreateTimeSeriesRequest + CreateTimeSeriesError + MutationRecord + NotificationChannelDescriptor + NotificationChannel + ListNotificationChannelDescriptorsRequest + ListNotificationChannelDescriptorsResponse + GetNotificationChannelDescriptorRequest + CreateNotificationChannelRequest + ListNotificationChannelsRequest + ListNotificationChannelsResponse + GetNotificationChannelRequest + UpdateNotificationChannelRequest + DeleteNotificationChannelRequest + SendNotificationChannelVerificationCodeRequest + GetNotificationChannelVerificationCodeRequest + GetNotificationChannelVerificationCodeResponse + VerifyNotificationChannelRequest + UptimeCheckConfig + UptimeCheckIp + ListUptimeCheckConfigsRequest + ListUptimeCheckConfigsResponse + GetUptimeCheckConfigRequest + CreateUptimeCheckConfigRequest + UpdateUptimeCheckConfigRequest + DeleteUptimeCheckConfigRequest + ListUptimeCheckIpsRequest + ListUptimeCheckIpsResponse +*/ +package monitoring + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import google_protobuf3 "github.com/golang/protobuf/ptypes/duration" +import google_protobuf4 "github.com/golang/protobuf/ptypes/wrappers" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Operators for combining conditions. +type AlertPolicy_ConditionCombinerType int32 + +const ( + // An unspecified combiner. + AlertPolicy_COMBINE_UNSPECIFIED AlertPolicy_ConditionCombinerType = 0 + // Combine conditions using the logical `AND` operator. An + // incident is created only if all conditions are met + // simultaneously. This combiner is satisfied if all conditions are + // met, even if they are met on completely different resources. + AlertPolicy_AND AlertPolicy_ConditionCombinerType = 1 + // Combine conditions using the logical `OR` operator. An incident + // is created if any of the listed conditions is met. + AlertPolicy_OR AlertPolicy_ConditionCombinerType = 2 + // Combine conditions using logical `AND` operator, but unlike the regular + // `AND` option, an incident is created only if all conditions are met + // simultaneously on at least one resource. + AlertPolicy_AND_WITH_MATCHING_RESOURCE AlertPolicy_ConditionCombinerType = 3 +) + +var AlertPolicy_ConditionCombinerType_name = map[int32]string{ + 0: "COMBINE_UNSPECIFIED", + 1: "AND", + 2: "OR", + 3: "AND_WITH_MATCHING_RESOURCE", +} +var AlertPolicy_ConditionCombinerType_value = map[string]int32{ + "COMBINE_UNSPECIFIED": 0, + "AND": 1, + "OR": 2, + "AND_WITH_MATCHING_RESOURCE": 3, +} + +func (x AlertPolicy_ConditionCombinerType) String() string { + return proto.EnumName(AlertPolicy_ConditionCombinerType_name, int32(x)) +} +func (AlertPolicy_ConditionCombinerType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{0, 0} +} + +// A description of the conditions under which some aspect of your system is +// considered to be "unhealthy" and the ways to notify people or services about +// this state. For an overview of alert policies, see +// [Introduction to Alerting](/monitoring/alerts/). +type AlertPolicy struct { + // Required if the policy exists. The resource name for this policy. The + // syntax is: + // + // projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID] + // + // `[ALERT_POLICY_ID]` is assigned by Stackdriver Monitoring when the policy + // is created. When calling the + // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy] + // method, do not include the `name` field in the alerting policy passed as + // part of the request. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // A short name or phrase used to identify the policy in dashboards, + // notifications, and incidents. To avoid confusion, don't use the same + // display name for multiple policies in the same project. The name is + // limited to 512 Unicode characters. + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // Documentation that is included with notifications and incidents related to + // this policy. Best practice is for the documentation to include information + // to help responders understand, mitigate, escalate, and correct the + // underlying problems detected by the alerting policy. Notification channels + // that have limited capacity might not show this documentation. + Documentation *AlertPolicy_Documentation `protobuf:"bytes,13,opt,name=documentation" json:"documentation,omitempty"` + // User-supplied key/value data to be used for organizing and + // identifying the `AlertPolicy` objects. + // + // The field can contain up to 64 entries. Each key and value is limited to + // 63 Unicode characters or 128 bytes, whichever is smaller. Labels and + // values can contain only lowercase letters, numerals, underscores, and + // dashes. Keys must begin with a letter. + UserLabels map[string]string `protobuf:"bytes,16,rep,name=user_labels,json=userLabels" json:"user_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // A list of conditions for the policy. The conditions are combined by AND or + // OR according to the `combiner` field. If the combined conditions evaluate + // to true, then an incident is created. A policy can have from one to six + // conditions. + Conditions []*AlertPolicy_Condition `protobuf:"bytes,12,rep,name=conditions" json:"conditions,omitempty"` + // How to combine the results of multiple conditions + // to determine if an incident should be opened. + Combiner AlertPolicy_ConditionCombinerType `protobuf:"varint,6,opt,name=combiner,enum=google.monitoring.v3.AlertPolicy_ConditionCombinerType" json:"combiner,omitempty"` + // Whether or not the policy is enabled. On write, the default interpretation + // if unset is that the policy is enabled. On read, clients should not make + // any assumption about the state if it has not been populated. The + // field should always be populated on List and Get operations, unless + // a field projection has been specified that strips it out. + Enabled *google_protobuf4.BoolValue `protobuf:"bytes,17,opt,name=enabled" json:"enabled,omitempty"` + // Identifies the notification channels to which notifications should be sent + // when incidents are opened or closed or when new violations occur on + // an already opened incident. Each element of this array corresponds to + // the `name` field in each of the + // [`NotificationChannel`][google.monitoring.v3.NotificationChannel] + // objects that are returned from the [`ListNotificationChannels`] + // [google.monitoring.v3.NotificationChannelService.ListNotificationChannels] + // method. The syntax of the entries in this field is: + // + // projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID] + NotificationChannels []string `protobuf:"bytes,14,rep,name=notification_channels,json=notificationChannels" json:"notification_channels,omitempty"` + // A read-only record of the creation of the alerting policy. If provided + // in a call to create or update, this field will be ignored. + CreationRecord *MutationRecord `protobuf:"bytes,10,opt,name=creation_record,json=creationRecord" json:"creation_record,omitempty"` + // A read-only record of the most recent change to the alerting policy. If + // provided in a call to create or update, this field will be ignored. + MutationRecord *MutationRecord `protobuf:"bytes,11,opt,name=mutation_record,json=mutationRecord" json:"mutation_record,omitempty"` +} + +func (m *AlertPolicy) Reset() { *m = AlertPolicy{} } +func (m *AlertPolicy) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy) ProtoMessage() {} +func (*AlertPolicy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *AlertPolicy) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AlertPolicy) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *AlertPolicy) GetDocumentation() *AlertPolicy_Documentation { + if m != nil { + return m.Documentation + } + return nil +} + +func (m *AlertPolicy) GetUserLabels() map[string]string { + if m != nil { + return m.UserLabels + } + return nil +} + +func (m *AlertPolicy) GetConditions() []*AlertPolicy_Condition { + if m != nil { + return m.Conditions + } + return nil +} + +func (m *AlertPolicy) GetCombiner() AlertPolicy_ConditionCombinerType { + if m != nil { + return m.Combiner + } + return AlertPolicy_COMBINE_UNSPECIFIED +} + +func (m *AlertPolicy) GetEnabled() *google_protobuf4.BoolValue { + if m != nil { + return m.Enabled + } + return nil +} + +func (m *AlertPolicy) GetNotificationChannels() []string { + if m != nil { + return m.NotificationChannels + } + return nil +} + +func (m *AlertPolicy) GetCreationRecord() *MutationRecord { + if m != nil { + return m.CreationRecord + } + return nil +} + +func (m *AlertPolicy) GetMutationRecord() *MutationRecord { + if m != nil { + return m.MutationRecord + } + return nil +} + +// A content string and a MIME type that describes the content string's +// format. +type AlertPolicy_Documentation struct { + // The text of the documentation, interpreted according to `mime_type`. + // The content may not exceed 8,192 Unicode characters and may not exceed + // more than 10,240 bytes when encoded in UTF-8 format, whichever is + // smaller. + Content string `protobuf:"bytes,1,opt,name=content" json:"content,omitempty"` + // The format of the `content` field. Presently, only the value + // `"text/markdown"` is supported. See + // [Markdown](https://en.wikipedia.org/wiki/Markdown) for more information. + MimeType string `protobuf:"bytes,2,opt,name=mime_type,json=mimeType" json:"mime_type,omitempty"` +} + +func (m *AlertPolicy_Documentation) Reset() { *m = AlertPolicy_Documentation{} } +func (m *AlertPolicy_Documentation) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy_Documentation) ProtoMessage() {} +func (*AlertPolicy_Documentation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +func (m *AlertPolicy_Documentation) GetContent() string { + if m != nil { + return m.Content + } + return "" +} + +func (m *AlertPolicy_Documentation) GetMimeType() string { + if m != nil { + return m.MimeType + } + return "" +} + +// A condition is a true/false test that determines when an alerting policy +// should open an incident. If a condition evaluates to true, it signifies +// that something is wrong. +type AlertPolicy_Condition struct { + // Required if the condition exists. The unique resource name for this + // condition. Its syntax is: + // + // projects/[PROJECT_ID]/alertPolicies/[POLICY_ID]/conditions/[CONDITION_ID] + // + // `[CONDITION_ID]` is assigned by Stackdriver Monitoring when the + // condition is created as part of a new or updated alerting policy. + // + // When calling the + // [alertPolicies.create][google.monitoring.v3.AlertPolicyService.CreateAlertPolicy] + // method, do not include the `name` field in the conditions of the + // requested alerting policy. Stackdriver Monitoring creates the + // condition identifiers and includes them in the new policy. + // + // When calling the + // [alertPolicies.update][google.monitoring.v3.AlertPolicyService.UpdateAlertPolicy] + // method to update a policy, including a condition `name` causes the + // existing condition to be updated. Conditions without names are added to + // the updated policy. Existing conditions are deleted if they are not + // updated. + // + // Best practice is to preserve `[CONDITION_ID]` if you make only small + // changes, such as those to condition thresholds, durations, or trigger + // values. Otherwise, treat the change as a new condition and let the + // existing condition be deleted. + Name string `protobuf:"bytes,12,opt,name=name" json:"name,omitempty"` + // A short name or phrase used to identify the condition in dashboards, + // notifications, and incidents. To avoid confusion, don't use the same + // display name for multiple conditions in the same policy. + DisplayName string `protobuf:"bytes,6,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // Only one of the following condition types will be specified. + // + // Types that are valid to be assigned to Condition: + // *AlertPolicy_Condition_ConditionThreshold + // *AlertPolicy_Condition_ConditionAbsent + Condition isAlertPolicy_Condition_Condition `protobuf_oneof:"condition"` +} + +func (m *AlertPolicy_Condition) Reset() { *m = AlertPolicy_Condition{} } +func (m *AlertPolicy_Condition) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy_Condition) ProtoMessage() {} +func (*AlertPolicy_Condition) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} } + +type isAlertPolicy_Condition_Condition interface { + isAlertPolicy_Condition_Condition() +} + +type AlertPolicy_Condition_ConditionThreshold struct { + ConditionThreshold *AlertPolicy_Condition_MetricThreshold `protobuf:"bytes,1,opt,name=condition_threshold,json=conditionThreshold,oneof"` +} +type AlertPolicy_Condition_ConditionAbsent struct { + ConditionAbsent *AlertPolicy_Condition_MetricAbsence `protobuf:"bytes,2,opt,name=condition_absent,json=conditionAbsent,oneof"` +} + +func (*AlertPolicy_Condition_ConditionThreshold) isAlertPolicy_Condition_Condition() {} +func (*AlertPolicy_Condition_ConditionAbsent) isAlertPolicy_Condition_Condition() {} + +func (m *AlertPolicy_Condition) GetCondition() isAlertPolicy_Condition_Condition { + if m != nil { + return m.Condition + } + return nil +} + +func (m *AlertPolicy_Condition) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AlertPolicy_Condition) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *AlertPolicy_Condition) GetConditionThreshold() *AlertPolicy_Condition_MetricThreshold { + if x, ok := m.GetCondition().(*AlertPolicy_Condition_ConditionThreshold); ok { + return x.ConditionThreshold + } + return nil +} + +func (m *AlertPolicy_Condition) GetConditionAbsent() *AlertPolicy_Condition_MetricAbsence { + if x, ok := m.GetCondition().(*AlertPolicy_Condition_ConditionAbsent); ok { + return x.ConditionAbsent + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*AlertPolicy_Condition) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _AlertPolicy_Condition_OneofMarshaler, _AlertPolicy_Condition_OneofUnmarshaler, _AlertPolicy_Condition_OneofSizer, []interface{}{ + (*AlertPolicy_Condition_ConditionThreshold)(nil), + (*AlertPolicy_Condition_ConditionAbsent)(nil), + } +} + +func _AlertPolicy_Condition_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*AlertPolicy_Condition) + // condition + switch x := m.Condition.(type) { + case *AlertPolicy_Condition_ConditionThreshold: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ConditionThreshold); err != nil { + return err + } + case *AlertPolicy_Condition_ConditionAbsent: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ConditionAbsent); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("AlertPolicy_Condition.Condition has unexpected type %T", x) + } + return nil +} + +func _AlertPolicy_Condition_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*AlertPolicy_Condition) + switch tag { + case 1: // condition.condition_threshold + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(AlertPolicy_Condition_MetricThreshold) + err := b.DecodeMessage(msg) + m.Condition = &AlertPolicy_Condition_ConditionThreshold{msg} + return true, err + case 2: // condition.condition_absent + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(AlertPolicy_Condition_MetricAbsence) + err := b.DecodeMessage(msg) + m.Condition = &AlertPolicy_Condition_ConditionAbsent{msg} + return true, err + default: + return false, nil + } +} + +func _AlertPolicy_Condition_OneofSizer(msg proto.Message) (n int) { + m := msg.(*AlertPolicy_Condition) + // condition + switch x := m.Condition.(type) { + case *AlertPolicy_Condition_ConditionThreshold: + s := proto.Size(x.ConditionThreshold) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *AlertPolicy_Condition_ConditionAbsent: + s := proto.Size(x.ConditionAbsent) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// Specifies how many time series must fail a predicate to trigger a +// condition. If not specified, then a `{count: 1}` trigger is used. +type AlertPolicy_Condition_Trigger struct { + // A type of trigger. + // + // Types that are valid to be assigned to Type: + // *AlertPolicy_Condition_Trigger_Count + // *AlertPolicy_Condition_Trigger_Percent + Type isAlertPolicy_Condition_Trigger_Type `protobuf_oneof:"type"` +} + +func (m *AlertPolicy_Condition_Trigger) Reset() { *m = AlertPolicy_Condition_Trigger{} } +func (m *AlertPolicy_Condition_Trigger) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy_Condition_Trigger) ProtoMessage() {} +func (*AlertPolicy_Condition_Trigger) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{0, 1, 0} +} + +type isAlertPolicy_Condition_Trigger_Type interface { + isAlertPolicy_Condition_Trigger_Type() +} + +type AlertPolicy_Condition_Trigger_Count struct { + Count int32 `protobuf:"varint,1,opt,name=count,oneof"` +} +type AlertPolicy_Condition_Trigger_Percent struct { + Percent float64 `protobuf:"fixed64,2,opt,name=percent,oneof"` +} + +func (*AlertPolicy_Condition_Trigger_Count) isAlertPolicy_Condition_Trigger_Type() {} +func (*AlertPolicy_Condition_Trigger_Percent) isAlertPolicy_Condition_Trigger_Type() {} + +func (m *AlertPolicy_Condition_Trigger) GetType() isAlertPolicy_Condition_Trigger_Type { + if m != nil { + return m.Type + } + return nil +} + +func (m *AlertPolicy_Condition_Trigger) GetCount() int32 { + if x, ok := m.GetType().(*AlertPolicy_Condition_Trigger_Count); ok { + return x.Count + } + return 0 +} + +func (m *AlertPolicy_Condition_Trigger) GetPercent() float64 { + if x, ok := m.GetType().(*AlertPolicy_Condition_Trigger_Percent); ok { + return x.Percent + } + return 0 +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*AlertPolicy_Condition_Trigger) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _AlertPolicy_Condition_Trigger_OneofMarshaler, _AlertPolicy_Condition_Trigger_OneofUnmarshaler, _AlertPolicy_Condition_Trigger_OneofSizer, []interface{}{ + (*AlertPolicy_Condition_Trigger_Count)(nil), + (*AlertPolicy_Condition_Trigger_Percent)(nil), + } +} + +func _AlertPolicy_Condition_Trigger_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*AlertPolicy_Condition_Trigger) + // type + switch x := m.Type.(type) { + case *AlertPolicy_Condition_Trigger_Count: + b.EncodeVarint(1<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Count)) + case *AlertPolicy_Condition_Trigger_Percent: + b.EncodeVarint(2<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.Percent)) + case nil: + default: + return fmt.Errorf("AlertPolicy_Condition_Trigger.Type has unexpected type %T", x) + } + return nil +} + +func _AlertPolicy_Condition_Trigger_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*AlertPolicy_Condition_Trigger) + switch tag { + case 1: // type.count + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Type = &AlertPolicy_Condition_Trigger_Count{int32(x)} + return true, err + case 2: // type.percent + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Type = &AlertPolicy_Condition_Trigger_Percent{math.Float64frombits(x)} + return true, err + default: + return false, nil + } +} + +func _AlertPolicy_Condition_Trigger_OneofSizer(msg proto.Message) (n int) { + m := msg.(*AlertPolicy_Condition_Trigger) + // type + switch x := m.Type.(type) { + case *AlertPolicy_Condition_Trigger_Count: + n += proto.SizeVarint(1<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Count)) + case *AlertPolicy_Condition_Trigger_Percent: + n += proto.SizeVarint(2<<3 | proto.WireFixed64) + n += 8 + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +// A condition type that compares a collection of time series +// against a threshold. +type AlertPolicy_Condition_MetricThreshold struct { + // A [filter](/monitoring/api/v3/filters) that + // identifies which time series should be compared with the threshold. + // + // The filter is similar to the one that is specified in the + // [`MetricService.ListTimeSeries` + // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that + // call is useful to verify the time series that will be retrieved / + // processed) and must specify the metric type and optionally may contain + // restrictions on resource type, resource labels, and metric labels. + // This field may not exceed 2048 Unicode characters in length. + Filter string `protobuf:"bytes,2,opt,name=filter" json:"filter,omitempty"` + // Specifies the alignment of data points in individual time series as + // well as how to combine the retrieved time series together (such as + // when aggregating multiple streams on each resource to a single + // stream for each resource or when aggregating streams across all + // members of a group of resrouces). Multiple aggregations + // are applied in the order specified. + // + // This field is similar to the one in the + // [`MetricService.ListTimeSeries` request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list). + // It is advisable to use the `ListTimeSeries` method when debugging this field. + Aggregations []*Aggregation `protobuf:"bytes,8,rep,name=aggregations" json:"aggregations,omitempty"` + // A [filter](/monitoring/api/v3/filters) that identifies a time + // series that should be used as the denominator of a ratio that will be + // compared with the threshold. If a `denominator_filter` is specified, + // the time series specified by the `filter` field will be used as the + // numerator. + // + // The filter is similar to the one that is specified in the + // [`MetricService.ListTimeSeries` + // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that + // call is useful to verify the time series that will be retrieved / + // processed) and must specify the metric type and optionally may contain + // restrictions on resource type, resource labels, and metric labels. + // This field may not exceed 2048 Unicode characters in length. + DenominatorFilter string `protobuf:"bytes,9,opt,name=denominator_filter,json=denominatorFilter" json:"denominator_filter,omitempty"` + // Specifies the alignment of data points in individual time series + // selected by `denominatorFilter` as + // well as how to combine the retrieved time series together (such as + // when aggregating multiple streams on each resource to a single + // stream for each resource or when aggregating streams across all + // members of a group of resources). + // + // When computing ratios, the `aggregations` and + // `denominator_aggregations` fields must use the same alignment period + // and produce time series that have the same periodicity and labels. + // + // This field is similar to the one in the + // [`MetricService.ListTimeSeries` + // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list). It + // is advisable to use the `ListTimeSeries` method when debugging this + // field. + DenominatorAggregations []*Aggregation `protobuf:"bytes,10,rep,name=denominator_aggregations,json=denominatorAggregations" json:"denominator_aggregations,omitempty"` + // The comparison to apply between the time series (indicated by `filter` + // and `aggregation`) and the threshold (indicated by `threshold_value`). + // The comparison is applied on each time series, with the time series + // on the left-hand side and the threshold on the right-hand side. + // + // Only `COMPARISON_LT` and `COMPARISON_GT` are supported currently. + Comparison ComparisonType `protobuf:"varint,4,opt,name=comparison,enum=google.monitoring.v3.ComparisonType" json:"comparison,omitempty"` + // A value against which to compare the time series. + ThresholdValue float64 `protobuf:"fixed64,5,opt,name=threshold_value,json=thresholdValue" json:"threshold_value,omitempty"` + // The amount of time that a time series must violate the + // threshold to be considered failing. Currently, only values + // that are a multiple of a minute--e.g. 60, 120, or 300 + // seconds--are supported. If an invalid value is given, an + // error will be returned. The `Duration.nanos` field is + // ignored. When choosing a duration, it is useful to keep in mind the + // frequency of the underlying time series data (which may also be + // affected by any alignments specified in the `aggregation` field); + // a good duration is long enough so that a single outlier does not + // generate spurious alerts, but short enough that unhealthy states + // are detected and alerted on quickly. + Duration *google_protobuf3.Duration `protobuf:"bytes,6,opt,name=duration" json:"duration,omitempty"` + // The number/percent of time series for which the comparison must hold + // in order for the condition to trigger. If unspecified, then the + // condition will trigger if the comparison is true for any of the + // time series that have been identified by `filter` and `aggregations`, + // or by the ratio, if `denominator_filter` and `denominator_aggregations` + // are specified. + Trigger *AlertPolicy_Condition_Trigger `protobuf:"bytes,7,opt,name=trigger" json:"trigger,omitempty"` +} + +func (m *AlertPolicy_Condition_MetricThreshold) Reset() { *m = AlertPolicy_Condition_MetricThreshold{} } +func (m *AlertPolicy_Condition_MetricThreshold) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy_Condition_MetricThreshold) ProtoMessage() {} +func (*AlertPolicy_Condition_MetricThreshold) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{0, 1, 1} +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetFilter() string { + if m != nil { + return m.Filter + } + return "" +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetAggregations() []*Aggregation { + if m != nil { + return m.Aggregations + } + return nil +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetDenominatorFilter() string { + if m != nil { + return m.DenominatorFilter + } + return "" +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetDenominatorAggregations() []*Aggregation { + if m != nil { + return m.DenominatorAggregations + } + return nil +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetComparison() ComparisonType { + if m != nil { + return m.Comparison + } + return ComparisonType_COMPARISON_UNSPECIFIED +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetThresholdValue() float64 { + if m != nil { + return m.ThresholdValue + } + return 0 +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetDuration() *google_protobuf3.Duration { + if m != nil { + return m.Duration + } + return nil +} + +func (m *AlertPolicy_Condition_MetricThreshold) GetTrigger() *AlertPolicy_Condition_Trigger { + if m != nil { + return m.Trigger + } + return nil +} + +// A condition type that checks that monitored resources +// are reporting data. The configuration defines a metric and +// a set of monitored resources. The predicate is considered in violation +// when a time series for the specified metric of a monitored +// resource does not include any data in the specified `duration`. +type AlertPolicy_Condition_MetricAbsence struct { + // A [filter](/monitoring/api/v3/filters) that + // identifies which time series should be compared with the threshold. + // + // The filter is similar to the one that is specified in the + // [`MetricService.ListTimeSeries` + // request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list) (that + // call is useful to verify the time series that will be retrieved / + // processed) and must specify the metric type and optionally may contain + // restrictions on resource type, resource labels, and metric labels. + // This field may not exceed 2048 Unicode characters in length. + Filter string `protobuf:"bytes,1,opt,name=filter" json:"filter,omitempty"` + // Specifies the alignment of data points in individual time series as + // well as how to combine the retrieved time series together (such as + // when aggregating multiple streams on each resource to a single + // stream for each resource or when aggregating streams across all + // members of a group of resrouces). Multiple aggregations + // are applied in the order specified. + // + // This field is similar to the + // one in the [`MetricService.ListTimeSeries` request](/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list). + // It is advisable to use the `ListTimeSeries` method when debugging this field. + Aggregations []*Aggregation `protobuf:"bytes,5,rep,name=aggregations" json:"aggregations,omitempty"` + // The amount of time that a time series must fail to report new + // data to be considered failing. Currently, only values that + // are a multiple of a minute--e.g. 60, 120, or 300 + // seconds--are supported. If an invalid value is given, an + // error will be returned. The `Duration.nanos` field is + // ignored. + Duration *google_protobuf3.Duration `protobuf:"bytes,2,opt,name=duration" json:"duration,omitempty"` + // The number/percent of time series for which the comparison must hold + // in order for the condition to trigger. If unspecified, then the + // condition will trigger if the comparison is true for any of the + // time series that have been identified by `filter` and `aggregations`. + Trigger *AlertPolicy_Condition_Trigger `protobuf:"bytes,3,opt,name=trigger" json:"trigger,omitempty"` +} + +func (m *AlertPolicy_Condition_MetricAbsence) Reset() { *m = AlertPolicy_Condition_MetricAbsence{} } +func (m *AlertPolicy_Condition_MetricAbsence) String() string { return proto.CompactTextString(m) } +func (*AlertPolicy_Condition_MetricAbsence) ProtoMessage() {} +func (*AlertPolicy_Condition_MetricAbsence) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{0, 1, 2} +} + +func (m *AlertPolicy_Condition_MetricAbsence) GetFilter() string { + if m != nil { + return m.Filter + } + return "" +} + +func (m *AlertPolicy_Condition_MetricAbsence) GetAggregations() []*Aggregation { + if m != nil { + return m.Aggregations + } + return nil +} + +func (m *AlertPolicy_Condition_MetricAbsence) GetDuration() *google_protobuf3.Duration { + if m != nil { + return m.Duration + } + return nil +} + +func (m *AlertPolicy_Condition_MetricAbsence) GetTrigger() *AlertPolicy_Condition_Trigger { + if m != nil { + return m.Trigger + } + return nil +} + +func init() { + proto.RegisterType((*AlertPolicy)(nil), "google.monitoring.v3.AlertPolicy") + proto.RegisterType((*AlertPolicy_Documentation)(nil), "google.monitoring.v3.AlertPolicy.Documentation") + proto.RegisterType((*AlertPolicy_Condition)(nil), "google.monitoring.v3.AlertPolicy.Condition") + proto.RegisterType((*AlertPolicy_Condition_Trigger)(nil), "google.monitoring.v3.AlertPolicy.Condition.Trigger") + proto.RegisterType((*AlertPolicy_Condition_MetricThreshold)(nil), "google.monitoring.v3.AlertPolicy.Condition.MetricThreshold") + proto.RegisterType((*AlertPolicy_Condition_MetricAbsence)(nil), "google.monitoring.v3.AlertPolicy.Condition.MetricAbsence") + proto.RegisterEnum("google.monitoring.v3.AlertPolicy_ConditionCombinerType", AlertPolicy_ConditionCombinerType_name, AlertPolicy_ConditionCombinerType_value) +} + +func init() { proto.RegisterFile("google/monitoring/v3/alert.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 941 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xeb, 0x6e, 0xe3, 0x44, + 0x14, 0xae, 0x93, 0xe6, 0x76, 0xd2, 0x36, 0xd9, 0xd9, 0xee, 0xae, 0x31, 0x68, 0x95, 0xae, 0x90, + 0x88, 0x40, 0x38, 0x22, 0x01, 0x71, 0x59, 0x81, 0x94, 0x5b, 0x37, 0x11, 0x24, 0xad, 0xa6, 0x69, + 0x91, 0x50, 0x25, 0xcb, 0x71, 0xa6, 0xae, 0x85, 0x3d, 0x63, 0x4d, 0xec, 0xa2, 0xbc, 0x0e, 0x3f, + 0x79, 0x14, 0x1e, 0x81, 0x7f, 0xbc, 0x02, 0xe2, 0x01, 0x90, 0xc7, 0x63, 0xc7, 0xe9, 0xa6, 0xbb, + 0x64, 0xf7, 0x5f, 0xce, 0x9c, 0xef, 0x7c, 0xe7, 0xf6, 0xcd, 0x38, 0xd0, 0xb0, 0x19, 0xb3, 0x5d, + 0xd2, 0xf2, 0x18, 0x75, 0x02, 0xc6, 0x1d, 0x6a, 0xb7, 0xee, 0x3a, 0x2d, 0xd3, 0x25, 0x3c, 0xd0, + 0x7d, 0xce, 0x02, 0x86, 0x8e, 0x63, 0x84, 0xbe, 0x46, 0xe8, 0x77, 0x1d, 0xed, 0x23, 0x19, 0x67, + 0xfa, 0x4e, 0xcb, 0xa4, 0x94, 0x05, 0x66, 0xe0, 0x30, 0xba, 0x8c, 0x63, 0xb4, 0x93, 0xad, 0xac, + 0x16, 0xf3, 0x3c, 0x46, 0x25, 0xe4, 0xd3, 0xad, 0x10, 0x2f, 0x8c, 0x89, 0x0c, 0x4e, 0x2c, 0xc6, + 0x17, 0x12, 0xfb, 0x5c, 0x62, 0x85, 0x35, 0x0f, 0x6f, 0x5a, 0x8b, 0x90, 0x0b, 0xd8, 0x43, 0xfe, + 0xdf, 0xb8, 0xe9, 0xfb, 0x84, 0xcb, 0x72, 0x5e, 0xfc, 0x5d, 0x83, 0x6a, 0x37, 0x6a, 0xe9, 0x9c, + 0xb9, 0x8e, 0xb5, 0x42, 0x08, 0xf6, 0xa9, 0xe9, 0x11, 0x55, 0x69, 0x28, 0xcd, 0x0a, 0x16, 0xbf, + 0xd1, 0x09, 0x1c, 0x2c, 0x9c, 0xa5, 0xef, 0x9a, 0x2b, 0x43, 0xf8, 0x72, 0xc2, 0x57, 0x95, 0x67, + 0xd3, 0x08, 0x72, 0x09, 0x87, 0x0b, 0x66, 0x85, 0x1e, 0xa1, 0x71, 0x91, 0xea, 0x61, 0x43, 0x69, + 0x56, 0xdb, 0x2d, 0x7d, 0xdb, 0x84, 0xf4, 0x4c, 0x42, 0x7d, 0x90, 0x0d, 0xc3, 0x9b, 0x2c, 0x08, + 0x43, 0x35, 0x5c, 0x12, 0x6e, 0xb8, 0xe6, 0x9c, 0xb8, 0x4b, 0xb5, 0xde, 0xc8, 0x37, 0xab, 0xed, + 0x2f, 0xde, 0x4e, 0x7a, 0xb9, 0x24, 0xfc, 0x27, 0x11, 0x33, 0xa4, 0x01, 0x5f, 0x61, 0x08, 0xd3, + 0x03, 0xf4, 0x23, 0x80, 0xc5, 0xe8, 0xc2, 0x11, 0x4b, 0x51, 0x0f, 0x04, 0xe5, 0x67, 0x6f, 0xa7, + 0xec, 0x27, 0x31, 0x38, 0x13, 0x8e, 0x2e, 0xa0, 0x6c, 0x31, 0x6f, 0xee, 0x50, 0xc2, 0xd5, 0x62, + 0x43, 0x69, 0x1e, 0xb5, 0xbf, 0xde, 0x81, 0xaa, 0x2f, 0x43, 0x67, 0x2b, 0x9f, 0xe0, 0x94, 0x08, + 0x7d, 0x09, 0x25, 0x42, 0xcd, 0xb9, 0x4b, 0x16, 0xea, 0x23, 0x31, 0x46, 0x2d, 0xe1, 0x4c, 0xb6, + 0xa8, 0xf7, 0x18, 0x73, 0xaf, 0x4c, 0x37, 0x24, 0x38, 0x81, 0xa2, 0x0e, 0x3c, 0xa1, 0x2c, 0x70, + 0x6e, 0x1c, 0x2b, 0x96, 0x89, 0x75, 0x6b, 0x52, 0x1a, 0x4d, 0xed, 0xa8, 0x91, 0x6f, 0x56, 0xf0, + 0x71, 0xd6, 0xd9, 0x97, 0x3e, 0x34, 0x81, 0x9a, 0xc5, 0x49, 0x56, 0x57, 0x2a, 0x88, 0x94, 0x1f, + 0x6f, 0x6f, 0x63, 0x22, 0x45, 0x88, 0x05, 0x16, 0x1f, 0x25, 0xc1, 0xb1, 0x1d, 0xd1, 0xdd, 0x93, + 0xa9, 0x5a, 0xdd, 0x85, 0xce, 0xdb, 0xb0, 0xb5, 0x53, 0x38, 0xdc, 0x90, 0x07, 0x52, 0xa1, 0x64, + 0x31, 0x1a, 0x10, 0x1a, 0x48, 0x81, 0x26, 0x26, 0xfa, 0x10, 0x2a, 0x9e, 0xe3, 0x11, 0x23, 0x58, + 0xf9, 0x89, 0x40, 0xcb, 0xd1, 0x41, 0x34, 0x5a, 0xed, 0xaf, 0x32, 0x54, 0xd2, 0xa1, 0xa7, 0x12, + 0x3f, 0x78, 0x83, 0xc4, 0x8b, 0xaf, 0x4b, 0x9c, 0xc2, 0xe3, 0x74, 0xf1, 0x46, 0x70, 0xcb, 0xc9, + 0xf2, 0x96, 0xb9, 0x0b, 0x51, 0x47, 0xb5, 0xfd, 0x72, 0x87, 0xad, 0xeb, 0x13, 0x12, 0x70, 0xc7, + 0x9a, 0x25, 0x14, 0xa3, 0x3d, 0x8c, 0x52, 0xe6, 0xf4, 0x14, 0xdd, 0x40, 0x7d, 0x9d, 0xcf, 0x9c, + 0x2f, 0xa3, 0xa6, 0x73, 0x22, 0xd9, 0xb7, 0xbb, 0x27, 0xeb, 0x46, 0xf1, 0x16, 0x19, 0xed, 0xe1, + 0x5a, 0x4a, 0x2a, 0xce, 0x02, 0x6d, 0x08, 0xa5, 0x19, 0x77, 0x6c, 0x9b, 0x70, 0xf4, 0x14, 0x0a, + 0x16, 0x0b, 0xe5, 0x70, 0x0b, 0xa3, 0x3d, 0x1c, 0x9b, 0x48, 0x83, 0x92, 0x4f, 0xb8, 0x95, 0x54, + 0xa0, 0x8c, 0xf6, 0x70, 0x72, 0xd0, 0x2b, 0xc2, 0x7e, 0x34, 0x73, 0xed, 0x9f, 0x3c, 0xd4, 0xee, + 0x35, 0x86, 0x9e, 0x42, 0xf1, 0xc6, 0x71, 0x03, 0xc2, 0xe5, 0x46, 0xa4, 0x85, 0x86, 0x70, 0x60, + 0xda, 0x36, 0x27, 0x76, 0xfc, 0x32, 0xaa, 0x65, 0x71, 0x09, 0x4f, 0x1e, 0x68, 0x6b, 0x8d, 0xc4, + 0x1b, 0x61, 0xe8, 0x73, 0x40, 0x0b, 0x42, 0x99, 0xe7, 0x50, 0x33, 0x60, 0xdc, 0x90, 0xa9, 0x2a, + 0x22, 0xd5, 0xa3, 0x8c, 0xe7, 0x34, 0xce, 0x7a, 0x0d, 0x6a, 0x16, 0xbe, 0x51, 0x01, 0xfc, 0xdf, + 0x0a, 0x9e, 0x65, 0x28, 0xba, 0xd9, 0x62, 0x06, 0xd1, 0xb3, 0xe2, 0xf9, 0x26, 0x77, 0x96, 0x8c, + 0xaa, 0xfb, 0xe2, 0x2d, 0x78, 0x40, 0xf5, 0xfd, 0x14, 0x27, 0x2e, 0x7e, 0x26, 0x0e, 0x7d, 0x02, + 0xb5, 0x54, 0x5a, 0xc6, 0x5d, 0x74, 0xc1, 0xd5, 0x42, 0x34, 0x71, 0x7c, 0x94, 0x1e, 0x8b, 0x6b, + 0x8f, 0xbe, 0x82, 0x72, 0xf2, 0xd2, 0x0b, 0xb1, 0x56, 0xdb, 0x1f, 0xbc, 0xf6, 0x48, 0x0c, 0x24, + 0x00, 0xa7, 0x50, 0x34, 0x81, 0x52, 0x10, 0x2f, 0x5b, 0x2d, 0x89, 0xa8, 0xce, 0x2e, 0x5a, 0x92, + 0x3a, 0xc1, 0x09, 0x87, 0xf6, 0xaf, 0x02, 0x87, 0x1b, 0x02, 0xcb, 0xac, 0x5c, 0x79, 0xe3, 0xca, + 0x0b, 0xef, 0xb6, 0xf2, 0x6c, 0xdb, 0xb9, 0x77, 0x6a, 0x3b, 0xff, 0xfe, 0x6d, 0xf7, 0xaa, 0x50, + 0x49, 0x6f, 0x91, 0xf6, 0x3d, 0xd4, 0xee, 0x7d, 0x6e, 0x50, 0x1d, 0xf2, 0xbf, 0x92, 0x95, 0x9c, + 0x40, 0xf4, 0x13, 0x1d, 0x43, 0x21, 0xde, 0x66, 0x7c, 0x11, 0x62, 0xe3, 0xbb, 0xdc, 0x37, 0xca, + 0x0b, 0x13, 0x9e, 0x6c, 0xfd, 0x1e, 0xa0, 0x67, 0xf0, 0xb8, 0x7f, 0x36, 0xe9, 0x8d, 0xa7, 0x43, + 0xe3, 0x72, 0x7a, 0x71, 0x3e, 0xec, 0x8f, 0x4f, 0xc7, 0xc3, 0x41, 0x7d, 0x0f, 0x95, 0x20, 0xdf, + 0x9d, 0x0e, 0xea, 0x0a, 0x2a, 0x42, 0xee, 0x0c, 0xd7, 0x73, 0xe8, 0x39, 0x68, 0xdd, 0xe9, 0xc0, + 0xf8, 0x79, 0x3c, 0x1b, 0x19, 0x93, 0xee, 0xac, 0x3f, 0x1a, 0x4f, 0x5f, 0x19, 0x78, 0x78, 0x71, + 0x76, 0x89, 0xfb, 0xc3, 0x7a, 0xbe, 0xf7, 0xbb, 0x02, 0xaa, 0xc5, 0xbc, 0xad, 0x2d, 0xf7, 0x20, + 0xee, 0x39, 0x1a, 0xde, 0xb9, 0xf2, 0xcb, 0x0f, 0x12, 0x63, 0x33, 0xd7, 0xa4, 0xb6, 0xce, 0xb8, + 0xdd, 0xb2, 0x09, 0x15, 0xa3, 0x6d, 0xc5, 0x2e, 0xd3, 0x77, 0x96, 0x9b, 0xff, 0x4c, 0x5e, 0xae, + 0xad, 0x3f, 0x72, 0xda, 0xab, 0x98, 0xa0, 0xef, 0xb2, 0x70, 0xa1, 0x4f, 0xd6, 0xa9, 0xae, 0x3a, + 0x7f, 0x26, 0xce, 0x6b, 0xe1, 0xbc, 0x5e, 0x3b, 0xaf, 0xaf, 0x3a, 0xf3, 0xa2, 0x48, 0xd2, 0xf9, + 0x2f, 0x00, 0x00, 0xff, 0xff, 0x66, 0xb5, 0x16, 0x64, 0x76, 0x09, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go new file mode 100644 index 0000000000..0b51478abe --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/alert_service.pb.go @@ -0,0 +1,527 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/monitoring/v3/alert_service.proto + +package monitoring + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import google_protobuf5 "github.com/golang/protobuf/ptypes/empty" +import google_protobuf6 "google.golang.org/genproto/protobuf/field_mask" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// The protocol for the `CreateAlertPolicy` request. +type CreateAlertPolicyRequest struct { + // The project in which to create the alerting policy. The format is + // `projects/[PROJECT_ID]`. + // + // Note that this field names the parent container in which the alerting + // policy will be written, not the name of the created policy. The alerting + // policy that is returned will have a name that contains a normalized + // representation of this name as a prefix but adds a suffix of the form + // `/alertPolicies/[POLICY_ID]`, identifying the policy in the container. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + // The requested alerting policy. You should omit the `name` field in this + // policy. The name will be returned in the new policy, including + // a new [ALERT_POLICY_ID] value. + AlertPolicy *AlertPolicy `protobuf:"bytes,2,opt,name=alert_policy,json=alertPolicy" json:"alert_policy,omitempty"` +} + +func (m *CreateAlertPolicyRequest) Reset() { *m = CreateAlertPolicyRequest{} } +func (m *CreateAlertPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*CreateAlertPolicyRequest) ProtoMessage() {} +func (*CreateAlertPolicyRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *CreateAlertPolicyRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreateAlertPolicyRequest) GetAlertPolicy() *AlertPolicy { + if m != nil { + return m.AlertPolicy + } + return nil +} + +// The protocol for the `GetAlertPolicy` request. +type GetAlertPolicyRequest struct { + // The alerting policy to retrieve. The format is + // + // projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID] + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *GetAlertPolicyRequest) Reset() { *m = GetAlertPolicyRequest{} } +func (m *GetAlertPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*GetAlertPolicyRequest) ProtoMessage() {} +func (*GetAlertPolicyRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *GetAlertPolicyRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The protocol for the `ListAlertPolicies` request. +type ListAlertPoliciesRequest struct { + // The project whose alert policies are to be listed. The format is + // + // projects/[PROJECT_ID] + // + // Note that this field names the parent container in which the alerting + // policies to be listed are stored. To retrieve a single alerting policy + // by name, use the + // [GetAlertPolicy][google.monitoring.v3.AlertPolicyService.GetAlertPolicy] + // operation, instead. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + // If provided, this field specifies the criteria that must be met by + // alert policies to be included in the response. + // + // For more details, see [sorting and + // filtering](/monitoring/api/v3/sorting-and-filtering). + Filter string `protobuf:"bytes,5,opt,name=filter" json:"filter,omitempty"` + // A comma-separated list of fields by which to sort the result. Supports + // the same set of field references as the `filter` field. Entries can be + // prefixed with a minus sign to sort by the field in descending order. + // + // For more details, see [sorting and + // filtering](/monitoring/api/v3/sorting-and-filtering). + OrderBy string `protobuf:"bytes,6,opt,name=order_by,json=orderBy" json:"order_by,omitempty"` + // The maximum number of results to return in a single response. + PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize" json:"page_size,omitempty"` + // If this field is not empty then it must contain the `nextPageToken` value + // returned by a previous call to this method. Using this field causes the + // method to return more results from the previous method call. + PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken" json:"page_token,omitempty"` +} + +func (m *ListAlertPoliciesRequest) Reset() { *m = ListAlertPoliciesRequest{} } +func (m *ListAlertPoliciesRequest) String() string { return proto.CompactTextString(m) } +func (*ListAlertPoliciesRequest) ProtoMessage() {} +func (*ListAlertPoliciesRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } + +func (m *ListAlertPoliciesRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ListAlertPoliciesRequest) GetFilter() string { + if m != nil { + return m.Filter + } + return "" +} + +func (m *ListAlertPoliciesRequest) GetOrderBy() string { + if m != nil { + return m.OrderBy + } + return "" +} + +func (m *ListAlertPoliciesRequest) GetPageSize() int32 { + if m != nil { + return m.PageSize + } + return 0 +} + +func (m *ListAlertPoliciesRequest) GetPageToken() string { + if m != nil { + return m.PageToken + } + return "" +} + +// The protocol for the `ListAlertPolicies` response. +type ListAlertPoliciesResponse struct { + // The returned alert policies. + AlertPolicies []*AlertPolicy `protobuf:"bytes,3,rep,name=alert_policies,json=alertPolicies" json:"alert_policies,omitempty"` + // If there might be more results than were returned, then this field is set + // to a non-empty value. To see the additional results, + // use that value as `pageToken` in the next call to this method. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (m *ListAlertPoliciesResponse) Reset() { *m = ListAlertPoliciesResponse{} } +func (m *ListAlertPoliciesResponse) String() string { return proto.CompactTextString(m) } +func (*ListAlertPoliciesResponse) ProtoMessage() {} +func (*ListAlertPoliciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } + +func (m *ListAlertPoliciesResponse) GetAlertPolicies() []*AlertPolicy { + if m != nil { + return m.AlertPolicies + } + return nil +} + +func (m *ListAlertPoliciesResponse) GetNextPageToken() string { + if m != nil { + return m.NextPageToken + } + return "" +} + +// The protocol for the `UpdateAlertPolicy` request. +type UpdateAlertPolicyRequest struct { + // Optional. A list of alerting policy field names. If this field is not + // empty, each listed field in the existing alerting policy is set to the + // value of the corresponding field in the supplied policy (`alert_policy`), + // or to the field's default value if the field is not in the supplied + // alerting policy. Fields not listed retain their previous value. + // + // Examples of valid field masks include `display_name`, `documentation`, + // `documentation.content`, `documentation.mime_type`, `user_labels`, + // `user_label.nameofkey`, `enabled`, `conditions`, `combiner`, etc. + // + // If this field is empty, then the supplied alerting policy replaces the + // existing policy. It is the same as deleting the existing policy and + // adding the supplied policy, except for the following: + // + // + The new policy will have the same `[ALERT_POLICY_ID]` as the former + // policy. This gives you continuity with the former policy in your + // notifications and incidents. + // + Conditions in the new policy will keep their former `[CONDITION_ID]` if + // the supplied condition includes the `name` field with that + // `[CONDITION_ID]`. If the supplied condition omits the `name` field, + // then a new `[CONDITION_ID]` is created. + UpdateMask *google_protobuf6.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` + // Required. The updated alerting policy or the updated values for the + // fields listed in `update_mask`. + // If `update_mask` is not empty, any fields in this policy that are + // not in `update_mask` are ignored. + AlertPolicy *AlertPolicy `protobuf:"bytes,3,opt,name=alert_policy,json=alertPolicy" json:"alert_policy,omitempty"` +} + +func (m *UpdateAlertPolicyRequest) Reset() { *m = UpdateAlertPolicyRequest{} } +func (m *UpdateAlertPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateAlertPolicyRequest) ProtoMessage() {} +func (*UpdateAlertPolicyRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } + +func (m *UpdateAlertPolicyRequest) GetUpdateMask() *google_protobuf6.FieldMask { + if m != nil { + return m.UpdateMask + } + return nil +} + +func (m *UpdateAlertPolicyRequest) GetAlertPolicy() *AlertPolicy { + if m != nil { + return m.AlertPolicy + } + return nil +} + +// The protocol for the `DeleteAlertPolicy` request. +type DeleteAlertPolicyRequest struct { + // The alerting policy to delete. The format is: + // + // projects/[PROJECT_ID]/alertPolicies/[ALERT_POLICY_ID] + // + // For more information, see [AlertPolicy][google.monitoring.v3.AlertPolicy]. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *DeleteAlertPolicyRequest) Reset() { *m = DeleteAlertPolicyRequest{} } +func (m *DeleteAlertPolicyRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteAlertPolicyRequest) ProtoMessage() {} +func (*DeleteAlertPolicyRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } + +func (m *DeleteAlertPolicyRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func init() { + proto.RegisterType((*CreateAlertPolicyRequest)(nil), "google.monitoring.v3.CreateAlertPolicyRequest") + proto.RegisterType((*GetAlertPolicyRequest)(nil), "google.monitoring.v3.GetAlertPolicyRequest") + proto.RegisterType((*ListAlertPoliciesRequest)(nil), "google.monitoring.v3.ListAlertPoliciesRequest") + proto.RegisterType((*ListAlertPoliciesResponse)(nil), "google.monitoring.v3.ListAlertPoliciesResponse") + proto.RegisterType((*UpdateAlertPolicyRequest)(nil), "google.monitoring.v3.UpdateAlertPolicyRequest") + proto.RegisterType((*DeleteAlertPolicyRequest)(nil), "google.monitoring.v3.DeleteAlertPolicyRequest") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for AlertPolicyService service + +type AlertPolicyServiceClient interface { + // Lists the existing alerting policies for the project. + ListAlertPolicies(ctx context.Context, in *ListAlertPoliciesRequest, opts ...grpc.CallOption) (*ListAlertPoliciesResponse, error) + // Gets a single alerting policy. + GetAlertPolicy(ctx context.Context, in *GetAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) + // Creates a new alerting policy. + CreateAlertPolicy(ctx context.Context, in *CreateAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) + // Deletes an alerting policy. + DeleteAlertPolicy(ctx context.Context, in *DeleteAlertPolicyRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) + // Updates an alerting policy. You can either replace the entire policy with + // a new one or replace only certain fields in the current alerting policy by + // specifying the fields to be updated via `updateMask`. Returns the + // updated alerting policy. + UpdateAlertPolicy(ctx context.Context, in *UpdateAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) +} + +type alertPolicyServiceClient struct { + cc *grpc.ClientConn +} + +func NewAlertPolicyServiceClient(cc *grpc.ClientConn) AlertPolicyServiceClient { + return &alertPolicyServiceClient{cc} +} + +func (c *alertPolicyServiceClient) ListAlertPolicies(ctx context.Context, in *ListAlertPoliciesRequest, opts ...grpc.CallOption) (*ListAlertPoliciesResponse, error) { + out := new(ListAlertPoliciesResponse) + err := grpc.Invoke(ctx, "/google.monitoring.v3.AlertPolicyService/ListAlertPolicies", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *alertPolicyServiceClient) GetAlertPolicy(ctx context.Context, in *GetAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) { + out := new(AlertPolicy) + err := grpc.Invoke(ctx, "/google.monitoring.v3.AlertPolicyService/GetAlertPolicy", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *alertPolicyServiceClient) CreateAlertPolicy(ctx context.Context, in *CreateAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) { + out := new(AlertPolicy) + err := grpc.Invoke(ctx, "/google.monitoring.v3.AlertPolicyService/CreateAlertPolicy", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *alertPolicyServiceClient) DeleteAlertPolicy(ctx context.Context, in *DeleteAlertPolicyRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) + err := grpc.Invoke(ctx, "/google.monitoring.v3.AlertPolicyService/DeleteAlertPolicy", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *alertPolicyServiceClient) UpdateAlertPolicy(ctx context.Context, in *UpdateAlertPolicyRequest, opts ...grpc.CallOption) (*AlertPolicy, error) { + out := new(AlertPolicy) + err := grpc.Invoke(ctx, "/google.monitoring.v3.AlertPolicyService/UpdateAlertPolicy", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for AlertPolicyService service + +type AlertPolicyServiceServer interface { + // Lists the existing alerting policies for the project. + ListAlertPolicies(context.Context, *ListAlertPoliciesRequest) (*ListAlertPoliciesResponse, error) + // Gets a single alerting policy. + GetAlertPolicy(context.Context, *GetAlertPolicyRequest) (*AlertPolicy, error) + // Creates a new alerting policy. + CreateAlertPolicy(context.Context, *CreateAlertPolicyRequest) (*AlertPolicy, error) + // Deletes an alerting policy. + DeleteAlertPolicy(context.Context, *DeleteAlertPolicyRequest) (*google_protobuf5.Empty, error) + // Updates an alerting policy. You can either replace the entire policy with + // a new one or replace only certain fields in the current alerting policy by + // specifying the fields to be updated via `updateMask`. Returns the + // updated alerting policy. + UpdateAlertPolicy(context.Context, *UpdateAlertPolicyRequest) (*AlertPolicy, error) +} + +func RegisterAlertPolicyServiceServer(s *grpc.Server, srv AlertPolicyServiceServer) { + s.RegisterService(&_AlertPolicyService_serviceDesc, srv) +} + +func _AlertPolicyService_ListAlertPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListAlertPoliciesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AlertPolicyServiceServer).ListAlertPolicies(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.AlertPolicyService/ListAlertPolicies", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AlertPolicyServiceServer).ListAlertPolicies(ctx, req.(*ListAlertPoliciesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AlertPolicyService_GetAlertPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAlertPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AlertPolicyServiceServer).GetAlertPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.AlertPolicyService/GetAlertPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AlertPolicyServiceServer).GetAlertPolicy(ctx, req.(*GetAlertPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AlertPolicyService_CreateAlertPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateAlertPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AlertPolicyServiceServer).CreateAlertPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.AlertPolicyService/CreateAlertPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AlertPolicyServiceServer).CreateAlertPolicy(ctx, req.(*CreateAlertPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AlertPolicyService_DeleteAlertPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteAlertPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AlertPolicyServiceServer).DeleteAlertPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.AlertPolicyService/DeleteAlertPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AlertPolicyServiceServer).DeleteAlertPolicy(ctx, req.(*DeleteAlertPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AlertPolicyService_UpdateAlertPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateAlertPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AlertPolicyServiceServer).UpdateAlertPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.AlertPolicyService/UpdateAlertPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AlertPolicyServiceServer).UpdateAlertPolicy(ctx, req.(*UpdateAlertPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _AlertPolicyService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.monitoring.v3.AlertPolicyService", + HandlerType: (*AlertPolicyServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListAlertPolicies", + Handler: _AlertPolicyService_ListAlertPolicies_Handler, + }, + { + MethodName: "GetAlertPolicy", + Handler: _AlertPolicyService_GetAlertPolicy_Handler, + }, + { + MethodName: "CreateAlertPolicy", + Handler: _AlertPolicyService_CreateAlertPolicy_Handler, + }, + { + MethodName: "DeleteAlertPolicy", + Handler: _AlertPolicyService_DeleteAlertPolicy_Handler, + }, + { + MethodName: "UpdateAlertPolicy", + Handler: _AlertPolicyService_UpdateAlertPolicy_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/monitoring/v3/alert_service.proto", +} + +func init() { proto.RegisterFile("google/monitoring/v3/alert_service.proto", fileDescriptor1) } + +var fileDescriptor1 = []byte{ + // 656 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x41, 0x6f, 0xd3, 0x4c, + 0x10, 0x95, 0x93, 0x36, 0x5f, 0xbb, 0xfd, 0x5a, 0x94, 0x15, 0x54, 0xae, 0x0b, 0x52, 0x30, 0x2a, + 0x54, 0xad, 0xb0, 0xa5, 0xf8, 0x04, 0x15, 0x48, 0xa4, 0x85, 0xf6, 0x40, 0xa5, 0x28, 0x85, 0x1e, + 0x50, 0xa4, 0x68, 0x93, 0x4c, 0xac, 0x25, 0x8e, 0xd7, 0x78, 0x37, 0x11, 0x29, 0xea, 0x85, 0x23, + 0x12, 0xe2, 0xc0, 0x99, 0x03, 0x47, 0x38, 0x20, 0x7e, 0x07, 0x57, 0xfe, 0x02, 0x3f, 0x04, 0x79, + 0xed, 0x34, 0x76, 0x6d, 0xab, 0x16, 0xb7, 0xcc, 0xce, 0xdb, 0x99, 0xb7, 0x6f, 0xde, 0x38, 0x68, + 0xdb, 0x66, 0xcc, 0x76, 0xc0, 0x1c, 0x31, 0x97, 0x0a, 0xe6, 0x53, 0xd7, 0x36, 0x27, 0x96, 0x49, + 0x1c, 0xf0, 0x45, 0x87, 0x83, 0x3f, 0xa1, 0x3d, 0x30, 0x3c, 0x9f, 0x09, 0x86, 0xaf, 0x87, 0x48, + 0x63, 0x8e, 0x34, 0x26, 0x96, 0x76, 0x33, 0xba, 0x4f, 0x3c, 0x6a, 0x12, 0xd7, 0x65, 0x82, 0x08, + 0xca, 0x5c, 0x1e, 0xde, 0xd1, 0x6a, 0xf9, 0xd5, 0x23, 0xc4, 0x66, 0x84, 0x90, 0x51, 0x77, 0x3c, + 0x30, 0x61, 0xe4, 0x89, 0xe9, 0xa5, 0xeb, 0x17, 0xc9, 0x01, 0x05, 0xa7, 0xdf, 0x19, 0x11, 0x3e, + 0x0c, 0x11, 0xba, 0x40, 0xea, 0xbe, 0x0f, 0x44, 0xc0, 0x93, 0xa0, 0x66, 0x93, 0x39, 0xb4, 0x37, + 0x6d, 0xc1, 0x9b, 0x31, 0x70, 0x81, 0x31, 0x5a, 0x70, 0xc9, 0x08, 0xd4, 0x72, 0x4d, 0xd9, 0x5e, + 0x6e, 0xc9, 0xdf, 0xf8, 0x00, 0xfd, 0x1f, 0xbe, 0xcd, 0x93, 0x50, 0xb5, 0x54, 0x53, 0xb6, 0x57, + 0xea, 0xb7, 0x8d, 0xac, 0xb7, 0x19, 0xf1, 0x9a, 0x2b, 0x64, 0x1e, 0xe8, 0xbb, 0xe8, 0xc6, 0x21, + 0x88, 0x62, 0x2d, 0xf5, 0x2f, 0x0a, 0x52, 0x9f, 0x53, 0x1e, 0x83, 0x53, 0xe0, 0x97, 0x2f, 0x2c, + 0xc4, 0x38, 0xae, 0xa3, 0xca, 0x80, 0x3a, 0x02, 0x7c, 0x75, 0x51, 0x9e, 0x46, 0x11, 0xde, 0x40, + 0x4b, 0xcc, 0xef, 0x83, 0xdf, 0xe9, 0x4e, 0xd5, 0x8a, 0xcc, 0xfc, 0x27, 0xe3, 0xc6, 0x14, 0x6f, + 0xa2, 0x65, 0x8f, 0xd8, 0xd0, 0xe1, 0xf4, 0x0c, 0xe4, 0x9b, 0x16, 0x5b, 0x4b, 0xc1, 0xc1, 0x09, + 0x3d, 0x03, 0x7c, 0x0b, 0x21, 0x99, 0x14, 0x6c, 0x08, 0x6e, 0x44, 0x4d, 0xc2, 0x5f, 0x04, 0x07, + 0xfa, 0x47, 0x05, 0x6d, 0x64, 0xf0, 0xe3, 0x1e, 0x73, 0x39, 0xe0, 0x23, 0xb4, 0x16, 0x13, 0x8c, + 0x02, 0x57, 0xcb, 0xb5, 0x72, 0x31, 0xc9, 0x56, 0x49, 0xbc, 0x22, 0xbe, 0x8b, 0xae, 0xb9, 0xf0, + 0x56, 0x74, 0x62, 0x5c, 0x4a, 0x92, 0xcb, 0x6a, 0x70, 0xdc, 0xbc, 0xe0, 0x13, 0xe8, 0xf5, 0xd2, + 0xeb, 0x67, 0xcf, 0x74, 0x0f, 0xad, 0x8c, 0x65, 0x4e, 0x9a, 0x20, 0x1a, 0x9f, 0x36, 0xe3, 0x32, + 0xf3, 0x89, 0xf1, 0x2c, 0xf0, 0xc9, 0x31, 0xe1, 0xc3, 0x16, 0x0a, 0xe1, 0xc1, 0xef, 0xd4, 0xf0, + 0xcb, 0xff, 0x34, 0x7c, 0x03, 0xa9, 0x07, 0xe0, 0x40, 0x51, 0xcb, 0xd5, 0x7f, 0x54, 0x10, 0x8e, + 0x41, 0x4f, 0xc2, 0xa5, 0xc2, 0x5f, 0x15, 0x54, 0x4d, 0xc9, 0x8e, 0x8d, 0x6c, 0x32, 0x79, 0xfe, + 0xd1, 0xcc, 0xc2, 0xf8, 0x70, 0x9e, 0xfa, 0xee, 0xfb, 0xdf, 0x7f, 0x3e, 0x97, 0xb6, 0xf0, 0x9d, + 0x60, 0x11, 0xdf, 0x05, 0x04, 0x1f, 0x79, 0x3e, 0x7b, 0x0d, 0x3d, 0xc1, 0xcd, 0x9d, 0x73, 0x33, + 0x39, 0xb2, 0x4f, 0x0a, 0x5a, 0x4b, 0x1a, 0x1d, 0xef, 0x66, 0x37, 0xcc, 0x5c, 0x07, 0xed, 0x6a, + 0x69, 0xf5, 0xfb, 0x92, 0xcf, 0x3d, 0xbc, 0x95, 0xc5, 0x27, 0x49, 0xc7, 0xdc, 0x39, 0x97, 0xaa, + 0xa5, 0x16, 0x3e, 0x4f, 0xb5, 0xbc, 0x2f, 0x43, 0x11, 0x5e, 0x0f, 0x24, 0x2f, 0x4b, 0x2f, 0xa2, + 0xd3, 0xc3, 0x84, 0xad, 0xf0, 0x07, 0x05, 0x55, 0x53, 0x0e, 0xc9, 0xe3, 0x98, 0x67, 0x25, 0x6d, + 0x3d, 0x65, 0xea, 0xa7, 0xc1, 0x97, 0x71, 0x26, 0xd8, 0x4e, 0x41, 0xc1, 0x7e, 0x2a, 0xa8, 0x9a, + 0xda, 0xa6, 0x3c, 0x32, 0x79, 0x6b, 0x57, 0x44, 0xb0, 0x23, 0xc9, 0xab, 0x51, 0xaf, 0x4b, 0x5e, + 0x71, 0x41, 0x8c, 0xab, 0x48, 0x26, 0xf5, 0x6b, 0x7c, 0x53, 0x90, 0xda, 0x63, 0xa3, 0xcc, 0x96, + 0x8d, 0xaa, 0xec, 0x19, 0x2d, 0x51, 0x33, 0x90, 0xa6, 0xa9, 0xbc, 0x7a, 0x1c, 0x41, 0x6d, 0xe6, + 0x10, 0xd7, 0x36, 0x98, 0x6f, 0x9b, 0x36, 0xb8, 0x52, 0x38, 0x33, 0x4c, 0x11, 0x8f, 0xf2, 0xe4, + 0xbf, 0xd0, 0xde, 0x3c, 0xfa, 0x5e, 0xd2, 0x0e, 0xc3, 0x02, 0xfb, 0x0e, 0x1b, 0xf7, 0x8d, 0xe3, + 0x79, 0xc7, 0x53, 0xeb, 0xd7, 0x2c, 0xd9, 0x96, 0xc9, 0xf6, 0x3c, 0xd9, 0x3e, 0xb5, 0xba, 0x15, + 0xd9, 0xc4, 0xfa, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x1f, 0xe6, 0xf0, 0x47, 0x07, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/common.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/common.pb.go index 4d967f529a..6023996717 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/common.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/common.pb.go @@ -1,61 +1,12 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/monitoring/v3/common.proto -/* -Package monitoring is a generated protocol buffer package. - -It is generated from these files: - google/monitoring/v3/common.proto - google/monitoring/v3/group.proto - google/monitoring/v3/group_service.proto - google/monitoring/v3/metric.proto - google/monitoring/v3/metric_service.proto - google/monitoring/v3/uptime.proto - google/monitoring/v3/uptime_service.proto - -It has these top-level messages: - TypedValue - TimeInterval - Aggregation - Group - ListGroupsRequest - ListGroupsResponse - GetGroupRequest - CreateGroupRequest - UpdateGroupRequest - DeleteGroupRequest - ListGroupMembersRequest - ListGroupMembersResponse - Point - TimeSeries - ListMonitoredResourceDescriptorsRequest - ListMonitoredResourceDescriptorsResponse - GetMonitoredResourceDescriptorRequest - ListMetricDescriptorsRequest - ListMetricDescriptorsResponse - GetMetricDescriptorRequest - CreateMetricDescriptorRequest - DeleteMetricDescriptorRequest - ListTimeSeriesRequest - ListTimeSeriesResponse - CreateTimeSeriesRequest - CreateTimeSeriesError - UptimeCheckConfig - UptimeCheckIp - ListUptimeCheckConfigsRequest - ListUptimeCheckConfigsResponse - GetUptimeCheckConfigRequest - CreateUptimeCheckConfigRequest - UpdateUptimeCheckConfigRequest - DeleteUptimeCheckConfigRequest - ListUptimeCheckIpsRequest - ListUptimeCheckIpsResponse -*/ package monitoring import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" import google_api2 "google.golang.org/genproto/googleapis/api/distribution" import google_protobuf3 "github.com/golang/protobuf/ptypes/duration" import google_protobuf2 "github.com/golang/protobuf/ptypes/timestamp" @@ -65,11 +16,87 @@ var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +// Specifies an ordering relationship on two arguments, here called left and +// right. +type ComparisonType int32 + +const ( + // No ordering relationship is specified. + ComparisonType_COMPARISON_UNSPECIFIED ComparisonType = 0 + // The left argument is greater than the right argument. + ComparisonType_COMPARISON_GT ComparisonType = 1 + // The left argument is greater than or equal to the right argument. + ComparisonType_COMPARISON_GE ComparisonType = 2 + // The left argument is less than the right argument. + ComparisonType_COMPARISON_LT ComparisonType = 3 + // The left argument is less than or equal to the right argument. + ComparisonType_COMPARISON_LE ComparisonType = 4 + // The left argument is equal to the right argument. + ComparisonType_COMPARISON_EQ ComparisonType = 5 + // The left argument is not equal to the right argument. + ComparisonType_COMPARISON_NE ComparisonType = 6 +) + +var ComparisonType_name = map[int32]string{ + 0: "COMPARISON_UNSPECIFIED", + 1: "COMPARISON_GT", + 2: "COMPARISON_GE", + 3: "COMPARISON_LT", + 4: "COMPARISON_LE", + 5: "COMPARISON_EQ", + 6: "COMPARISON_NE", +} +var ComparisonType_value = map[string]int32{ + "COMPARISON_UNSPECIFIED": 0, + "COMPARISON_GT": 1, + "COMPARISON_GE": 2, + "COMPARISON_LT": 3, + "COMPARISON_LE": 4, + "COMPARISON_EQ": 5, + "COMPARISON_NE": 6, +} + +func (x ComparisonType) String() string { + return proto.EnumName(ComparisonType_name, int32(x)) +} +func (ComparisonType) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } + +// The tier of service for a Stackdriver account. Please see the +// [service tiers documentation](https://cloud.google.com/monitoring/accounts/tiers) +// for more details. +type ServiceTier int32 + +const ( + // An invalid sentinel value, used to indicate that a tier has not + // been provided explicitly. + ServiceTier_SERVICE_TIER_UNSPECIFIED ServiceTier = 0 + // The Stackdriver Basic tier, a free tier of service that provides basic + // features, a moderate allotment of logs, and access to built-in metrics. + // A number of features are not available in this tier. For more details, + // see [the service tiers documentation](https://cloud.google.com/monitoring/accounts/tiers). + ServiceTier_SERVICE_TIER_BASIC ServiceTier = 1 + // The Stackdriver Premium tier, a higher, more expensive tier of service + // that provides access to all Stackdriver features, lets you use Stackdriver + // with AWS accounts, and has a larger allotments for logs and metrics. For + // more details, see [the service tiers documentation](https://cloud.google.com/monitoring/accounts/tiers). + ServiceTier_SERVICE_TIER_PREMIUM ServiceTier = 2 +) + +var ServiceTier_name = map[int32]string{ + 0: "SERVICE_TIER_UNSPECIFIED", + 1: "SERVICE_TIER_BASIC", + 2: "SERVICE_TIER_PREMIUM", +} +var ServiceTier_value = map[string]int32{ + "SERVICE_TIER_UNSPECIFIED": 0, + "SERVICE_TIER_BASIC": 1, + "SERVICE_TIER_PREMIUM": 2, +} + +func (x ServiceTier) String() string { + return proto.EnumName(ServiceTier_name, int32(x)) +} +func (ServiceTier) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } // The Aligner describes how to bring the data points in a single // time series into temporal alignment. @@ -85,11 +112,22 @@ const ( // delta metric to a delta metric requires that the alignment // period be increased. The value type of the result is the same // as the value type of the input. + // + // One can think of this aligner as a rate but without time units; that + // is, the output is conceptually (second_point - first_point). Aggregation_ALIGN_DELTA Aggregation_Aligner = 1 // Align and convert to a rate. This alignment is valid for // cumulative metrics and delta metrics with numeric values. The output is a // gauge metric with value type // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]. + // + // One can think of this aligner as conceptually providing the slope of + // the line that passes through the value at the start and end of the + // window. In other words, this is conceptually ((y1 - y0)/(t1 - t0)), + // and the output unit is one that has a "/time" dimension. + // + // If, by rate, you are looking for percentage change, see the + // `ALIGN_PERCENT_CHANGE` aligner option. Aggregation_ALIGN_RATE Aggregation_Aligner = 2 // Align by interpolating between adjacent points around the // period boundary. This alignment is valid for gauge @@ -144,6 +182,12 @@ const ( // [INT64][google.api.MetricDescriptor.ValueType.INT64]. Aggregation_ALIGN_COUNT_TRUE Aggregation_Aligner = 16 // Align time series via aggregation. The resulting data point in + // the alignment period is the count of False-valued data points in the + // period. This alignment is valid for gauge metrics with + // Boolean values. The value type of the output is + // [INT64][google.api.MetricDescriptor.ValueType.INT64]. + Aggregation_ALIGN_COUNT_FALSE Aggregation_Aligner = 24 + // Align time series via aggregation. The resulting data point in // the alignment period is the fraction of True-valued data points in the // period. This alignment is valid for gauge metrics with Boolean values. // The output value is in the range [0, 1] and has value type @@ -173,6 +217,22 @@ const ( // with distribution values. The output is a gauge metric with value type // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]. Aggregation_ALIGN_PERCENTILE_05 Aggregation_Aligner = 21 + // Align and convert to a percentage change. This alignment is valid for + // gauge and delta metrics with numeric values. This alignment conceptually + // computes the equivalent of "((current - previous)/previous)*100" + // where previous value is determined based on the alignmentPeriod. + // In the event that previous is 0 the calculated value is infinity with the + // exception that if both (current - previous) and previous are 0 the + // calculated value is 0. + // A 10 minute moving mean is computed at each point of the time window + // prior to the above calculation to smooth the metric and prevent false + // positives from very short lived spikes. + // Only applicable for data that is >= 0. Any values < 0 are treated as + // no data. While delta metrics are accepted by this alignment special care + // should be taken that the values for the metric will always be positive. + // The output is a gauge metric with value type + // [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]. + Aggregation_ALIGN_PERCENT_CHANGE Aggregation_Aligner = 23 ) var Aggregation_Aligner_name = map[int32]string{ @@ -188,36 +248,40 @@ var Aggregation_Aligner_name = map[int32]string{ 14: "ALIGN_SUM", 15: "ALIGN_STDDEV", 16: "ALIGN_COUNT_TRUE", + 24: "ALIGN_COUNT_FALSE", 17: "ALIGN_FRACTION_TRUE", 18: "ALIGN_PERCENTILE_99", 19: "ALIGN_PERCENTILE_95", 20: "ALIGN_PERCENTILE_50", 21: "ALIGN_PERCENTILE_05", + 23: "ALIGN_PERCENT_CHANGE", } var Aggregation_Aligner_value = map[string]int32{ - "ALIGN_NONE": 0, - "ALIGN_DELTA": 1, - "ALIGN_RATE": 2, - "ALIGN_INTERPOLATE": 3, - "ALIGN_NEXT_OLDER": 4, - "ALIGN_MIN": 10, - "ALIGN_MAX": 11, - "ALIGN_MEAN": 12, - "ALIGN_COUNT": 13, - "ALIGN_SUM": 14, - "ALIGN_STDDEV": 15, - "ALIGN_COUNT_TRUE": 16, - "ALIGN_FRACTION_TRUE": 17, - "ALIGN_PERCENTILE_99": 18, - "ALIGN_PERCENTILE_95": 19, - "ALIGN_PERCENTILE_50": 20, - "ALIGN_PERCENTILE_05": 21, + "ALIGN_NONE": 0, + "ALIGN_DELTA": 1, + "ALIGN_RATE": 2, + "ALIGN_INTERPOLATE": 3, + "ALIGN_NEXT_OLDER": 4, + "ALIGN_MIN": 10, + "ALIGN_MAX": 11, + "ALIGN_MEAN": 12, + "ALIGN_COUNT": 13, + "ALIGN_SUM": 14, + "ALIGN_STDDEV": 15, + "ALIGN_COUNT_TRUE": 16, + "ALIGN_COUNT_FALSE": 24, + "ALIGN_FRACTION_TRUE": 17, + "ALIGN_PERCENTILE_99": 18, + "ALIGN_PERCENTILE_95": 19, + "ALIGN_PERCENTILE_50": 20, + "ALIGN_PERCENTILE_05": 21, + "ALIGN_PERCENT_CHANGE": 23, } func (x Aggregation_Aligner) String() string { return proto.EnumName(Aggregation_Aligner_name, int32(x)) } -func (Aggregation_Aligner) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } +func (Aggregation_Aligner) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{2, 0} } // A Reducer describes how to aggregate data points from multiple // time series into a single time series. @@ -263,6 +327,11 @@ const ( // and gauge metrics of Boolean value type. The value type of // the output is [INT64][google.api.MetricDescriptor.ValueType.INT64]. Aggregation_REDUCE_COUNT_TRUE Aggregation_Reducer = 7 + // Reduce by computing the count of False-valued data points across time + // series for each alignment period. This reducer is valid for delta + // and gauge metrics of Boolean value type. The value type of + // the output is [INT64][google.api.MetricDescriptor.ValueType.INT64]. + Aggregation_REDUCE_COUNT_FALSE Aggregation_Reducer = 15 // Reduce by computing the fraction of True-valued data points across time // series for each alignment period. This reducer is valid for delta // and gauge metrics of Boolean value type. The output value is in the @@ -300,6 +369,7 @@ var Aggregation_Reducer_name = map[int32]string{ 5: "REDUCE_STDDEV", 6: "REDUCE_COUNT", 7: "REDUCE_COUNT_TRUE", + 15: "REDUCE_COUNT_FALSE", 8: "REDUCE_FRACTION_TRUE", 9: "REDUCE_PERCENTILE_99", 10: "REDUCE_PERCENTILE_95", @@ -315,6 +385,7 @@ var Aggregation_Reducer_value = map[string]int32{ "REDUCE_STDDEV": 5, "REDUCE_COUNT": 6, "REDUCE_COUNT_TRUE": 7, + "REDUCE_COUNT_FALSE": 15, "REDUCE_FRACTION_TRUE": 8, "REDUCE_PERCENTILE_99": 9, "REDUCE_PERCENTILE_95": 10, @@ -325,7 +396,7 @@ var Aggregation_Reducer_value = map[string]int32{ func (x Aggregation_Reducer) String() string { return proto.EnumName(Aggregation_Reducer_name, int32(x)) } -func (Aggregation_Reducer) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 1} } +func (Aggregation_Reducer) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{2, 1} } // A single strongly-typed value. type TypedValue struct { @@ -343,7 +414,7 @@ type TypedValue struct { func (m *TypedValue) Reset() { *m = TypedValue{} } func (m *TypedValue) String() string { return proto.CompactTextString(m) } func (*TypedValue) ProtoMessage() {} -func (*TypedValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (*TypedValue) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } type isTypedValue_Value interface { isTypedValue_Value() @@ -544,7 +615,7 @@ type TimeInterval struct { func (m *TimeInterval) Reset() { *m = TimeInterval{} } func (m *TimeInterval) String() string { return proto.CompactTextString(m) } func (*TimeInterval) ProtoMessage() {} -func (*TimeInterval) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (*TimeInterval) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } func (m *TimeInterval) GetEndTime() *google_protobuf2.Timestamp { if m != nil { @@ -562,8 +633,9 @@ func (m *TimeInterval) GetStartTime() *google_protobuf2.Timestamp { // Describes how to combine multiple time series to provide different views of // the data. Aggregation consists of an alignment step on individual time -// series (`per_series_aligner`) followed by an optional reduction of the data -// across different time series (`cross_series_reducer`). For more details, see +// series (`alignment_period` and `per_series_aligner`) followed by an optional +// reduction step of the data across the aligned time series +// (`cross_series_reducer` and `group_by_fields`). For more details, see // [Aggregation](/monitoring/api/learn_more#aggregation). type Aggregation struct { // The alignment period for per-[time series][google.monitoring.v3.TimeSeries] @@ -619,7 +691,7 @@ type Aggregation struct { func (m *Aggregation) Reset() { *m = Aggregation{} } func (m *Aggregation) String() string { return proto.CompactTextString(m) } func (*Aggregation) ProtoMessage() {} -func (*Aggregation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (*Aggregation) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} } func (m *Aggregation) GetAlignmentPeriod() *google_protobuf3.Duration { if m != nil { @@ -653,62 +725,74 @@ func init() { proto.RegisterType((*TypedValue)(nil), "google.monitoring.v3.TypedValue") proto.RegisterType((*TimeInterval)(nil), "google.monitoring.v3.TimeInterval") proto.RegisterType((*Aggregation)(nil), "google.monitoring.v3.Aggregation") + proto.RegisterEnum("google.monitoring.v3.ComparisonType", ComparisonType_name, ComparisonType_value) + proto.RegisterEnum("google.monitoring.v3.ServiceTier", ServiceTier_name, ServiceTier_value) proto.RegisterEnum("google.monitoring.v3.Aggregation_Aligner", Aggregation_Aligner_name, Aggregation_Aligner_value) proto.RegisterEnum("google.monitoring.v3.Aggregation_Reducer", Aggregation_Reducer_name, Aggregation_Reducer_value) } -func init() { proto.RegisterFile("google/monitoring/v3/common.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 792 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xdd, 0x6a, 0xe3, 0x46, - 0x14, 0xb6, 0xec, 0x64, 0x1d, 0x1f, 0x39, 0xf1, 0x64, 0xd6, 0x4b, 0xdd, 0x40, 0xbb, 0x5e, 0x17, - 0x8a, 0x7b, 0x23, 0x87, 0xb8, 0x2e, 0x84, 0x42, 0x41, 0xb1, 0xb5, 0x1b, 0x83, 0x23, 0x9b, 0x59, - 0x25, 0x0d, 0x6d, 0x40, 0xc8, 0xd1, 0xac, 0x10, 0xc8, 0x1a, 0x31, 0x92, 0x0d, 0xb9, 0xeb, 0x6b, - 0xf4, 0xba, 0x77, 0xfb, 0x28, 0x7d, 0x84, 0x3e, 0x44, 0x9f, 0xa1, 0x68, 0x66, 0xb4, 0x52, 0x5a, - 0x97, 0xf6, 0xf2, 0xfb, 0x39, 0xdf, 0xe8, 0x7c, 0x23, 0xd9, 0xf0, 0x26, 0x60, 0x2c, 0x88, 0xe8, - 0x68, 0xc3, 0xe2, 0x30, 0x63, 0x3c, 0x8c, 0x83, 0xd1, 0x6e, 0x3c, 0x7a, 0x64, 0x9b, 0x0d, 0x8b, - 0x8d, 0x84, 0xb3, 0x8c, 0xe1, 0xae, 0xb4, 0x18, 0xa5, 0xc5, 0xd8, 0x8d, 0xcf, 0xbe, 0x50, 0x83, - 0x5e, 0x12, 0x8e, 0xfc, 0x30, 0xcd, 0x78, 0xb8, 0xde, 0x66, 0x61, 0x31, 0x74, 0xf6, 0xa5, 0x92, - 0x05, 0x5a, 0x6f, 0x3f, 0x8c, 0xfc, 0x2d, 0xf7, 0x2a, 0xfa, 0xeb, 0xbf, 0xeb, 0x59, 0xb8, 0xa1, - 0x69, 0xe6, 0x6d, 0x12, 0x69, 0x18, 0xfc, 0xa9, 0x01, 0x38, 0x4f, 0x09, 0xf5, 0xef, 0xbc, 0x68, - 0x4b, 0xf1, 0x6b, 0x80, 0x35, 0x63, 0x91, 0xbb, 0xcb, 0x51, 0x4f, 0xeb, 0x6b, 0xc3, 0xa3, 0xeb, - 0x1a, 0x69, 0xe5, 0x9c, 0x34, 0xbc, 0x01, 0x3d, 0x8c, 0xb3, 0xef, 0xbe, 0x55, 0x8e, 0x7a, 0x5f, - 0x1b, 0x36, 0xae, 0x6b, 0x04, 0x04, 0x29, 0x2d, 0x5f, 0x41, 0xdb, 0x67, 0xdb, 0x75, 0x44, 0x95, - 0xa7, 0xd1, 0xd7, 0x86, 0xda, 0x75, 0x8d, 0xe8, 0x92, 0xfd, 0x64, 0xca, 0x97, 0x89, 0x03, 0x65, - 0x3a, 0xe8, 0x6b, 0xc3, 0x56, 0x6e, 0x92, 0xac, 0x34, 0xcd, 0x01, 0x57, 0x77, 0x56, 0xd6, 0xc3, - 0xbe, 0x36, 0xd4, 0x2f, 0x7a, 0x86, 0xea, 0xcb, 0x4b, 0x42, 0x63, 0x56, 0x71, 0x5d, 0xd7, 0xc8, - 0x69, 0x75, 0x4a, 0x44, 0x5d, 0x35, 0xe1, 0x50, 0x4c, 0x0f, 0x7e, 0xd1, 0xa0, 0xed, 0x84, 0x1b, - 0x3a, 0x8f, 0x33, 0xca, 0x77, 0x5e, 0x84, 0x27, 0x70, 0x44, 0x63, 0xdf, 0xcd, 0x8b, 0x11, 0xeb, - 0xe8, 0x17, 0x67, 0x45, 0x74, 0xd1, 0x9a, 0xe1, 0x14, 0xad, 0x91, 0x26, 0x8d, 0xfd, 0x1c, 0xe1, - 0x4b, 0x80, 0x34, 0xf3, 0x78, 0x26, 0x07, 0xb5, 0xff, 0x1c, 0x6c, 0x09, 0x77, 0x8e, 0x07, 0x1f, - 0x9b, 0xa0, 0x9b, 0x41, 0xc0, 0x69, 0x20, 0xae, 0x0a, 0xcf, 0x00, 0x79, 0x51, 0x18, 0xc4, 0x1b, - 0x1a, 0x67, 0x6e, 0x42, 0x79, 0xc8, 0x7c, 0x15, 0xf8, 0xf9, 0x3f, 0x02, 0x67, 0xea, 0x7e, 0x49, - 0xe7, 0xd3, 0xc8, 0x4a, 0x4c, 0xe0, 0x1f, 0x01, 0x27, 0x94, 0xbb, 0x29, 0xe5, 0x21, 0x4d, 0x5d, - 0xa1, 0x52, 0x2e, 0x36, 0x3a, 0xb9, 0xf8, 0xc6, 0xd8, 0xf7, 0x72, 0x19, 0x95, 0x87, 0x30, 0x4c, - 0x39, 0x40, 0x50, 0x42, 0xf9, 0x7b, 0x91, 0xa1, 0x18, 0xfc, 0x33, 0x74, 0x1f, 0x39, 0x4b, 0xd3, - 0x22, 0x9a, 0x53, 0x7f, 0xfb, 0x48, 0xb9, 0xb8, 0xb2, 0xff, 0x15, 0x4d, 0xe4, 0x00, 0xc1, 0x22, - 0x46, 0x86, 0x2b, 0x0e, 0x7f, 0x0d, 0x9d, 0x80, 0xb3, 0x6d, 0xe2, 0xae, 0x9f, 0xdc, 0x0f, 0x21, - 0x8d, 0xfc, 0xb4, 0x77, 0xd8, 0x6f, 0x0c, 0x5b, 0xe4, 0x58, 0xd0, 0x57, 0x4f, 0x6f, 0x05, 0x39, - 0xf8, 0xa3, 0x0e, 0xcd, 0xe2, 0x81, 0x4e, 0x00, 0xcc, 0xc5, 0xfc, 0x9d, 0xed, 0xda, 0x4b, 0xdb, - 0x42, 0x35, 0xdc, 0x01, 0x5d, 0xe2, 0x99, 0xb5, 0x70, 0x4c, 0xa4, 0x95, 0x06, 0x62, 0x3a, 0x16, - 0xaa, 0xe3, 0x57, 0x70, 0x2a, 0xf1, 0xdc, 0x76, 0x2c, 0xb2, 0x5a, 0x2e, 0x72, 0xba, 0x81, 0xbb, - 0x80, 0x54, 0x8e, 0x75, 0xef, 0xb8, 0xcb, 0xc5, 0xcc, 0x22, 0xe8, 0x00, 0x1f, 0x43, 0x4b, 0xb2, - 0x37, 0x73, 0x1b, 0x41, 0x05, 0x9a, 0xf7, 0x48, 0x2f, 0xa3, 0x6f, 0x2c, 0xd3, 0x46, 0xed, 0xf2, - 0xec, 0xe9, 0xf2, 0xd6, 0x76, 0xd0, 0x71, 0xe9, 0x7f, 0x7f, 0x7b, 0x83, 0x4e, 0x30, 0x82, 0xb6, - 0x82, 0xce, 0x6c, 0x66, 0xdd, 0xa1, 0x4e, 0x79, 0xaa, 0x98, 0x70, 0x1d, 0x72, 0x6b, 0x21, 0x84, - 0x3f, 0x83, 0x97, 0x92, 0x7d, 0x4b, 0xcc, 0xa9, 0x33, 0x5f, 0xda, 0x52, 0x38, 0x2d, 0x85, 0x95, - 0x45, 0xa6, 0x96, 0xed, 0xcc, 0x17, 0x96, 0x7b, 0x79, 0x89, 0xf0, 0x7e, 0x61, 0x82, 0x5e, 0xee, - 0x15, 0x26, 0xe7, 0xa8, 0xbb, 0x57, 0x38, 0x9f, 0xa0, 0x57, 0x83, 0x5f, 0xeb, 0xd0, 0x2c, 0x2e, - 0xa4, 0x03, 0x3a, 0xb1, 0x66, 0xb7, 0x53, 0xab, 0xd2, 0xae, 0x22, 0xc4, 0xca, 0xa2, 0xdd, 0x82, - 0x98, 0xdb, 0xa8, 0x5e, 0xc5, 0xe6, 0x3d, 0x6a, 0x54, 0x70, 0x5e, 0xc1, 0x01, 0x3e, 0x85, 0xe3, - 0x02, 0xcb, 0x0e, 0x0e, 0xf3, 0x56, 0x14, 0x25, 0x6b, 0x7b, 0x91, 0x5f, 0x51, 0x95, 0x91, 0xdb, - 0x37, 0x71, 0x0f, 0xba, 0x8a, 0x7e, 0xde, 0xcb, 0x51, 0x45, 0x79, 0x5e, 0x4c, 0xeb, 0x5f, 0x94, - 0x09, 0x82, 0xfd, 0xca, 0xe4, 0x1c, 0xe9, 0xfb, 0x95, 0xf3, 0x09, 0x6a, 0x5f, 0xfd, 0xa6, 0x41, - 0xef, 0x91, 0x6d, 0xf6, 0xbe, 0xe5, 0x57, 0xfa, 0x54, 0xfc, 0x82, 0xaf, 0xf2, 0xaf, 0x73, 0xa5, - 0xfd, 0xf4, 0x83, 0x32, 0x05, 0x2c, 0xf2, 0xe2, 0xc0, 0x60, 0x3c, 0x18, 0x05, 0x34, 0x16, 0xdf, - 0xee, 0x48, 0x4a, 0x5e, 0x12, 0xa6, 0xcf, 0xff, 0x04, 0xbe, 0x2f, 0xd1, 0xc7, 0xfa, 0xd9, 0x3b, - 0x19, 0x30, 0x8d, 0xd8, 0xd6, 0x37, 0x6e, 0xca, 0xb3, 0xee, 0xc6, 0xbf, 0x17, 0xe2, 0x83, 0x10, - 0x1f, 0x4a, 0xf1, 0xe1, 0x6e, 0xbc, 0x7e, 0x21, 0x0e, 0x19, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, - 0x57, 0xa4, 0xb9, 0xce, 0x68, 0x06, 0x00, 0x00, +func init() { proto.RegisterFile("google/monitoring/v3/common.proto", fileDescriptor2) } + +var fileDescriptor2 = []byte{ + // 954 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0xc1, 0x6e, 0xe3, 0x44, + 0x18, 0xc7, 0xe3, 0xa4, 0x6d, 0x9a, 0xcf, 0x6d, 0x33, 0x9d, 0xed, 0x76, 0x43, 0xb5, 0xb0, 0xd9, + 0x22, 0xa1, 0xb0, 0x07, 0xa7, 0x6a, 0x09, 0x52, 0x85, 0x84, 0xe4, 0x3a, 0xd3, 0xd6, 0x52, 0xe2, + 0x84, 0x89, 0x53, 0x2a, 0x28, 0xb2, 0x9c, 0x66, 0xd6, 0xb2, 0x94, 0x78, 0x2c, 0xdb, 0xa9, 0xd4, + 0x1b, 0x77, 0xde, 0x81, 0x0b, 0x37, 0x6e, 0xbc, 0x06, 0x0f, 0xc3, 0x85, 0x17, 0x40, 0x9e, 0x71, + 0xd6, 0x4e, 0x08, 0x62, 0x8f, 0xdf, 0xef, 0xff, 0xff, 0xbe, 0x99, 0xf9, 0x8f, 0x35, 0x86, 0xb7, + 0x1e, 0xe7, 0xde, 0x8c, 0xb5, 0xe7, 0x3c, 0xf0, 0x13, 0x1e, 0xf9, 0x81, 0xd7, 0x7e, 0xba, 0x68, + 0x3f, 0xf2, 0xf9, 0x9c, 0x07, 0x5a, 0x18, 0xf1, 0x84, 0xe3, 0x23, 0x69, 0xd1, 0x72, 0x8b, 0xf6, + 0x74, 0x71, 0xf2, 0x3a, 0x6b, 0x74, 0x43, 0xbf, 0xed, 0x06, 0x01, 0x4f, 0xdc, 0xc4, 0xe7, 0x41, + 0x2c, 0x7b, 0x4e, 0x3e, 0x2d, 0xa8, 0x53, 0x3f, 0x4e, 0x22, 0x7f, 0xb2, 0x48, 0xf5, 0x4c, 0xfe, + 0x2c, 0x93, 0x45, 0x35, 0x59, 0xbc, 0x6f, 0x4f, 0x17, 0x91, 0x5b, 0xd0, 0xdf, 0xac, 0xeb, 0x89, + 0x3f, 0x67, 0x71, 0xe2, 0xce, 0x43, 0x69, 0x38, 0xfd, 0x4b, 0x01, 0xb0, 0x9f, 0x43, 0x36, 0xbd, + 0x73, 0x67, 0x0b, 0x86, 0xdf, 0x00, 0x4c, 0x38, 0x9f, 0x39, 0x4f, 0x69, 0xd5, 0x50, 0x9a, 0x4a, + 0x6b, 0xf7, 0xb6, 0x44, 0x6b, 0x29, 0x93, 0x86, 0xb7, 0xa0, 0xfa, 0x41, 0xf2, 0xf5, 0x57, 0x99, + 0xa3, 0xdc, 0x54, 0x5a, 0x95, 0xdb, 0x12, 0x05, 0x01, 0xa5, 0xe5, 0x73, 0xd8, 0x9b, 0xf2, 0xc5, + 0x64, 0xc6, 0x32, 0x4f, 0xa5, 0xa9, 0xb4, 0x94, 0xdb, 0x12, 0x55, 0x25, 0xfd, 0x60, 0x4a, 0x0f, + 0x13, 0x78, 0x99, 0x69, 0xab, 0xa9, 0xb4, 0x6a, 0xa9, 0x49, 0x52, 0x69, 0x32, 0x01, 0x17, 0xcf, + 0x9c, 0x59, 0xb7, 0x9b, 0x4a, 0x4b, 0x3d, 0x6f, 0x68, 0x59, 0x9a, 0x6e, 0xe8, 0x6b, 0xdd, 0x82, + 0xeb, 0xb6, 0x44, 0x0f, 0x8b, 0x5d, 0x62, 0xd4, 0x55, 0x15, 0xb6, 0x45, 0xf7, 0xe9, 0xcf, 0x0a, + 0xec, 0xd9, 0xfe, 0x9c, 0x99, 0x41, 0xc2, 0xa2, 0x27, 0x77, 0x86, 0x3b, 0xb0, 0xcb, 0x82, 0xa9, + 0x93, 0x06, 0x23, 0x8e, 0xa3, 0x9e, 0x9f, 0x2c, 0x47, 0x2f, 0x53, 0xd3, 0xec, 0x65, 0x6a, 0xb4, + 0xca, 0x82, 0x69, 0x5a, 0xe1, 0x4b, 0x80, 0x38, 0x71, 0xa3, 0x44, 0x36, 0x2a, 0xff, 0xdb, 0x58, + 0x13, 0xee, 0xb4, 0x3e, 0xfd, 0xbb, 0x0a, 0xaa, 0xee, 0x79, 0x11, 0xf3, 0xc4, 0x55, 0xe1, 0x2e, + 0x20, 0x77, 0xe6, 0x7b, 0xc1, 0x9c, 0x05, 0x89, 0x13, 0xb2, 0xc8, 0xe7, 0xd3, 0x6c, 0xe0, 0x27, + 0xff, 0x1a, 0xd8, 0xcd, 0xee, 0x97, 0xd6, 0x3f, 0xb4, 0x0c, 0x45, 0x07, 0xfe, 0x1e, 0x70, 0xc8, + 0x22, 0x27, 0x66, 0x91, 0xcf, 0x62, 0x47, 0xa8, 0x2c, 0x12, 0x27, 0x3a, 0x38, 0xff, 0x52, 0xdb, + 0xf4, 0xe9, 0x69, 0x85, 0x4d, 0x68, 0xba, 0x6c, 0xa0, 0x28, 0x64, 0xd1, 0x48, 0xcc, 0xc8, 0x08, + 0xfe, 0x11, 0x8e, 0x1e, 0x23, 0x1e, 0xc7, 0xcb, 0xd1, 0x11, 0x9b, 0x2e, 0x1e, 0x59, 0x24, 0xae, + 0xec, 0xa3, 0x46, 0x53, 0xd9, 0x40, 0xb1, 0x18, 0x23, 0x87, 0x67, 0x0c, 0x7f, 0x01, 0x75, 0x2f, + 0xe2, 0x8b, 0xd0, 0x99, 0x3c, 0x3b, 0xef, 0x7d, 0x36, 0x9b, 0xc6, 0x8d, 0xed, 0x66, 0xa5, 0x55, + 0xa3, 0xfb, 0x02, 0x5f, 0x3d, 0x5f, 0x0b, 0x78, 0xfa, 0x4b, 0x05, 0xaa, 0xcb, 0x0d, 0x1d, 0x00, + 0xe8, 0x3d, 0xf3, 0xc6, 0x72, 0xac, 0x81, 0x45, 0x50, 0x09, 0xd7, 0x41, 0x95, 0x75, 0x97, 0xf4, + 0x6c, 0x1d, 0x29, 0xb9, 0x81, 0xea, 0x36, 0x41, 0x65, 0xfc, 0x12, 0x0e, 0x65, 0x6d, 0x5a, 0x36, + 0xa1, 0xc3, 0x41, 0x2f, 0xc5, 0x15, 0x7c, 0x04, 0x28, 0x9b, 0x43, 0xee, 0x6d, 0x67, 0xd0, 0xeb, + 0x12, 0x8a, 0xb6, 0xf0, 0x3e, 0xd4, 0x24, 0xed, 0x9b, 0x16, 0x82, 0x42, 0xa9, 0xdf, 0x23, 0x35, + 0x1f, 0xdd, 0x27, 0xba, 0x85, 0xf6, 0xf2, 0xb5, 0x8d, 0xc1, 0xd8, 0xb2, 0xd1, 0x7e, 0xee, 0x1f, + 0x8d, 0xfb, 0xe8, 0x00, 0x23, 0xd8, 0xcb, 0x4a, 0xbb, 0xdb, 0x25, 0x77, 0xa8, 0x9e, 0xaf, 0x2a, + 0x3a, 0x1c, 0x9b, 0x8e, 0x09, 0x42, 0xf9, 0x16, 0x25, 0xbd, 0xd6, 0x7b, 0x23, 0x82, 0x1a, 0xf8, + 0x15, 0xbc, 0x90, 0xf8, 0x9a, 0xea, 0x86, 0x6d, 0x0e, 0x2c, 0xe9, 0x3f, 0xcc, 0x85, 0x21, 0xa1, + 0x06, 0xb1, 0x6c, 0xb3, 0x47, 0x9c, 0xcb, 0x4b, 0x84, 0x37, 0x0b, 0x1d, 0xf4, 0x62, 0xa3, 0xd0, + 0x39, 0x43, 0x47, 0x1b, 0x85, 0xb3, 0x0e, 0x7a, 0x89, 0x1b, 0x70, 0xb4, 0x22, 0x38, 0xc6, 0xad, + 0x6e, 0xdd, 0x10, 0xf4, 0xea, 0xf4, 0x8f, 0x32, 0x54, 0x97, 0x37, 0x58, 0x07, 0x95, 0x92, 0xee, + 0xd8, 0x20, 0x85, 0xeb, 0xc8, 0x80, 0xc8, 0x48, 0x5c, 0xc7, 0x12, 0x98, 0x16, 0x2a, 0x17, 0x6b, + 0xfd, 0x1e, 0x55, 0x0a, 0x75, 0x9a, 0xd9, 0x16, 0x3e, 0x84, 0xfd, 0x65, 0x2d, 0x43, 0xdb, 0x4e, + 0x63, 0xcc, 0x90, 0xcc, 0x79, 0x27, 0x0d, 0xac, 0x48, 0x64, 0x2e, 0x55, 0x7c, 0x0c, 0x78, 0x05, + 0xcb, 0x20, 0xeb, 0xe9, 0x59, 0x32, 0xbe, 0x9a, 0xe4, 0x6e, 0x41, 0x59, 0x8d, 0xb2, 0xf6, 0x1f, + 0x4a, 0x07, 0xc1, 0x66, 0xa5, 0x73, 0x86, 0xd4, 0xcd, 0xca, 0x59, 0x07, 0xed, 0xbd, 0xfb, 0x55, + 0x81, 0x03, 0x83, 0xcf, 0x43, 0x37, 0xf2, 0x63, 0x1e, 0xa4, 0x6f, 0x2e, 0x3e, 0x81, 0x63, 0x63, + 0xd0, 0x1f, 0xea, 0xd4, 0x1c, 0x0d, 0x2c, 0x67, 0x6c, 0x8d, 0x86, 0xc4, 0x30, 0xaf, 0x4d, 0xd2, + 0x45, 0xa5, 0x34, 0x84, 0x82, 0x76, 0x63, 0x23, 0x65, 0x1d, 0xa5, 0x5f, 0xf6, 0x2a, 0xea, 0xd9, + 0xa8, 0xb2, 0x8e, 0x88, 0x0c, 0xb4, 0x80, 0xc8, 0x77, 0x68, 0x7b, 0x0d, 0x59, 0x04, 0xed, 0xbc, + 0xfb, 0x09, 0xd4, 0x11, 0x8b, 0x9e, 0xfc, 0x47, 0x66, 0xfb, 0x2c, 0xc2, 0xaf, 0xa1, 0x31, 0x22, + 0xf4, 0xce, 0x34, 0x88, 0x63, 0x9b, 0x84, 0xae, 0x6d, 0xef, 0x18, 0xf0, 0x8a, 0x7a, 0xa5, 0x8f, + 0x4c, 0x03, 0x29, 0xe9, 0xf9, 0x57, 0xf8, 0x90, 0x92, 0xbe, 0x39, 0xee, 0xa3, 0xf2, 0xd5, 0x6f, + 0x0a, 0x34, 0x1e, 0xf9, 0x7c, 0xe3, 0x73, 0x71, 0xa5, 0x1a, 0xe2, 0x47, 0x39, 0x4c, 0x9f, 0xb9, + 0xa1, 0xf2, 0xc3, 0xb7, 0x99, 0xc9, 0xe3, 0x33, 0x37, 0xf0, 0x34, 0x1e, 0x79, 0x6d, 0x8f, 0x05, + 0xe2, 0x11, 0x6c, 0x4b, 0xc9, 0x0d, 0xfd, 0x78, 0xf5, 0x5f, 0xfb, 0x4d, 0x5e, 0xfd, 0x5e, 0x3e, + 0xb9, 0x91, 0x03, 0x8c, 0x19, 0x5f, 0x4c, 0xb5, 0x7e, 0xbe, 0xd6, 0xdd, 0xc5, 0x9f, 0x4b, 0xf1, + 0x41, 0x88, 0x0f, 0xb9, 0xf8, 0x70, 0x77, 0x31, 0xd9, 0x11, 0x8b, 0x5c, 0xfc, 0x13, 0x00, 0x00, + 0xff, 0xff, 0xe2, 0x9f, 0x67, 0xb2, 0xcf, 0x07, 0x00, 0x00, } diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go index a9c0dd811b..0afad7a68a 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group.pb.go @@ -61,7 +61,7 @@ type Group struct { func (m *Group) Reset() { *m = Group{} } func (m *Group) String() string { return proto.CompactTextString(m) } func (*Group) ProtoMessage() {} -func (*Group) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } +func (*Group) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } func (m *Group) GetName() string { if m != nil { @@ -102,9 +102,9 @@ func init() { proto.RegisterType((*Group)(nil), "google.monitoring.v3.Group") } -func init() { proto.RegisterFile("google/monitoring/v3/group.proto", fileDescriptor1) } +func init() { proto.RegisterFile("google/monitoring/v3/group.proto", fileDescriptor3) } -var fileDescriptor1 = []byte{ +var fileDescriptor3 = []byte{ // 261 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xcf, 0x4a, 0x2b, 0x31, 0x14, 0x87, 0x49, 0xef, 0xed, 0x60, 0x4f, 0x5d, 0x0d, 0x22, 0x83, 0x20, 0x8e, 0xae, 0xba, 0xca, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go index 14750fa97c..de212a50b4 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/group_service.pb.go @@ -8,7 +8,7 @@ import fmt "fmt" import math "math" import _ "google.golang.org/genproto/googleapis/api/annotations" import google_api4 "google.golang.org/genproto/googleapis/api/monitoredres" -import google_protobuf4 "github.com/golang/protobuf/ptypes/empty" +import google_protobuf5 "github.com/golang/protobuf/ptypes/empty" import ( context "golang.org/x/net/context" @@ -45,7 +45,7 @@ type ListGroupsRequest struct { func (m *ListGroupsRequest) Reset() { *m = ListGroupsRequest{} } func (m *ListGroupsRequest) String() string { return proto.CompactTextString(m) } func (*ListGroupsRequest) ProtoMessage() {} -func (*ListGroupsRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } +func (*ListGroupsRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} } type isListGroupsRequest_Filter interface { isListGroupsRequest_Filter() @@ -208,7 +208,7 @@ type ListGroupsResponse struct { func (m *ListGroupsResponse) Reset() { *m = ListGroupsResponse{} } func (m *ListGroupsResponse) String() string { return proto.CompactTextString(m) } func (*ListGroupsResponse) ProtoMessage() {} -func (*ListGroupsResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } +func (*ListGroupsResponse) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{1} } func (m *ListGroupsResponse) GetGroup() []*Group { if m != nil { @@ -234,7 +234,7 @@ type GetGroupRequest struct { func (m *GetGroupRequest) Reset() { *m = GetGroupRequest{} } func (m *GetGroupRequest) String() string { return proto.CompactTextString(m) } func (*GetGroupRequest) ProtoMessage() {} -func (*GetGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} } +func (*GetGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{2} } func (m *GetGroupRequest) GetName() string { if m != nil { @@ -258,7 +258,7 @@ type CreateGroupRequest struct { func (m *CreateGroupRequest) Reset() { *m = CreateGroupRequest{} } func (m *CreateGroupRequest) String() string { return proto.CompactTextString(m) } func (*CreateGroupRequest) ProtoMessage() {} -func (*CreateGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{3} } +func (*CreateGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{3} } func (m *CreateGroupRequest) GetName() string { if m != nil { @@ -293,7 +293,7 @@ type UpdateGroupRequest struct { func (m *UpdateGroupRequest) Reset() { *m = UpdateGroupRequest{} } func (m *UpdateGroupRequest) String() string { return proto.CompactTextString(m) } func (*UpdateGroupRequest) ProtoMessage() {} -func (*UpdateGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{4} } +func (*UpdateGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{4} } func (m *UpdateGroupRequest) GetGroup() *Group { if m != nil { @@ -319,7 +319,7 @@ type DeleteGroupRequest struct { func (m *DeleteGroupRequest) Reset() { *m = DeleteGroupRequest{} } func (m *DeleteGroupRequest) String() string { return proto.CompactTextString(m) } func (*DeleteGroupRequest) ProtoMessage() {} -func (*DeleteGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{5} } +func (*DeleteGroupRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{5} } func (m *DeleteGroupRequest) GetName() string { if m != nil { @@ -357,7 +357,7 @@ type ListGroupMembersRequest struct { func (m *ListGroupMembersRequest) Reset() { *m = ListGroupMembersRequest{} } func (m *ListGroupMembersRequest) String() string { return proto.CompactTextString(m) } func (*ListGroupMembersRequest) ProtoMessage() {} -func (*ListGroupMembersRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{6} } +func (*ListGroupMembersRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{6} } func (m *ListGroupMembersRequest) GetName() string { if m != nil { @@ -409,7 +409,7 @@ type ListGroupMembersResponse struct { func (m *ListGroupMembersResponse) Reset() { *m = ListGroupMembersResponse{} } func (m *ListGroupMembersResponse) String() string { return proto.CompactTextString(m) } func (*ListGroupMembersResponse) ProtoMessage() {} -func (*ListGroupMembersResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{7} } +func (*ListGroupMembersResponse) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{7} } func (m *ListGroupMembersResponse) GetMembers() []*google_api4.MonitoredResource { if m != nil { @@ -464,7 +464,7 @@ type GroupServiceClient interface { // You can change any group attributes except `name`. UpdateGroup(ctx context.Context, in *UpdateGroupRequest, opts ...grpc.CallOption) (*Group, error) // Deletes an existing group. - DeleteGroup(ctx context.Context, in *DeleteGroupRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) + DeleteGroup(ctx context.Context, in *DeleteGroupRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) // Lists the monitored resources that are members of a group. ListGroupMembers(ctx context.Context, in *ListGroupMembersRequest, opts ...grpc.CallOption) (*ListGroupMembersResponse, error) } @@ -513,8 +513,8 @@ func (c *groupServiceClient) UpdateGroup(ctx context.Context, in *UpdateGroupReq return out, nil } -func (c *groupServiceClient) DeleteGroup(ctx context.Context, in *DeleteGroupRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) { - out := new(google_protobuf4.Empty) +func (c *groupServiceClient) DeleteGroup(ctx context.Context, in *DeleteGroupRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) err := grpc.Invoke(ctx, "/google.monitoring.v3.GroupService/DeleteGroup", in, out, c.cc, opts...) if err != nil { return nil, err @@ -544,7 +544,7 @@ type GroupServiceServer interface { // You can change any group attributes except `name`. UpdateGroup(context.Context, *UpdateGroupRequest) (*Group, error) // Deletes an existing group. - DeleteGroup(context.Context, *DeleteGroupRequest) (*google_protobuf4.Empty, error) + DeleteGroup(context.Context, *DeleteGroupRequest) (*google_protobuf5.Empty, error) // Lists the monitored resources that are members of a group. ListGroupMembers(context.Context, *ListGroupMembersRequest) (*ListGroupMembersResponse, error) } @@ -694,9 +694,9 @@ var _GroupService_serviceDesc = grpc.ServiceDesc{ Metadata: "google/monitoring/v3/group_service.proto", } -func init() { proto.RegisterFile("google/monitoring/v3/group_service.proto", fileDescriptor2) } +func init() { proto.RegisterFile("google/monitoring/v3/group_service.proto", fileDescriptor4) } -var fileDescriptor2 = []byte{ +var fileDescriptor4 = []byte{ // 826 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x4d, 0x6f, 0xd3, 0x4c, 0x10, 0x7e, 0xdd, 0xa4, 0x69, 0xb2, 0x69, 0xd5, 0x76, 0x55, 0xf5, 0x8d, 0xdc, 0x0f, 0x05, 0xf7, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go index 533b5373cd..99e745139b 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric.pb.go @@ -32,7 +32,7 @@ type Point struct { func (m *Point) Reset() { *m = Point{} } func (m *Point) String() string { return proto.CompactTextString(m) } func (*Point) ProtoMessage() {} -func (*Point) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } +func (*Point) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} } func (m *Point) GetInterval() *TimeInterval { if m != nil { @@ -90,7 +90,7 @@ type TimeSeries struct { func (m *TimeSeries) Reset() { *m = TimeSeries{} } func (m *TimeSeries) String() string { return proto.CompactTextString(m) } func (*TimeSeries) ProtoMessage() {} -func (*TimeSeries) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{1} } +func (*TimeSeries) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{1} } func (m *TimeSeries) GetMetric() *google_api5.Metric { if m != nil { @@ -132,9 +132,9 @@ func init() { proto.RegisterType((*TimeSeries)(nil), "google.monitoring.v3.TimeSeries") } -func init() { proto.RegisterFile("google/monitoring/v3/metric.proto", fileDescriptor3) } +func init() { proto.RegisterFile("google/monitoring/v3/metric.proto", fileDescriptor5) } -var fileDescriptor3 = []byte{ +var fileDescriptor5 = []byte{ // 396 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xc1, 0x4a, 0xeb, 0x40, 0x14, 0x86, 0x49, 0x7b, 0x5b, 0x7a, 0x27, 0x70, 0x17, 0xc3, 0x05, 0x43, 0x45, 0x88, 0x15, 0xb4, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go index 77840f1cfe..1673fecb89 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/metric_service.pb.go @@ -9,7 +9,7 @@ import math "math" import _ "google.golang.org/genproto/googleapis/api/annotations" import google_api5 "google.golang.org/genproto/googleapis/api/metric" import google_api4 "google.golang.org/genproto/googleapis/api/monitoredres" -import google_protobuf4 "github.com/golang/protobuf/ptypes/empty" +import google_protobuf5 "github.com/golang/protobuf/ptypes/empty" import google_rpc "google.golang.org/genproto/googleapis/rpc/status" import ( @@ -47,7 +47,7 @@ func (x ListTimeSeriesRequest_TimeSeriesView) String() string { return proto.EnumName(ListTimeSeriesRequest_TimeSeriesView_name, int32(x)) } func (ListTimeSeriesRequest_TimeSeriesView) EnumDescriptor() ([]byte, []int) { - return fileDescriptor4, []int{8, 0} + return fileDescriptor6, []int{8, 0} } // The `ListMonitoredResourceDescriptors` request. @@ -77,7 +77,7 @@ func (m *ListMonitoredResourceDescriptorsRequest) Reset() { func (m *ListMonitoredResourceDescriptorsRequest) String() string { return proto.CompactTextString(m) } func (*ListMonitoredResourceDescriptorsRequest) ProtoMessage() {} func (*ListMonitoredResourceDescriptorsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor4, []int{0} + return fileDescriptor6, []int{0} } func (m *ListMonitoredResourceDescriptorsRequest) GetName() string { @@ -125,7 +125,7 @@ func (m *ListMonitoredResourceDescriptorsResponse) Reset() { func (m *ListMonitoredResourceDescriptorsResponse) String() string { return proto.CompactTextString(m) } func (*ListMonitoredResourceDescriptorsResponse) ProtoMessage() {} func (*ListMonitoredResourceDescriptorsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor4, []int{1} + return fileDescriptor6, []int{1} } func (m *ListMonitoredResourceDescriptorsResponse) GetResourceDescriptors() []*google_api4.MonitoredResourceDescriptor { @@ -155,7 +155,7 @@ func (m *GetMonitoredResourceDescriptorRequest) Reset() { *m = GetMonito func (m *GetMonitoredResourceDescriptorRequest) String() string { return proto.CompactTextString(m) } func (*GetMonitoredResourceDescriptorRequest) ProtoMessage() {} func (*GetMonitoredResourceDescriptorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor4, []int{2} + return fileDescriptor6, []int{2} } func (m *GetMonitoredResourceDescriptorRequest) GetName() string { @@ -190,7 +190,7 @@ type ListMetricDescriptorsRequest struct { func (m *ListMetricDescriptorsRequest) Reset() { *m = ListMetricDescriptorsRequest{} } func (m *ListMetricDescriptorsRequest) String() string { return proto.CompactTextString(m) } func (*ListMetricDescriptorsRequest) ProtoMessage() {} -func (*ListMetricDescriptorsRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{3} } +func (*ListMetricDescriptorsRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{3} } func (m *ListMetricDescriptorsRequest) GetName() string { if m != nil { @@ -234,7 +234,7 @@ type ListMetricDescriptorsResponse struct { func (m *ListMetricDescriptorsResponse) Reset() { *m = ListMetricDescriptorsResponse{} } func (m *ListMetricDescriptorsResponse) String() string { return proto.CompactTextString(m) } func (*ListMetricDescriptorsResponse) ProtoMessage() {} -func (*ListMetricDescriptorsResponse) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{4} } +func (*ListMetricDescriptorsResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{4} } func (m *ListMetricDescriptorsResponse) GetMetricDescriptors() []*google_api5.MetricDescriptor { if m != nil { @@ -262,7 +262,7 @@ type GetMetricDescriptorRequest struct { func (m *GetMetricDescriptorRequest) Reset() { *m = GetMetricDescriptorRequest{} } func (m *GetMetricDescriptorRequest) String() string { return proto.CompactTextString(m) } func (*GetMetricDescriptorRequest) ProtoMessage() {} -func (*GetMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{5} } +func (*GetMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{5} } func (m *GetMetricDescriptorRequest) GetName() string { if m != nil { @@ -284,7 +284,7 @@ type CreateMetricDescriptorRequest struct { func (m *CreateMetricDescriptorRequest) Reset() { *m = CreateMetricDescriptorRequest{} } func (m *CreateMetricDescriptorRequest) String() string { return proto.CompactTextString(m) } func (*CreateMetricDescriptorRequest) ProtoMessage() {} -func (*CreateMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{6} } +func (*CreateMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{6} } func (m *CreateMetricDescriptorRequest) GetName() string { if m != nil { @@ -312,7 +312,7 @@ type DeleteMetricDescriptorRequest struct { func (m *DeleteMetricDescriptorRequest) Reset() { *m = DeleteMetricDescriptorRequest{} } func (m *DeleteMetricDescriptorRequest) String() string { return proto.CompactTextString(m) } func (*DeleteMetricDescriptorRequest) ProtoMessage() {} -func (*DeleteMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{7} } +func (*DeleteMetricDescriptorRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{7} } func (m *DeleteMetricDescriptorRequest) GetName() string { if m != nil { @@ -362,7 +362,7 @@ type ListTimeSeriesRequest struct { func (m *ListTimeSeriesRequest) Reset() { *m = ListTimeSeriesRequest{} } func (m *ListTimeSeriesRequest) String() string { return proto.CompactTextString(m) } func (*ListTimeSeriesRequest) ProtoMessage() {} -func (*ListTimeSeriesRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{8} } +func (*ListTimeSeriesRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{8} } func (m *ListTimeSeriesRequest) GetName() string { if m != nil { @@ -433,7 +433,7 @@ type ListTimeSeriesResponse struct { func (m *ListTimeSeriesResponse) Reset() { *m = ListTimeSeriesResponse{} } func (m *ListTimeSeriesResponse) String() string { return proto.CompactTextString(m) } func (*ListTimeSeriesResponse) ProtoMessage() {} -func (*ListTimeSeriesResponse) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{9} } +func (*ListTimeSeriesResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{9} } func (m *ListTimeSeriesResponse) GetTimeSeries() []*TimeSeries { if m != nil { @@ -465,7 +465,7 @@ type CreateTimeSeriesRequest struct { func (m *CreateTimeSeriesRequest) Reset() { *m = CreateTimeSeriesRequest{} } func (m *CreateTimeSeriesRequest) String() string { return proto.CompactTextString(m) } func (*CreateTimeSeriesRequest) ProtoMessage() {} -func (*CreateTimeSeriesRequest) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{10} } +func (*CreateTimeSeriesRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{10} } func (m *CreateTimeSeriesRequest) GetName() string { if m != nil { @@ -495,7 +495,7 @@ type CreateTimeSeriesError struct { func (m *CreateTimeSeriesError) Reset() { *m = CreateTimeSeriesError{} } func (m *CreateTimeSeriesError) String() string { return proto.CompactTextString(m) } func (*CreateTimeSeriesError) ProtoMessage() {} -func (*CreateTimeSeriesError) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{11} } +func (*CreateTimeSeriesError) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{11} } func (m *CreateTimeSeriesError) GetTimeSeries() *TimeSeries { if m != nil { @@ -552,14 +552,14 @@ type MetricServiceClient interface { CreateMetricDescriptor(ctx context.Context, in *CreateMetricDescriptorRequest, opts ...grpc.CallOption) (*google_api5.MetricDescriptor, error) // Deletes a metric descriptor. Only user-created // [custom metrics](/monitoring/custom-metrics) can be deleted. - DeleteMetricDescriptor(ctx context.Context, in *DeleteMetricDescriptorRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) + DeleteMetricDescriptor(ctx context.Context, in *DeleteMetricDescriptorRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) // Lists time series that match a filter. This method does not require a Stackdriver account. ListTimeSeries(ctx context.Context, in *ListTimeSeriesRequest, opts ...grpc.CallOption) (*ListTimeSeriesResponse, error) // Creates or adds data to one or more time series. // The response is empty if all time series in the request were written. // If any time series could not be written, a corresponding failure message is // included in the error response. - CreateTimeSeries(ctx context.Context, in *CreateTimeSeriesRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) + CreateTimeSeries(ctx context.Context, in *CreateTimeSeriesRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) } type metricServiceClient struct { @@ -615,8 +615,8 @@ func (c *metricServiceClient) CreateMetricDescriptor(ctx context.Context, in *Cr return out, nil } -func (c *metricServiceClient) DeleteMetricDescriptor(ctx context.Context, in *DeleteMetricDescriptorRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) { - out := new(google_protobuf4.Empty) +func (c *metricServiceClient) DeleteMetricDescriptor(ctx context.Context, in *DeleteMetricDescriptorRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) err := grpc.Invoke(ctx, "/google.monitoring.v3.MetricService/DeleteMetricDescriptor", in, out, c.cc, opts...) if err != nil { return nil, err @@ -633,8 +633,8 @@ func (c *metricServiceClient) ListTimeSeries(ctx context.Context, in *ListTimeSe return out, nil } -func (c *metricServiceClient) CreateTimeSeries(ctx context.Context, in *CreateTimeSeriesRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) { - out := new(google_protobuf4.Empty) +func (c *metricServiceClient) CreateTimeSeries(ctx context.Context, in *CreateTimeSeriesRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) err := grpc.Invoke(ctx, "/google.monitoring.v3.MetricService/CreateTimeSeries", in, out, c.cc, opts...) if err != nil { return nil, err @@ -659,14 +659,14 @@ type MetricServiceServer interface { CreateMetricDescriptor(context.Context, *CreateMetricDescriptorRequest) (*google_api5.MetricDescriptor, error) // Deletes a metric descriptor. Only user-created // [custom metrics](/monitoring/custom-metrics) can be deleted. - DeleteMetricDescriptor(context.Context, *DeleteMetricDescriptorRequest) (*google_protobuf4.Empty, error) + DeleteMetricDescriptor(context.Context, *DeleteMetricDescriptorRequest) (*google_protobuf5.Empty, error) // Lists time series that match a filter. This method does not require a Stackdriver account. ListTimeSeries(context.Context, *ListTimeSeriesRequest) (*ListTimeSeriesResponse, error) // Creates or adds data to one or more time series. // The response is empty if all time series in the request were written. // If any time series could not be written, a corresponding failure message is // included in the error response. - CreateTimeSeries(context.Context, *CreateTimeSeriesRequest) (*google_protobuf4.Empty, error) + CreateTimeSeries(context.Context, *CreateTimeSeriesRequest) (*google_protobuf5.Empty, error) } func RegisterMetricServiceServer(s *grpc.Server, srv MetricServiceServer) { @@ -858,9 +858,9 @@ var _MetricService_serviceDesc = grpc.ServiceDesc{ Metadata: "google/monitoring/v3/metric_service.proto", } -func init() { proto.RegisterFile("google/monitoring/v3/metric_service.proto", fileDescriptor4) } +func init() { proto.RegisterFile("google/monitoring/v3/metric_service.proto", fileDescriptor6) } -var fileDescriptor4 = []byte{ +var fileDescriptor6 = []byte{ // 1011 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0x4d, 0x6f, 0x1b, 0x45, 0x18, 0x66, 0x92, 0x34, 0x1f, 0xaf, 0xd5, 0x90, 0x4e, 0x5b, 0xd7, 0x6c, 0x13, 0xe4, 0x2e, 0x2a, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go new file mode 100644 index 0000000000..32f983d04e --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/mutation_record.pb.go @@ -0,0 +1,67 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/monitoring/v3/mutation_record.proto + +package monitoring + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf2 "github.com/golang/protobuf/ptypes/timestamp" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Describes a change made to a configuration. +type MutationRecord struct { + // When the change occurred. + MutateTime *google_protobuf2.Timestamp `protobuf:"bytes,1,opt,name=mutate_time,json=mutateTime" json:"mutate_time,omitempty"` + // The email address of the user making the change. + MutatedBy string `protobuf:"bytes,2,opt,name=mutated_by,json=mutatedBy" json:"mutated_by,omitempty"` +} + +func (m *MutationRecord) Reset() { *m = MutationRecord{} } +func (m *MutationRecord) String() string { return proto.CompactTextString(m) } +func (*MutationRecord) ProtoMessage() {} +func (*MutationRecord) Descriptor() ([]byte, []int) { return fileDescriptor7, []int{0} } + +func (m *MutationRecord) GetMutateTime() *google_protobuf2.Timestamp { + if m != nil { + return m.MutateTime + } + return nil +} + +func (m *MutationRecord) GetMutatedBy() string { + if m != nil { + return m.MutatedBy + } + return "" +} + +func init() { + proto.RegisterType((*MutationRecord)(nil), "google.monitoring.v3.MutationRecord") +} + +func init() { proto.RegisterFile("google/monitoring/v3/mutation_record.proto", fileDescriptor7) } + +var fileDescriptor7 = []byte{ + // 251 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4a, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0xcf, 0xcd, 0xcf, 0xcb, 0x2c, 0xc9, 0x2f, 0xca, 0xcc, 0x4b, 0xd7, 0x2f, 0x33, + 0xd6, 0xcf, 0x2d, 0x2d, 0x49, 0x2c, 0xc9, 0xcc, 0xcf, 0x8b, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4a, + 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x81, 0xa8, 0xd5, 0x43, 0xa8, 0xd5, 0x2b, 0x33, + 0x96, 0x92, 0x87, 0x9a, 0x00, 0x56, 0x93, 0x54, 0x9a, 0xa6, 0x5f, 0x92, 0x99, 0x9b, 0x5a, 0x5c, + 0x92, 0x98, 0x5b, 0x00, 0xd1, 0xa6, 0x94, 0xc3, 0xc5, 0xe7, 0x0b, 0x35, 0x2f, 0x08, 0x6c, 0x9c, + 0x90, 0x35, 0x17, 0x37, 0xd8, 0x86, 0xd4, 0x78, 0x90, 0x5a, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, + 0x23, 0x29, 0x3d, 0xa8, 0xf1, 0x30, 0x83, 0xf4, 0x42, 0x60, 0x06, 0x05, 0x71, 0x41, 0x94, 0x83, + 0x04, 0x84, 0x64, 0xb9, 0xa0, 0xbc, 0x94, 0xf8, 0xa4, 0x4a, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xce, + 0x20, 0x4e, 0xa8, 0x88, 0x53, 0xa5, 0xd3, 0x6a, 0x46, 0x2e, 0x89, 0xe4, 0xfc, 0x5c, 0x3d, 0x6c, + 0x6e, 0x75, 0x12, 0x46, 0x75, 0x48, 0x00, 0xc8, 0xa6, 0x00, 0xc6, 0x28, 0x3b, 0xa8, 0xe2, 0xf4, + 0xfc, 0x9c, 0xc4, 0xbc, 0x74, 0xbd, 0xfc, 0xa2, 0x74, 0xfd, 0xf4, 0xd4, 0x3c, 0xb0, 0x3b, 0xf4, + 0x21, 0x52, 0x89, 0x05, 0x99, 0xc5, 0xa8, 0x61, 0x64, 0x8d, 0xe0, 0xad, 0x62, 0x92, 0x72, 0x87, + 0x18, 0xe0, 0x9c, 0x93, 0x5f, 0x9a, 0xa2, 0xe7, 0x8b, 0xb0, 0x33, 0xcc, 0xf8, 0x14, 0x4c, 0x32, + 0x06, 0x2c, 0x19, 0x83, 0x90, 0x8c, 0x09, 0x33, 0x4e, 0x62, 0x03, 0x5b, 0x62, 0x0c, 0x08, 0x00, + 0x00, 0xff, 0xff, 0x95, 0xa7, 0xf3, 0xbd, 0x87, 0x01, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go new file mode 100644 index 0000000000..6d0534efba --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification.pb.go @@ -0,0 +1,313 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/monitoring/v3/notification.proto + +package monitoring + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import google_api3 "google.golang.org/genproto/googleapis/api/label" +import google_protobuf4 "github.com/golang/protobuf/ptypes/wrappers" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Indicates whether the channel has been verified or not. It is illegal +// to specify this field in a +// [`CreateNotificationChannel`][google.monitoring.v3.NotificationChannelService.CreateNotificationChannel] +// or an +// [`UpdateNotificationChannel`][google.monitoring.v3.NotificationChannelService.UpdateNotificationChannel] +// operation. +type NotificationChannel_VerificationStatus int32 + +const ( + // Sentinel value used to indicate that the state is unknown, omitted, or + // is not applicable (as in the case of channels that neither support + // nor require verification in order to function). + NotificationChannel_VERIFICATION_STATUS_UNSPECIFIED NotificationChannel_VerificationStatus = 0 + // The channel has yet to be verified and requires verification to function. + // Note that this state also applies to the case where the verification + // process has been initiated by sending a verification code but where + // the verification code has not been submitted to complete the process. + NotificationChannel_UNVERIFIED NotificationChannel_VerificationStatus = 1 + // It has been proven that notifications can be received on this + // notification channel and that someone on the project has access + // to messages that are delivered to that channel. + NotificationChannel_VERIFIED NotificationChannel_VerificationStatus = 2 +) + +var NotificationChannel_VerificationStatus_name = map[int32]string{ + 0: "VERIFICATION_STATUS_UNSPECIFIED", + 1: "UNVERIFIED", + 2: "VERIFIED", +} +var NotificationChannel_VerificationStatus_value = map[string]int32{ + "VERIFICATION_STATUS_UNSPECIFIED": 0, + "UNVERIFIED": 1, + "VERIFIED": 2, +} + +func (x NotificationChannel_VerificationStatus) String() string { + return proto.EnumName(NotificationChannel_VerificationStatus_name, int32(x)) +} +func (NotificationChannel_VerificationStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor8, []int{1, 0} +} + +// A description of a notification channel. The descriptor includes +// the properties of the channel and the set of labels or fields that +// must be specified to configure channels of a given type. +type NotificationChannelDescriptor struct { + // The full REST resource name for this descriptor. The syntax is: + // + // projects/[PROJECT_ID]/notificationChannelDescriptors/[TYPE] + // + // In the above, `[TYPE]` is the value of the `type` field. + Name string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` + // The type of notification channel, such as "email", "sms", etc. + // Notification channel types are globally unique. + Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` + // A human-readable name for the notification channel type. This + // form of the name is suitable for a user interface. + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // A human-readable description of the notification channel + // type. The description may include a description of the properties + // of the channel and pointers to external documentation. + Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` + // The set of labels that must be defined to identify a particular + // channel of the corresponding type. Each label includes a + // description for how that field should be populated. + Labels []*google_api3.LabelDescriptor `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty"` + // The tiers that support this notification channel; the project service tier + // must be one of the supported_tiers. + SupportedTiers []ServiceTier `protobuf:"varint,5,rep,packed,name=supported_tiers,json=supportedTiers,enum=google.monitoring.v3.ServiceTier" json:"supported_tiers,omitempty"` +} + +func (m *NotificationChannelDescriptor) Reset() { *m = NotificationChannelDescriptor{} } +func (m *NotificationChannelDescriptor) String() string { return proto.CompactTextString(m) } +func (*NotificationChannelDescriptor) ProtoMessage() {} +func (*NotificationChannelDescriptor) Descriptor() ([]byte, []int) { return fileDescriptor8, []int{0} } + +func (m *NotificationChannelDescriptor) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *NotificationChannelDescriptor) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *NotificationChannelDescriptor) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *NotificationChannelDescriptor) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *NotificationChannelDescriptor) GetLabels() []*google_api3.LabelDescriptor { + if m != nil { + return m.Labels + } + return nil +} + +func (m *NotificationChannelDescriptor) GetSupportedTiers() []ServiceTier { + if m != nil { + return m.SupportedTiers + } + return nil +} + +// A `NotificationChannel` is a medium through which an alert is +// delivered when a policy violation is detected. Examples of channels +// include email, SMS, and third-party messaging applications. Fields +// containing sensitive information like authentication tokens or +// contact info are only partially populated on retrieval. +type NotificationChannel struct { + // The type of the notification channel. This field matches the + // value of the [NotificationChannelDescriptor.type][google.monitoring.v3.NotificationChannelDescriptor.type] field. + Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` + // The full REST resource name for this channel. The syntax is: + // + // projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID] + // + // The `[CHANNEL_ID]` is automatically assigned by the server on creation. + Name string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` + // An optional human-readable name for this notification channel. It is + // recommended that you specify a non-empty and unique name in order to + // make it easier to identify the channels in your project, though this is + // not enforced. The display name is limited to 512 Unicode characters. + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // An optional human-readable description of this notification channel. This + // description may provide additional details, beyond the display + // name, for the channel. This may not exceeed 1024 Unicode characters. + Description string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` + // Configuration fields that define the channel and its behavior. The + // permissible and required labels are specified in the + // [NotificationChannelDescriptor.labels][google.monitoring.v3.NotificationChannelDescriptor.labels] of the + // `NotificationChannelDescriptor` corresponding to the `type` field. + Labels map[string]string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // User-supplied key/value data that does not need to conform to + // the corresponding `NotificationChannelDescriptor`'s schema, unlike + // the `labels` field. This field is intended to be used for organizing + // and identifying the `NotificationChannel` objects. + // + // The field can contain up to 64 entries. Each key and value is limited to + // 63 Unicode characters or 128 bytes, whichever is smaller. Labels and + // values can contain only lowercase letters, numerals, underscores, and + // dashes. Keys must begin with a letter. + UserLabels map[string]string `protobuf:"bytes,8,rep,name=user_labels,json=userLabels" json:"user_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Indicates whether this channel has been verified or not. On a + // [`ListNotificationChannels`][google.monitoring.v3.NotificationChannelService.ListNotificationChannels] + // or + // [`GetNotificationChannel`][google.monitoring.v3.NotificationChannelService.GetNotificationChannel] + // operation, this field is expected to be populated. + // + // If the value is `UNVERIFIED`, then it indicates that the channel is + // non-functioning (it both requires verification and lacks verification); + // otherwise, it is assumed that the channel works. + // + // If the channel is neither `VERIFIED` nor `UNVERIFIED`, it implies that + // the channel is of a type that does not require verification or that + // this specific channel has been exempted from verification because it was + // created prior to verification being required for channels of this type. + // + // This field cannot be modified using a standard + // [`UpdateNotificationChannel`][google.monitoring.v3.NotificationChannelService.UpdateNotificationChannel] + // operation. To change the value of this field, you must call + // [`VerifyNotificationChannel`][google.monitoring.v3.NotificationChannelService.VerifyNotificationChannel]. + VerificationStatus NotificationChannel_VerificationStatus `protobuf:"varint,9,opt,name=verification_status,json=verificationStatus,enum=google.monitoring.v3.NotificationChannel_VerificationStatus" json:"verification_status,omitempty"` + // Whether notifications are forwarded to the described channel. This makes + // it possible to disable delivery of notifications to a particular channel + // without removing the channel from all alerting policies that reference + // the channel. This is a more convenient approach when the change is + // temporary and you want to receive notifications from the same set + // of alerting policies on the channel at some point in the future. + Enabled *google_protobuf4.BoolValue `protobuf:"bytes,11,opt,name=enabled" json:"enabled,omitempty"` +} + +func (m *NotificationChannel) Reset() { *m = NotificationChannel{} } +func (m *NotificationChannel) String() string { return proto.CompactTextString(m) } +func (*NotificationChannel) ProtoMessage() {} +func (*NotificationChannel) Descriptor() ([]byte, []int) { return fileDescriptor8, []int{1} } + +func (m *NotificationChannel) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *NotificationChannel) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *NotificationChannel) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *NotificationChannel) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *NotificationChannel) GetLabels() map[string]string { + if m != nil { + return m.Labels + } + return nil +} + +func (m *NotificationChannel) GetUserLabels() map[string]string { + if m != nil { + return m.UserLabels + } + return nil +} + +func (m *NotificationChannel) GetVerificationStatus() NotificationChannel_VerificationStatus { + if m != nil { + return m.VerificationStatus + } + return NotificationChannel_VERIFICATION_STATUS_UNSPECIFIED +} + +func (m *NotificationChannel) GetEnabled() *google_protobuf4.BoolValue { + if m != nil { + return m.Enabled + } + return nil +} + +func init() { + proto.RegisterType((*NotificationChannelDescriptor)(nil), "google.monitoring.v3.NotificationChannelDescriptor") + proto.RegisterType((*NotificationChannel)(nil), "google.monitoring.v3.NotificationChannel") + proto.RegisterEnum("google.monitoring.v3.NotificationChannel_VerificationStatus", NotificationChannel_VerificationStatus_name, NotificationChannel_VerificationStatus_value) +} + +func init() { proto.RegisterFile("google/monitoring/v3/notification.proto", fileDescriptor8) } + +var fileDescriptor8 = []byte{ + // 599 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdd, 0x6e, 0xd3, 0x30, + 0x14, 0xc7, 0x49, 0xbb, 0x8e, 0xcd, 0x99, 0xba, 0xe1, 0x4d, 0x28, 0x0a, 0x5f, 0xdd, 0xb8, 0xa0, + 0x57, 0x89, 0xd4, 0x82, 0xc4, 0xf8, 0x92, 0xb6, 0xae, 0x43, 0x45, 0xac, 0x4c, 0xfd, 0x42, 0x9a, + 0x26, 0x55, 0x6e, 0xeb, 0x05, 0x8b, 0xc4, 0x8e, 0x6c, 0x27, 0xa8, 0x0f, 0xc1, 0x63, 0x70, 0x01, + 0x8f, 0xc2, 0x53, 0xa1, 0x38, 0x6e, 0x12, 0xb6, 0x48, 0x8c, 0x3b, 0x9f, 0x73, 0xfe, 0xe7, 0x7f, + 0xce, 0xf9, 0x35, 0x2a, 0x78, 0xe6, 0x31, 0xe6, 0xf9, 0xd8, 0x0d, 0x18, 0x25, 0x92, 0x71, 0x42, + 0x3d, 0x37, 0x6e, 0xbb, 0x94, 0x49, 0x72, 0x45, 0xe6, 0x48, 0x12, 0x46, 0x9d, 0x90, 0x33, 0xc9, + 0xe0, 0x5e, 0x2a, 0x74, 0x72, 0xa1, 0x13, 0xb7, 0xed, 0x87, 0xba, 0x1d, 0x85, 0xc4, 0x45, 0x94, + 0x32, 0xa9, 0x5a, 0x44, 0xda, 0x63, 0xdf, 0x2f, 0x54, 0x7d, 0x34, 0xc3, 0xbe, 0xce, 0xef, 0x97, + 0x0e, 0x9d, 0xb3, 0x20, 0x58, 0x8d, 0xb3, 0x1f, 0x6b, 0x89, 0x8a, 0x66, 0xd1, 0x95, 0xfb, 0x8d, + 0xa3, 0x30, 0xc4, 0x5c, 0x5b, 0x1f, 0x7c, 0xaf, 0x80, 0x47, 0xfd, 0xc2, 0x96, 0x9d, 0x2f, 0x88, + 0x52, 0xec, 0x9f, 0x60, 0x31, 0xe7, 0x24, 0x94, 0x8c, 0x43, 0x08, 0xd6, 0x28, 0x0a, 0xb0, 0xb5, + 0xde, 0x30, 0x9a, 0x9b, 0x03, 0xf5, 0x4e, 0x72, 0x72, 0x19, 0x62, 0xcb, 0x48, 0x73, 0xc9, 0x1b, + 0xee, 0x83, 0xad, 0x05, 0x11, 0xa1, 0x8f, 0x96, 0x53, 0xa5, 0xaf, 0xa8, 0x9a, 0xa9, 0x73, 0xfd, + 0xa4, 0xad, 0x01, 0xcc, 0x85, 0x36, 0x26, 0x8c, 0x5a, 0x55, 0xad, 0xc8, 0x53, 0xb0, 0x0d, 0xd6, + 0xd5, 0x81, 0xc2, 0x5a, 0x6b, 0x54, 0x9b, 0x66, 0xeb, 0x81, 0xa3, 0x71, 0xa1, 0x90, 0x38, 0x1f, + 0x93, 0x4a, 0xbe, 0xd9, 0x40, 0x4b, 0xe1, 0x07, 0xb0, 0x2d, 0xa2, 0x30, 0x64, 0x5c, 0xe2, 0xc5, + 0x54, 0x12, 0xcc, 0x85, 0x55, 0x6b, 0x54, 0x9b, 0xf5, 0xd6, 0xbe, 0x53, 0x06, 0xdb, 0x19, 0x62, + 0x1e, 0x93, 0x39, 0x1e, 0x11, 0xcc, 0x07, 0xf5, 0xac, 0x33, 0x09, 0xc5, 0xc1, 0x8f, 0x1a, 0xd8, + 0x2d, 0xe1, 0x51, 0x7a, 0x71, 0x19, 0x99, 0xeb, 0x14, 0xaa, 0xff, 0xa4, 0xb0, 0x76, 0x93, 0xc2, + 0x59, 0x46, 0xa1, 0xa6, 0x28, 0xbc, 0x28, 0xbf, 0xa3, 0x64, 0xcf, 0x94, 0x91, 0xe8, 0x52, 0xc9, + 0x97, 0x19, 0x9f, 0x0b, 0x60, 0x46, 0x02, 0xf3, 0xa9, 0xf6, 0xdc, 0x50, 0x9e, 0x87, 0xb7, 0xf7, + 0x1c, 0x0b, 0xcc, 0x8b, 0xbe, 0x20, 0xca, 0x12, 0x30, 0x00, 0xbb, 0x31, 0xe6, 0x59, 0xcb, 0x54, + 0x48, 0x24, 0x23, 0x61, 0x6d, 0x36, 0x8c, 0x66, 0xbd, 0xf5, 0xe6, 0xf6, 0x33, 0x26, 0x05, 0x93, + 0xa1, 0xf2, 0x18, 0xc0, 0xf8, 0x46, 0x0e, 0x3e, 0x07, 0x77, 0x31, 0x45, 0x33, 0x1f, 0x2f, 0x2c, + 0xb3, 0x61, 0x34, 0xcd, 0x96, 0xbd, 0x1a, 0xb1, 0xfa, 0xc0, 0x9d, 0x63, 0xc6, 0xfc, 0x09, 0xf2, + 0x23, 0x3c, 0x58, 0x49, 0xed, 0x43, 0x60, 0x16, 0xf6, 0x87, 0x3b, 0xa0, 0xfa, 0x15, 0x2f, 0xf5, + 0x4f, 0x99, 0x3c, 0xe1, 0x1e, 0xa8, 0xc5, 0x49, 0x8b, 0xfe, 0x68, 0xd3, 0xe0, 0x55, 0xe5, 0xa5, + 0x61, 0xbf, 0x05, 0xdb, 0xd7, 0xce, 0xff, 0x9f, 0xf6, 0x83, 0xcf, 0x00, 0xde, 0xbc, 0x0c, 0x3e, + 0x05, 0x4f, 0x26, 0xdd, 0x41, 0xef, 0xb4, 0xd7, 0x39, 0x1a, 0xf5, 0x3e, 0xf5, 0xa7, 0xc3, 0xd1, + 0xd1, 0x68, 0x3c, 0x9c, 0x8e, 0xfb, 0xc3, 0xf3, 0x6e, 0xa7, 0x77, 0xda, 0xeb, 0x9e, 0xec, 0xdc, + 0x81, 0x75, 0x00, 0xc6, 0xfd, 0x54, 0xd6, 0x3d, 0xd9, 0x31, 0xe0, 0x16, 0xd8, 0xc8, 0xa2, 0xca, + 0xf1, 0x4f, 0x03, 0x58, 0x73, 0x16, 0x94, 0x02, 0x3e, 0xbe, 0x57, 0x24, 0x7c, 0x9e, 0x80, 0x39, + 0x37, 0x2e, 0xde, 0x69, 0xa9, 0xc7, 0x7c, 0x44, 0x3d, 0x87, 0x71, 0xcf, 0xf5, 0x30, 0x55, 0xd8, + 0xdc, 0xb4, 0x84, 0x42, 0x22, 0xfe, 0xfe, 0x2f, 0x79, 0x9d, 0x47, 0xbf, 0x2a, 0xf6, 0xfb, 0xd4, + 0xa0, 0xe3, 0xb3, 0x68, 0xe1, 0x9c, 0xe5, 0x13, 0x27, 0xed, 0xdf, 0xab, 0xe2, 0xa5, 0x2a, 0x5e, + 0xe6, 0xc5, 0xcb, 0x49, 0x7b, 0xb6, 0xae, 0x86, 0xb4, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xdf, + 0xb9, 0x3f, 0x8b, 0x24, 0x05, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go new file mode 100644 index 0000000000..ea5cf925c9 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/notification_service.pb.go @@ -0,0 +1,1035 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/monitoring/v3/notification_service.proto + +package monitoring + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import google_protobuf5 "github.com/golang/protobuf/ptypes/empty" +import google_protobuf6 "google.golang.org/genproto/protobuf/field_mask" +import google_protobuf2 "github.com/golang/protobuf/ptypes/timestamp" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// The `ListNotificationChannelDescriptors` request. +type ListNotificationChannelDescriptorsRequest struct { + // The REST resource name of the parent from which to retrieve + // the notification channel descriptors. The expected syntax is: + // + // projects/[PROJECT_ID] + // + // Note that this names the parent container in which to look for the + // descriptors; to retrieve a single descriptor by name, use the + // [GetNotificationChannelDescriptor][google.monitoring.v3.NotificationChannelService.GetNotificationChannelDescriptor] + // operation, instead. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + // The maximum number of results to return in a single response. If + // not set to a positive number, a reasonable value will be chosen by the + // service. + PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize" json:"page_size,omitempty"` + // If non-empty, `page_token` must contain a value returned as the + // `next_page_token` in a previous response to request the next set + // of results. + PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken" json:"page_token,omitempty"` +} + +func (m *ListNotificationChannelDescriptorsRequest) Reset() { + *m = ListNotificationChannelDescriptorsRequest{} +} +func (m *ListNotificationChannelDescriptorsRequest) String() string { return proto.CompactTextString(m) } +func (*ListNotificationChannelDescriptorsRequest) ProtoMessage() {} +func (*ListNotificationChannelDescriptorsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{0} +} + +func (m *ListNotificationChannelDescriptorsRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ListNotificationChannelDescriptorsRequest) GetPageSize() int32 { + if m != nil { + return m.PageSize + } + return 0 +} + +func (m *ListNotificationChannelDescriptorsRequest) GetPageToken() string { + if m != nil { + return m.PageToken + } + return "" +} + +// The `ListNotificationChannelDescriptors` response. +type ListNotificationChannelDescriptorsResponse struct { + // The monitored resource descriptors supported for the specified + // project, optionally filtered. + ChannelDescriptors []*NotificationChannelDescriptor `protobuf:"bytes,1,rep,name=channel_descriptors,json=channelDescriptors" json:"channel_descriptors,omitempty"` + // If not empty, indicates that there may be more results that match + // the request. Use the value in the `page_token` field in a + // subsequent request to fetch the next set of results. If empty, + // all results have been returned. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (m *ListNotificationChannelDescriptorsResponse) Reset() { + *m = ListNotificationChannelDescriptorsResponse{} +} +func (m *ListNotificationChannelDescriptorsResponse) String() string { + return proto.CompactTextString(m) +} +func (*ListNotificationChannelDescriptorsResponse) ProtoMessage() {} +func (*ListNotificationChannelDescriptorsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{1} +} + +func (m *ListNotificationChannelDescriptorsResponse) GetChannelDescriptors() []*NotificationChannelDescriptor { + if m != nil { + return m.ChannelDescriptors + } + return nil +} + +func (m *ListNotificationChannelDescriptorsResponse) GetNextPageToken() string { + if m != nil { + return m.NextPageToken + } + return "" +} + +// The `GetNotificationChannelDescriptor` response. +type GetNotificationChannelDescriptorRequest struct { + // The channel type for which to execute the request. The format is + // `projects/[PROJECT_ID]/notificationChannelDescriptors/{channel_type}`. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *GetNotificationChannelDescriptorRequest) Reset() { + *m = GetNotificationChannelDescriptorRequest{} +} +func (m *GetNotificationChannelDescriptorRequest) String() string { return proto.CompactTextString(m) } +func (*GetNotificationChannelDescriptorRequest) ProtoMessage() {} +func (*GetNotificationChannelDescriptorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{2} +} + +func (m *GetNotificationChannelDescriptorRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The `CreateNotificationChannel` request. +type CreateNotificationChannelRequest struct { + // The project on which to execute the request. The format is: + // + // projects/[PROJECT_ID] + // + // Note that this names the container into which the channel will be + // written. This does not name the newly created channel. The resulting + // channel's name will have a normalized version of this field as a prefix, + // but will add `/notificationChannels/[CHANNEL_ID]` to identify the channel. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + // The definition of the `NotificationChannel` to create. + NotificationChannel *NotificationChannel `protobuf:"bytes,2,opt,name=notification_channel,json=notificationChannel" json:"notification_channel,omitempty"` +} + +func (m *CreateNotificationChannelRequest) Reset() { *m = CreateNotificationChannelRequest{} } +func (m *CreateNotificationChannelRequest) String() string { return proto.CompactTextString(m) } +func (*CreateNotificationChannelRequest) ProtoMessage() {} +func (*CreateNotificationChannelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{3} +} + +func (m *CreateNotificationChannelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreateNotificationChannelRequest) GetNotificationChannel() *NotificationChannel { + if m != nil { + return m.NotificationChannel + } + return nil +} + +// The `ListNotificationChannels` request. +type ListNotificationChannelsRequest struct { + // The project on which to execute the request. The format is + // `projects/[PROJECT_ID]`. That is, this names the container + // in which to look for the notification channels; it does not name a + // specific channel. To query a specific channel by REST resource name, use + // the + // [`GetNotificationChannel`][google.monitoring.v3.NotificationChannelService.GetNotificationChannel] operation. + Name string `protobuf:"bytes,5,opt,name=name" json:"name,omitempty"` + // If provided, this field specifies the criteria that must be met by + // notification channels to be included in the response. + // + // For more details, see [sorting and + // filtering](/monitoring/api/v3/sorting-and-filtering). + Filter string `protobuf:"bytes,6,opt,name=filter" json:"filter,omitempty"` + // A comma-separated list of fields by which to sort the result. Supports + // the same set of fields as in `filter`. Entries can be prefixed with + // a minus sign to sort in descending rather than ascending order. + // + // For more details, see [sorting and + // filtering](/monitoring/api/v3/sorting-and-filtering). + OrderBy string `protobuf:"bytes,7,opt,name=order_by,json=orderBy" json:"order_by,omitempty"` + // The maximum number of results to return in a single response. If + // not set to a positive number, a reasonable value will be chosen by the + // service. + PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize" json:"page_size,omitempty"` + // If non-empty, `page_token` must contain a value returned as the + // `next_page_token` in a previous response to request the next set + // of results. + PageToken string `protobuf:"bytes,4,opt,name=page_token,json=pageToken" json:"page_token,omitempty"` +} + +func (m *ListNotificationChannelsRequest) Reset() { *m = ListNotificationChannelsRequest{} } +func (m *ListNotificationChannelsRequest) String() string { return proto.CompactTextString(m) } +func (*ListNotificationChannelsRequest) ProtoMessage() {} +func (*ListNotificationChannelsRequest) Descriptor() ([]byte, []int) { return fileDescriptor9, []int{4} } + +func (m *ListNotificationChannelsRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ListNotificationChannelsRequest) GetFilter() string { + if m != nil { + return m.Filter + } + return "" +} + +func (m *ListNotificationChannelsRequest) GetOrderBy() string { + if m != nil { + return m.OrderBy + } + return "" +} + +func (m *ListNotificationChannelsRequest) GetPageSize() int32 { + if m != nil { + return m.PageSize + } + return 0 +} + +func (m *ListNotificationChannelsRequest) GetPageToken() string { + if m != nil { + return m.PageToken + } + return "" +} + +// The `ListNotificationChannels` response. +type ListNotificationChannelsResponse struct { + // The notification channels defined for the specified project. + NotificationChannels []*NotificationChannel `protobuf:"bytes,3,rep,name=notification_channels,json=notificationChannels" json:"notification_channels,omitempty"` + // If not empty, indicates that there may be more results that match + // the request. Use the value in the `page_token` field in a + // subsequent request to fetch the next set of results. If empty, + // all results have been returned. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (m *ListNotificationChannelsResponse) Reset() { *m = ListNotificationChannelsResponse{} } +func (m *ListNotificationChannelsResponse) String() string { return proto.CompactTextString(m) } +func (*ListNotificationChannelsResponse) ProtoMessage() {} +func (*ListNotificationChannelsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{5} +} + +func (m *ListNotificationChannelsResponse) GetNotificationChannels() []*NotificationChannel { + if m != nil { + return m.NotificationChannels + } + return nil +} + +func (m *ListNotificationChannelsResponse) GetNextPageToken() string { + if m != nil { + return m.NextPageToken + } + return "" +} + +// The `GetNotificationChannel` request. +type GetNotificationChannelRequest struct { + // The channel for which to execute the request. The format is + // `projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]`. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *GetNotificationChannelRequest) Reset() { *m = GetNotificationChannelRequest{} } +func (m *GetNotificationChannelRequest) String() string { return proto.CompactTextString(m) } +func (*GetNotificationChannelRequest) ProtoMessage() {} +func (*GetNotificationChannelRequest) Descriptor() ([]byte, []int) { return fileDescriptor9, []int{6} } + +func (m *GetNotificationChannelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The `UpdateNotificationChannel` request. +type UpdateNotificationChannelRequest struct { + // The fields to update. + UpdateMask *google_protobuf6.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` + // A description of the changes to be applied to the specified + // notification channel. The description must provide a definition for + // fields to be updated; the names of these fields should also be + // included in the `update_mask`. + NotificationChannel *NotificationChannel `protobuf:"bytes,3,opt,name=notification_channel,json=notificationChannel" json:"notification_channel,omitempty"` +} + +func (m *UpdateNotificationChannelRequest) Reset() { *m = UpdateNotificationChannelRequest{} } +func (m *UpdateNotificationChannelRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateNotificationChannelRequest) ProtoMessage() {} +func (*UpdateNotificationChannelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{7} +} + +func (m *UpdateNotificationChannelRequest) GetUpdateMask() *google_protobuf6.FieldMask { + if m != nil { + return m.UpdateMask + } + return nil +} + +func (m *UpdateNotificationChannelRequest) GetNotificationChannel() *NotificationChannel { + if m != nil { + return m.NotificationChannel + } + return nil +} + +// The `DeleteNotificationChannel` request. +type DeleteNotificationChannelRequest struct { + // The channel for which to execute the request. The format is + // `projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]`. + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + // If true, the notification channel will be deleted regardless of its + // use in alert policies (the policies will be updated to remove the + // channel). If false, channels that are still referenced by an existing + // alerting policy will fail to be deleted in a delete operation. + Force bool `protobuf:"varint,5,opt,name=force" json:"force,omitempty"` +} + +func (m *DeleteNotificationChannelRequest) Reset() { *m = DeleteNotificationChannelRequest{} } +func (m *DeleteNotificationChannelRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteNotificationChannelRequest) ProtoMessage() {} +func (*DeleteNotificationChannelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{8} +} + +func (m *DeleteNotificationChannelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *DeleteNotificationChannelRequest) GetForce() bool { + if m != nil { + return m.Force + } + return false +} + +// The `SendNotificationChannelVerificationCode` request. +type SendNotificationChannelVerificationCodeRequest struct { + // The notification channel to which to send a verification code. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *SendNotificationChannelVerificationCodeRequest) Reset() { + *m = SendNotificationChannelVerificationCodeRequest{} +} +func (m *SendNotificationChannelVerificationCodeRequest) String() string { + return proto.CompactTextString(m) +} +func (*SendNotificationChannelVerificationCodeRequest) ProtoMessage() {} +func (*SendNotificationChannelVerificationCodeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{9} +} + +func (m *SendNotificationChannelVerificationCodeRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The `GetNotificationChannelVerificationCode` request. +type GetNotificationChannelVerificationCodeRequest struct { + // The notification channel for which a verification code is to be generated + // and retrieved. This must name a channel that is already verified; if + // the specified channel is not verified, the request will fail. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The desired expiration time. If specified, the API will guarantee that + // the returned code will not be valid after the specified timestamp; + // however, the API cannot guarantee that the returned code will be + // valid for at least as long as the requested time (the API puts an upper + // bound on the amount of time for which a code may be valid). If omitted, + // a default expiration will be used, which may be less than the max + // permissible expiration (so specifying an expiration may extend the + // code's lifetime over omitting an expiration, even though the API does + // impose an upper limit on the maximum expiration that is permitted). + ExpireTime *google_protobuf2.Timestamp `protobuf:"bytes,2,opt,name=expire_time,json=expireTime" json:"expire_time,omitempty"` +} + +func (m *GetNotificationChannelVerificationCodeRequest) Reset() { + *m = GetNotificationChannelVerificationCodeRequest{} +} +func (m *GetNotificationChannelVerificationCodeRequest) String() string { + return proto.CompactTextString(m) +} +func (*GetNotificationChannelVerificationCodeRequest) ProtoMessage() {} +func (*GetNotificationChannelVerificationCodeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{10} +} + +func (m *GetNotificationChannelVerificationCodeRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *GetNotificationChannelVerificationCodeRequest) GetExpireTime() *google_protobuf2.Timestamp { + if m != nil { + return m.ExpireTime + } + return nil +} + +// The `GetNotificationChannelVerificationCode` request. +type GetNotificationChannelVerificationCodeResponse struct { + // The verification code, which may be used to verify other channels + // that have an equivalent identity (i.e. other channels of the same + // type with the same fingerprint such as other email channels with + // the same email address or other sms channels with the same number). + Code string `protobuf:"bytes,1,opt,name=code" json:"code,omitempty"` + // The expiration time associated with the code that was returned. If + // an expiration was provided in the request, this is the minimum of the + // requested expiration in the request and the max permitted expiration. + ExpireTime *google_protobuf2.Timestamp `protobuf:"bytes,2,opt,name=expire_time,json=expireTime" json:"expire_time,omitempty"` +} + +func (m *GetNotificationChannelVerificationCodeResponse) Reset() { + *m = GetNotificationChannelVerificationCodeResponse{} +} +func (m *GetNotificationChannelVerificationCodeResponse) String() string { + return proto.CompactTextString(m) +} +func (*GetNotificationChannelVerificationCodeResponse) ProtoMessage() {} +func (*GetNotificationChannelVerificationCodeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{11} +} + +func (m *GetNotificationChannelVerificationCodeResponse) GetCode() string { + if m != nil { + return m.Code + } + return "" +} + +func (m *GetNotificationChannelVerificationCodeResponse) GetExpireTime() *google_protobuf2.Timestamp { + if m != nil { + return m.ExpireTime + } + return nil +} + +// The `VerifyNotificationChannel` request. +type VerifyNotificationChannelRequest struct { + // The notification channel to verify. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The verification code that was delivered to the channel as + // a result of invoking the `SendNotificationChannelVerificationCode` API + // method or that was retrieved from a verified channel via + // `GetNotificationChannelVerificationCode`. For example, one might have + // "G-123456" or "TKNZGhhd2EyN3I1MnRnMjRv" (in general, one is only + // guaranteed that the code is valid UTF-8; one should not + // make any assumptions regarding the structure or format of the code). + Code string `protobuf:"bytes,2,opt,name=code" json:"code,omitempty"` +} + +func (m *VerifyNotificationChannelRequest) Reset() { *m = VerifyNotificationChannelRequest{} } +func (m *VerifyNotificationChannelRequest) String() string { return proto.CompactTextString(m) } +func (*VerifyNotificationChannelRequest) ProtoMessage() {} +func (*VerifyNotificationChannelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor9, []int{12} +} + +func (m *VerifyNotificationChannelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *VerifyNotificationChannelRequest) GetCode() string { + if m != nil { + return m.Code + } + return "" +} + +func init() { + proto.RegisterType((*ListNotificationChannelDescriptorsRequest)(nil), "google.monitoring.v3.ListNotificationChannelDescriptorsRequest") + proto.RegisterType((*ListNotificationChannelDescriptorsResponse)(nil), "google.monitoring.v3.ListNotificationChannelDescriptorsResponse") + proto.RegisterType((*GetNotificationChannelDescriptorRequest)(nil), "google.monitoring.v3.GetNotificationChannelDescriptorRequest") + proto.RegisterType((*CreateNotificationChannelRequest)(nil), "google.monitoring.v3.CreateNotificationChannelRequest") + proto.RegisterType((*ListNotificationChannelsRequest)(nil), "google.monitoring.v3.ListNotificationChannelsRequest") + proto.RegisterType((*ListNotificationChannelsResponse)(nil), "google.monitoring.v3.ListNotificationChannelsResponse") + proto.RegisterType((*GetNotificationChannelRequest)(nil), "google.monitoring.v3.GetNotificationChannelRequest") + proto.RegisterType((*UpdateNotificationChannelRequest)(nil), "google.monitoring.v3.UpdateNotificationChannelRequest") + proto.RegisterType((*DeleteNotificationChannelRequest)(nil), "google.monitoring.v3.DeleteNotificationChannelRequest") + proto.RegisterType((*SendNotificationChannelVerificationCodeRequest)(nil), "google.monitoring.v3.SendNotificationChannelVerificationCodeRequest") + proto.RegisterType((*GetNotificationChannelVerificationCodeRequest)(nil), "google.monitoring.v3.GetNotificationChannelVerificationCodeRequest") + proto.RegisterType((*GetNotificationChannelVerificationCodeResponse)(nil), "google.monitoring.v3.GetNotificationChannelVerificationCodeResponse") + proto.RegisterType((*VerifyNotificationChannelRequest)(nil), "google.monitoring.v3.VerifyNotificationChannelRequest") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for NotificationChannelService service + +type NotificationChannelServiceClient interface { + // Lists the descriptors for supported channel types. The use of descriptors + // makes it possible for new channel types to be dynamically added. + ListNotificationChannelDescriptors(ctx context.Context, in *ListNotificationChannelDescriptorsRequest, opts ...grpc.CallOption) (*ListNotificationChannelDescriptorsResponse, error) + // Gets a single channel descriptor. The descriptor indicates which fields + // are expected / permitted for a notification channel of the given type. + GetNotificationChannelDescriptor(ctx context.Context, in *GetNotificationChannelDescriptorRequest, opts ...grpc.CallOption) (*NotificationChannelDescriptor, error) + // Lists the notification channels that have been created for the project. + ListNotificationChannels(ctx context.Context, in *ListNotificationChannelsRequest, opts ...grpc.CallOption) (*ListNotificationChannelsResponse, error) + // Gets a single notification channel. The channel includes the relevant + // configuration details with which the channel was created. However, the + // response may truncate or omit passwords, API keys, or other private key + // matter and thus the response may not be 100% identical to the information + // that was supplied in the call to the create method. + GetNotificationChannel(ctx context.Context, in *GetNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) + // Creates a new notification channel, representing a single notification + // endpoint such as an email address, SMS number, or pagerduty service. + CreateNotificationChannel(ctx context.Context, in *CreateNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) + // Updates a notification channel. Fields not specified in the field mask + // remain unchanged. + UpdateNotificationChannel(ctx context.Context, in *UpdateNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) + // Deletes a notification channel. + DeleteNotificationChannel(ctx context.Context, in *DeleteNotificationChannelRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) + // Causes a verification code to be delivered to the channel. The code + // can then be supplied in `VerifyNotificationChannel` to verify the channel. + SendNotificationChannelVerificationCode(ctx context.Context, in *SendNotificationChannelVerificationCodeRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) + // Requests a verification code for an already verified channel that can then + // be used in a call to VerifyNotificationChannel() on a different channel + // with an equivalent identity in the same or in a different project. This + // makes it possible to copy a channel between projects without requiring + // manual reverification of the channel. If the channel is not in the + // verified state, this method will fail (in other words, this may only be + // used if the SendNotificationChannelVerificationCode and + // VerifyNotificationChannel paths have already been used to put the given + // channel into the verified state). + // + // There is no guarantee that the verification codes returned by this method + // will be of a similar structure or form as the ones that are delivered + // to the channel via SendNotificationChannelVerificationCode; while + // VerifyNotificationChannel() will recognize both the codes delivered via + // SendNotificationChannelVerificationCode() and returned from + // GetNotificationChannelVerificationCode(), it is typically the case that + // the verification codes delivered via + // SendNotificationChannelVerificationCode() will be shorter and also + // have a shorter expiration (e.g. codes such as "G-123456") whereas + // GetVerificationCode() will typically return a much longer, websafe base + // 64 encoded string that has a longer expiration time. + GetNotificationChannelVerificationCode(ctx context.Context, in *GetNotificationChannelVerificationCodeRequest, opts ...grpc.CallOption) (*GetNotificationChannelVerificationCodeResponse, error) + // Verifies a `NotificationChannel` by proving receipt of the code + // delivered to the channel as a result of calling + // `SendNotificationChannelVerificationCode`. + VerifyNotificationChannel(ctx context.Context, in *VerifyNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) +} + +type notificationChannelServiceClient struct { + cc *grpc.ClientConn +} + +func NewNotificationChannelServiceClient(cc *grpc.ClientConn) NotificationChannelServiceClient { + return ¬ificationChannelServiceClient{cc} +} + +func (c *notificationChannelServiceClient) ListNotificationChannelDescriptors(ctx context.Context, in *ListNotificationChannelDescriptorsRequest, opts ...grpc.CallOption) (*ListNotificationChannelDescriptorsResponse, error) { + out := new(ListNotificationChannelDescriptorsResponse) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/ListNotificationChannelDescriptors", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) GetNotificationChannelDescriptor(ctx context.Context, in *GetNotificationChannelDescriptorRequest, opts ...grpc.CallOption) (*NotificationChannelDescriptor, error) { + out := new(NotificationChannelDescriptor) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/GetNotificationChannelDescriptor", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) ListNotificationChannels(ctx context.Context, in *ListNotificationChannelsRequest, opts ...grpc.CallOption) (*ListNotificationChannelsResponse, error) { + out := new(ListNotificationChannelsResponse) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/ListNotificationChannels", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) GetNotificationChannel(ctx context.Context, in *GetNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) { + out := new(NotificationChannel) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/GetNotificationChannel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) CreateNotificationChannel(ctx context.Context, in *CreateNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) { + out := new(NotificationChannel) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/CreateNotificationChannel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) UpdateNotificationChannel(ctx context.Context, in *UpdateNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) { + out := new(NotificationChannel) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/UpdateNotificationChannel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) DeleteNotificationChannel(ctx context.Context, in *DeleteNotificationChannelRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/DeleteNotificationChannel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) SendNotificationChannelVerificationCode(ctx context.Context, in *SendNotificationChannelVerificationCodeRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/SendNotificationChannelVerificationCode", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) GetNotificationChannelVerificationCode(ctx context.Context, in *GetNotificationChannelVerificationCodeRequest, opts ...grpc.CallOption) (*GetNotificationChannelVerificationCodeResponse, error) { + out := new(GetNotificationChannelVerificationCodeResponse) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/GetNotificationChannelVerificationCode", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *notificationChannelServiceClient) VerifyNotificationChannel(ctx context.Context, in *VerifyNotificationChannelRequest, opts ...grpc.CallOption) (*NotificationChannel, error) { + out := new(NotificationChannel) + err := grpc.Invoke(ctx, "/google.monitoring.v3.NotificationChannelService/VerifyNotificationChannel", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for NotificationChannelService service + +type NotificationChannelServiceServer interface { + // Lists the descriptors for supported channel types. The use of descriptors + // makes it possible for new channel types to be dynamically added. + ListNotificationChannelDescriptors(context.Context, *ListNotificationChannelDescriptorsRequest) (*ListNotificationChannelDescriptorsResponse, error) + // Gets a single channel descriptor. The descriptor indicates which fields + // are expected / permitted for a notification channel of the given type. + GetNotificationChannelDescriptor(context.Context, *GetNotificationChannelDescriptorRequest) (*NotificationChannelDescriptor, error) + // Lists the notification channels that have been created for the project. + ListNotificationChannels(context.Context, *ListNotificationChannelsRequest) (*ListNotificationChannelsResponse, error) + // Gets a single notification channel. The channel includes the relevant + // configuration details with which the channel was created. However, the + // response may truncate or omit passwords, API keys, or other private key + // matter and thus the response may not be 100% identical to the information + // that was supplied in the call to the create method. + GetNotificationChannel(context.Context, *GetNotificationChannelRequest) (*NotificationChannel, error) + // Creates a new notification channel, representing a single notification + // endpoint such as an email address, SMS number, or pagerduty service. + CreateNotificationChannel(context.Context, *CreateNotificationChannelRequest) (*NotificationChannel, error) + // Updates a notification channel. Fields not specified in the field mask + // remain unchanged. + UpdateNotificationChannel(context.Context, *UpdateNotificationChannelRequest) (*NotificationChannel, error) + // Deletes a notification channel. + DeleteNotificationChannel(context.Context, *DeleteNotificationChannelRequest) (*google_protobuf5.Empty, error) + // Causes a verification code to be delivered to the channel. The code + // can then be supplied in `VerifyNotificationChannel` to verify the channel. + SendNotificationChannelVerificationCode(context.Context, *SendNotificationChannelVerificationCodeRequest) (*google_protobuf5.Empty, error) + // Requests a verification code for an already verified channel that can then + // be used in a call to VerifyNotificationChannel() on a different channel + // with an equivalent identity in the same or in a different project. This + // makes it possible to copy a channel between projects without requiring + // manual reverification of the channel. If the channel is not in the + // verified state, this method will fail (in other words, this may only be + // used if the SendNotificationChannelVerificationCode and + // VerifyNotificationChannel paths have already been used to put the given + // channel into the verified state). + // + // There is no guarantee that the verification codes returned by this method + // will be of a similar structure or form as the ones that are delivered + // to the channel via SendNotificationChannelVerificationCode; while + // VerifyNotificationChannel() will recognize both the codes delivered via + // SendNotificationChannelVerificationCode() and returned from + // GetNotificationChannelVerificationCode(), it is typically the case that + // the verification codes delivered via + // SendNotificationChannelVerificationCode() will be shorter and also + // have a shorter expiration (e.g. codes such as "G-123456") whereas + // GetVerificationCode() will typically return a much longer, websafe base + // 64 encoded string that has a longer expiration time. + GetNotificationChannelVerificationCode(context.Context, *GetNotificationChannelVerificationCodeRequest) (*GetNotificationChannelVerificationCodeResponse, error) + // Verifies a `NotificationChannel` by proving receipt of the code + // delivered to the channel as a result of calling + // `SendNotificationChannelVerificationCode`. + VerifyNotificationChannel(context.Context, *VerifyNotificationChannelRequest) (*NotificationChannel, error) +} + +func RegisterNotificationChannelServiceServer(s *grpc.Server, srv NotificationChannelServiceServer) { + s.RegisterService(&_NotificationChannelService_serviceDesc, srv) +} + +func _NotificationChannelService_ListNotificationChannelDescriptors_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListNotificationChannelDescriptorsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).ListNotificationChannelDescriptors(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/ListNotificationChannelDescriptors", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).ListNotificationChannelDescriptors(ctx, req.(*ListNotificationChannelDescriptorsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_GetNotificationChannelDescriptor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNotificationChannelDescriptorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).GetNotificationChannelDescriptor(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/GetNotificationChannelDescriptor", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).GetNotificationChannelDescriptor(ctx, req.(*GetNotificationChannelDescriptorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_ListNotificationChannels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListNotificationChannelsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).ListNotificationChannels(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/ListNotificationChannels", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).ListNotificationChannels(ctx, req.(*ListNotificationChannelsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_GetNotificationChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNotificationChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).GetNotificationChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/GetNotificationChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).GetNotificationChannel(ctx, req.(*GetNotificationChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_CreateNotificationChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateNotificationChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).CreateNotificationChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/CreateNotificationChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).CreateNotificationChannel(ctx, req.(*CreateNotificationChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_UpdateNotificationChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateNotificationChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).UpdateNotificationChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/UpdateNotificationChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).UpdateNotificationChannel(ctx, req.(*UpdateNotificationChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_DeleteNotificationChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteNotificationChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).DeleteNotificationChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/DeleteNotificationChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).DeleteNotificationChannel(ctx, req.(*DeleteNotificationChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_SendNotificationChannelVerificationCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendNotificationChannelVerificationCodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).SendNotificationChannelVerificationCode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/SendNotificationChannelVerificationCode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).SendNotificationChannelVerificationCode(ctx, req.(*SendNotificationChannelVerificationCodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_GetNotificationChannelVerificationCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNotificationChannelVerificationCodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).GetNotificationChannelVerificationCode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/GetNotificationChannelVerificationCode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).GetNotificationChannelVerificationCode(ctx, req.(*GetNotificationChannelVerificationCodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NotificationChannelService_VerifyNotificationChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyNotificationChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NotificationChannelServiceServer).VerifyNotificationChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.monitoring.v3.NotificationChannelService/VerifyNotificationChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NotificationChannelServiceServer).VerifyNotificationChannel(ctx, req.(*VerifyNotificationChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _NotificationChannelService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.monitoring.v3.NotificationChannelService", + HandlerType: (*NotificationChannelServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListNotificationChannelDescriptors", + Handler: _NotificationChannelService_ListNotificationChannelDescriptors_Handler, + }, + { + MethodName: "GetNotificationChannelDescriptor", + Handler: _NotificationChannelService_GetNotificationChannelDescriptor_Handler, + }, + { + MethodName: "ListNotificationChannels", + Handler: _NotificationChannelService_ListNotificationChannels_Handler, + }, + { + MethodName: "GetNotificationChannel", + Handler: _NotificationChannelService_GetNotificationChannel_Handler, + }, + { + MethodName: "CreateNotificationChannel", + Handler: _NotificationChannelService_CreateNotificationChannel_Handler, + }, + { + MethodName: "UpdateNotificationChannel", + Handler: _NotificationChannelService_UpdateNotificationChannel_Handler, + }, + { + MethodName: "DeleteNotificationChannel", + Handler: _NotificationChannelService_DeleteNotificationChannel_Handler, + }, + { + MethodName: "SendNotificationChannelVerificationCode", + Handler: _NotificationChannelService_SendNotificationChannelVerificationCode_Handler, + }, + { + MethodName: "GetNotificationChannelVerificationCode", + Handler: _NotificationChannelService_GetNotificationChannelVerificationCode_Handler, + }, + { + MethodName: "VerifyNotificationChannel", + Handler: _NotificationChannelService_VerifyNotificationChannel_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "google/monitoring/v3/notification_service.proto", +} + +func init() { proto.RegisterFile("google/monitoring/v3/notification_service.proto", fileDescriptor9) } + +var fileDescriptor9 = []byte{ + // 1011 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x41, 0x6f, 0xdc, 0x44, + 0x14, 0xd6, 0xec, 0x26, 0x69, 0xfa, 0x22, 0x04, 0x9a, 0x86, 0xc8, 0xbb, 0xa5, 0xaa, 0xe5, 0x43, + 0x93, 0xae, 0x8a, 0x2d, 0xad, 0x4b, 0x84, 0x52, 0x52, 0xda, 0x64, 0xdb, 0x22, 0x48, 0x51, 0xb4, + 0x29, 0x91, 0x40, 0x11, 0x2b, 0xc7, 0x7e, 0x6b, 0x4c, 0x76, 0x67, 0x8c, 0x3d, 0x89, 0x9a, 0x56, + 0x95, 0x0a, 0x7f, 0x01, 0xfe, 0x00, 0x12, 0xa7, 0x1e, 0x10, 0x67, 0x50, 0x39, 0x23, 0xae, 0x08, + 0xae, 0x5c, 0xe0, 0x7f, 0x20, 0x8f, 0xbd, 0xd9, 0xcd, 0x66, 0xbc, 0x6b, 0x37, 0xdc, 0x3c, 0xf3, + 0xde, 0xbc, 0xf7, 0xbd, 0xef, 0x7d, 0x9e, 0x67, 0x83, 0xe5, 0x73, 0xee, 0xf7, 0xd0, 0xea, 0x73, + 0x16, 0x08, 0x1e, 0x05, 0xcc, 0xb7, 0x8e, 0x6c, 0x8b, 0x71, 0x11, 0x74, 0x03, 0xd7, 0x11, 0x01, + 0x67, 0x9d, 0x18, 0xa3, 0xa3, 0xc0, 0x45, 0x33, 0x8c, 0xb8, 0xe0, 0x74, 0x31, 0x3d, 0x60, 0x0e, + 0x0f, 0x98, 0x47, 0x76, 0xfd, 0xad, 0x2c, 0x8c, 0x13, 0x06, 0x96, 0xc3, 0x18, 0x17, 0xf2, 0x68, + 0x9c, 0x9e, 0xa9, 0x2f, 0x4f, 0x4d, 0x92, 0x39, 0x5e, 0xce, 0x1c, 0xe5, 0x6a, 0xff, 0xb0, 0x6b, + 0x61, 0x3f, 0x14, 0xc7, 0x99, 0x51, 0x1f, 0x37, 0x76, 0x03, 0xec, 0x79, 0x9d, 0xbe, 0x13, 0x1f, + 0x64, 0x1e, 0x57, 0xc7, 0x3d, 0x44, 0xd0, 0xc7, 0x58, 0x38, 0xfd, 0x30, 0x75, 0x30, 0x9e, 0xc2, + 0xf5, 0xad, 0x20, 0x16, 0x1f, 0x8f, 0x64, 0xde, 0xfc, 0xc2, 0x61, 0x0c, 0x7b, 0x2d, 0x8c, 0xdd, + 0x28, 0x08, 0x05, 0x8f, 0xe2, 0x36, 0x7e, 0x75, 0x88, 0xb1, 0xa0, 0x14, 0x66, 0x98, 0xd3, 0x47, + 0x6d, 0x46, 0x27, 0x2b, 0x17, 0xdb, 0xf2, 0x99, 0x5e, 0x86, 0x8b, 0xa1, 0xe3, 0x63, 0x27, 0x0e, + 0x9e, 0xa0, 0x56, 0xd1, 0xc9, 0xca, 0x6c, 0x7b, 0x3e, 0xd9, 0xd8, 0x09, 0x9e, 0x20, 0xbd, 0x02, + 0x20, 0x8d, 0x82, 0x1f, 0x20, 0xd3, 0xaa, 0xf2, 0x98, 0x74, 0x7f, 0x94, 0x6c, 0x18, 0x3f, 0x13, + 0x68, 0x14, 0xc9, 0x1e, 0x87, 0x9c, 0xc5, 0x48, 0x3d, 0xb8, 0xe4, 0xa6, 0xd6, 0x8e, 0x37, 0x34, + 0x6b, 0x44, 0xaf, 0xae, 0x2c, 0x34, 0x6d, 0x53, 0xd5, 0x06, 0x73, 0x62, 0xe8, 0x36, 0x75, 0xcf, + 0x64, 0xa3, 0xd7, 0xe0, 0x75, 0x86, 0x8f, 0x45, 0x67, 0x04, 0x78, 0x45, 0x02, 0x7f, 0x2d, 0xd9, + 0xde, 0x3e, 0x01, 0xbf, 0x0e, 0xcb, 0x0f, 0x70, 0x32, 0xf4, 0x71, 0xde, 0xaa, 0x43, 0xde, 0x8c, + 0xef, 0x08, 0xe8, 0x9b, 0x11, 0x3a, 0x02, 0x15, 0x21, 0x26, 0x1c, 0xa4, 0x7b, 0xb0, 0x78, 0x4a, + 0x8c, 0x59, 0x09, 0x12, 0xe4, 0x42, 0xf3, 0x7a, 0x61, 0x1a, 0xda, 0x97, 0xd8, 0xd9, 0x4d, 0xe3, + 0x07, 0x02, 0x57, 0x73, 0x5a, 0x72, 0x46, 0x06, 0xb3, 0x23, 0xa8, 0x96, 0x60, 0xae, 0x1b, 0xf4, + 0x04, 0x46, 0xda, 0x9c, 0xdc, 0xcd, 0x56, 0xb4, 0x06, 0xf3, 0x3c, 0xf2, 0x30, 0xea, 0xec, 0x1f, + 0x6b, 0x17, 0xa4, 0xe5, 0x82, 0x5c, 0x6f, 0x1c, 0x9f, 0x56, 0x4e, 0x75, 0xa2, 0x72, 0x66, 0xc6, + 0x95, 0xf3, 0x82, 0x80, 0x9e, 0x0f, 0x33, 0xd3, 0xcb, 0xe7, 0xf0, 0xa6, 0x8a, 0xa9, 0x58, 0xab, + 0x4a, 0xc5, 0x94, 0xa0, 0x6a, 0x51, 0x41, 0x55, 0x71, 0xa5, 0xd8, 0x70, 0x45, 0xad, 0x94, 0x49, + 0xfa, 0x78, 0x49, 0x40, 0xff, 0x24, 0xf4, 0x26, 0xeb, 0xe3, 0x16, 0x2c, 0x1c, 0x4a, 0x1f, 0xf9, + 0xce, 0x67, 0x12, 0xa8, 0x0f, 0xea, 0x1a, 0xbc, 0xf4, 0xe6, 0xfd, 0xe4, 0x5a, 0x78, 0xe8, 0xc4, + 0x07, 0x6d, 0x48, 0xdd, 0x93, 0xe7, 0x5c, 0x21, 0x55, 0xff, 0x17, 0x21, 0x6d, 0x81, 0xde, 0xc2, + 0x1e, 0x96, 0x96, 0xf7, 0x22, 0xcc, 0x76, 0x79, 0xe4, 0xa6, 0xea, 0x9a, 0x6f, 0xa7, 0x0b, 0xa3, + 0x05, 0xe6, 0x0e, 0x32, 0x4f, 0x11, 0x6b, 0x17, 0xa3, 0xe1, 0x16, 0xf7, 0x70, 0x3c, 0x36, 0x19, + 0xe1, 0xf4, 0x39, 0x81, 0xb7, 0xd5, 0x9d, 0x28, 0x11, 0x25, 0x21, 0x1d, 0x1f, 0x87, 0x41, 0x84, + 0x9d, 0xe4, 0x32, 0xcd, 0x25, 0xfd, 0xd1, 0xe0, 0xa6, 0x6d, 0x43, 0xea, 0x9e, 0x6c, 0x18, 0x5f, + 0x13, 0x30, 0x8b, 0x42, 0xc8, 0x64, 0x4c, 0x61, 0xc6, 0xe5, 0xde, 0x09, 0x86, 0xe4, 0xf9, 0x7c, + 0x18, 0x3e, 0x04, 0x5d, 0x26, 0x3b, 0x2e, 0xd0, 0x9a, 0xd1, 0xc2, 0x07, 0x40, 0x2a, 0x43, 0x20, + 0xcd, 0x5f, 0xde, 0x80, 0xba, 0x22, 0xcc, 0x4e, 0x3a, 0x21, 0xe9, 0xbf, 0x04, 0x8c, 0xe9, 0x37, + 0x3c, 0x7d, 0x5f, 0x2d, 0xb6, 0xc2, 0x93, 0xa9, 0x7e, 0xe7, 0xd5, 0x03, 0xa4, 0x2c, 0x1b, 0xef, + 0x7d, 0xf3, 0xc7, 0x3f, 0xdf, 0x56, 0x56, 0xe9, 0xcd, 0x64, 0x10, 0x3f, 0x4d, 0xea, 0x5d, 0x0f, + 0x23, 0xfe, 0x25, 0xba, 0x22, 0xb6, 0x1a, 0xcf, 0x2c, 0x36, 0xb9, 0x80, 0xbf, 0x08, 0xe8, 0xd3, + 0xa6, 0x01, 0x5d, 0x57, 0x83, 0x2c, 0x38, 0x45, 0xea, 0xaf, 0x32, 0xe1, 0x8c, 0xdb, 0xb2, 0xac, + 0x77, 0xe9, 0xaa, 0xaa, 0xac, 0x29, 0x55, 0x59, 0x8d, 0x67, 0xf4, 0x25, 0x01, 0x2d, 0xef, 0xa2, + 0xa5, 0xef, 0x94, 0x62, 0xfd, 0xa4, 0x59, 0xab, 0x65, 0x8f, 0x65, 0x2d, 0x6a, 0xca, 0x5a, 0x6e, + 0xd0, 0x46, 0xe1, 0x16, 0xc5, 0xf4, 0x47, 0x02, 0x4b, 0x6a, 0x82, 0xa9, 0x5d, 0xa6, 0x1d, 0x03, + 0xec, 0xc5, 0xaf, 0x45, 0xe3, 0xa6, 0x84, 0x6b, 0xd2, 0x1b, 0x45, 0xa9, 0x97, 0x84, 0xff, 0x46, + 0xa0, 0x96, 0xfb, 0x5d, 0x40, 0x73, 0xa8, 0x9b, 0xf6, 0x21, 0x51, 0x06, 0xf6, 0x07, 0x12, 0xf6, + 0x86, 0x51, 0x82, 0xe5, 0x35, 0xe5, 0x20, 0xa1, 0x7f, 0x13, 0xa8, 0xe5, 0x8e, 0xb0, 0xbc, 0x52, + 0xa6, 0xcd, 0xbc, 0x32, 0xa5, 0x74, 0x64, 0x29, 0x9f, 0x36, 0xef, 0xa6, 0xa5, 0x28, 0x30, 0x9a, + 0x05, 0xdb, 0x92, 0x53, 0xe1, 0xf7, 0x04, 0x6a, 0xb9, 0x53, 0x2e, 0xaf, 0xc2, 0x69, 0x63, 0xb1, + 0xbe, 0x74, 0xe6, 0x1e, 0xbf, 0x97, 0x7c, 0xf4, 0x0f, 0x04, 0xd5, 0x28, 0x27, 0xa8, 0x3f, 0x09, + 0x2c, 0x17, 0x9c, 0x9d, 0xb4, 0xa5, 0x46, 0x5c, 0x6e, 0xf4, 0xe6, 0xe2, 0xdf, 0x92, 0xf8, 0xef, + 0x1b, 0x77, 0xcb, 0xe0, 0x5f, 0x8b, 0x91, 0x79, 0xe3, 0x99, 0xd6, 0x48, 0x83, 0x3e, 0xaf, 0xc0, + 0xb5, 0x62, 0x93, 0x94, 0x6e, 0x96, 0x79, 0xd3, 0xf3, 0xaa, 0x6a, 0x9d, 0x2f, 0x48, 0x76, 0x87, + 0x7d, 0x24, 0x39, 0xb8, 0x67, 0xdc, 0x29, 0xc5, 0x81, 0x8f, 0x42, 0x45, 0xc1, 0xaf, 0x04, 0x6a, + 0xb9, 0x93, 0x3c, 0x4f, 0x7e, 0xd3, 0x46, 0x7f, 0x99, 0x17, 0x2c, 0x9b, 0x2e, 0x86, 0x5d, 0xaa, + 0x9a, 0x23, 0x89, 0x60, 0x8d, 0x34, 0x36, 0x7e, 0x22, 0xa0, 0xb9, 0xbc, 0xaf, 0x4c, 0xb8, 0xa1, + 0x8d, 0x66, 0xcc, 0x3e, 0x28, 0xb6, 0x13, 0x45, 0x6d, 0x93, 0xcf, 0x6e, 0x67, 0x27, 0x7c, 0xde, + 0x73, 0x98, 0x6f, 0xf2, 0xc8, 0xb7, 0x7c, 0x64, 0x52, 0x6f, 0xd9, 0xff, 0xbb, 0x13, 0x06, 0xf1, + 0xe9, 0xdf, 0xeb, 0x5b, 0xc3, 0xd5, 0x8b, 0x4a, 0xfd, 0x41, 0x1a, 0x60, 0xb3, 0xc7, 0x0f, 0x3d, + 0xf3, 0xe1, 0x30, 0xf1, 0xae, 0xfd, 0xfb, 0xc0, 0xb8, 0x27, 0x8d, 0x7b, 0x43, 0xe3, 0xde, 0xae, + 0xbd, 0x3f, 0x27, 0x93, 0xd8, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xf3, 0x96, 0xf5, 0x27, + 0x10, 0x00, 0x00, +} diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime.pb.go index 042cddd042..9357d352af 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime.pb.go @@ -51,7 +51,7 @@ var UptimeCheckRegion_value = map[string]int32{ func (x UptimeCheckRegion) String() string { return proto.EnumName(UptimeCheckRegion_name, int32(x)) } -func (UptimeCheckRegion) EnumDescriptor() ([]byte, []int) { return fileDescriptor5, []int{0} } +func (UptimeCheckRegion) EnumDescriptor() ([]byte, []int) { return fileDescriptor10, []int{0} } // The supported resource types that can be used as values of // group_resource.resource_type. gae_app and uptime_url are not allowed @@ -81,7 +81,7 @@ var GroupResourceType_value = map[string]int32{ func (x GroupResourceType) String() string { return proto.EnumName(GroupResourceType_name, int32(x)) } -func (GroupResourceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor5, []int{1} } +func (GroupResourceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor10, []int{1} } // This message configures which resources and services to monitor for // availability. @@ -136,7 +136,7 @@ type UptimeCheckConfig struct { func (m *UptimeCheckConfig) Reset() { *m = UptimeCheckConfig{} } func (m *UptimeCheckConfig) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig) ProtoMessage() {} -func (*UptimeCheckConfig) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} } +func (*UptimeCheckConfig) Descriptor() ([]byte, []int) { return fileDescriptor10, []int{0} } type isUptimeCheckConfig_Resource interface { isUptimeCheckConfig_Resource() @@ -391,7 +391,7 @@ func (m *UptimeCheckConfig_ResourceGroup) Reset() { *m = UptimeCheckConf func (m *UptimeCheckConfig_ResourceGroup) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig_ResourceGroup) ProtoMessage() {} func (*UptimeCheckConfig_ResourceGroup) Descriptor() ([]byte, []int) { - return fileDescriptor5, []int{0, 0} + return fileDescriptor10, []int{0, 0} } func (m *UptimeCheckConfig_ResourceGroup) GetGroupId() string { @@ -443,7 +443,7 @@ type UptimeCheckConfig_HttpCheck struct { func (m *UptimeCheckConfig_HttpCheck) Reset() { *m = UptimeCheckConfig_HttpCheck{} } func (m *UptimeCheckConfig_HttpCheck) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig_HttpCheck) ProtoMessage() {} -func (*UptimeCheckConfig_HttpCheck) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0, 1} } +func (*UptimeCheckConfig_HttpCheck) Descriptor() ([]byte, []int) { return fileDescriptor10, []int{0, 1} } func (m *UptimeCheckConfig_HttpCheck) GetUseSsl() bool { if m != nil { @@ -505,7 +505,7 @@ func (m *UptimeCheckConfig_HttpCheck_BasicAuthentication) String() string { } func (*UptimeCheckConfig_HttpCheck_BasicAuthentication) ProtoMessage() {} func (*UptimeCheckConfig_HttpCheck_BasicAuthentication) Descriptor() ([]byte, []int) { - return fileDescriptor5, []int{0, 1, 0} + return fileDescriptor10, []int{0, 1, 0} } func (m *UptimeCheckConfig_HttpCheck_BasicAuthentication) GetUsername() string { @@ -533,7 +533,7 @@ type UptimeCheckConfig_TcpCheck struct { func (m *UptimeCheckConfig_TcpCheck) Reset() { *m = UptimeCheckConfig_TcpCheck{} } func (m *UptimeCheckConfig_TcpCheck) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig_TcpCheck) ProtoMessage() {} -func (*UptimeCheckConfig_TcpCheck) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0, 2} } +func (*UptimeCheckConfig_TcpCheck) Descriptor() ([]byte, []int) { return fileDescriptor10, []int{0, 2} } func (m *UptimeCheckConfig_TcpCheck) GetPort() int32 { if m != nil { @@ -554,7 +554,7 @@ func (m *UptimeCheckConfig_ContentMatcher) Reset() { *m = UptimeCheckCon func (m *UptimeCheckConfig_ContentMatcher) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig_ContentMatcher) ProtoMessage() {} func (*UptimeCheckConfig_ContentMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor5, []int{0, 3} + return fileDescriptor10, []int{0, 3} } func (m *UptimeCheckConfig_ContentMatcher) GetContent() string { @@ -583,7 +583,7 @@ func (m *UptimeCheckConfig_InternalChecker) Reset() { *m = UptimeCheckCo func (m *UptimeCheckConfig_InternalChecker) String() string { return proto.CompactTextString(m) } func (*UptimeCheckConfig_InternalChecker) ProtoMessage() {} func (*UptimeCheckConfig_InternalChecker) Descriptor() ([]byte, []int) { - return fileDescriptor5, []int{0, 4} + return fileDescriptor10, []int{0, 4} } func (m *UptimeCheckConfig_InternalChecker) GetProjectId() string { @@ -641,7 +641,7 @@ type UptimeCheckIp struct { func (m *UptimeCheckIp) Reset() { *m = UptimeCheckIp{} } func (m *UptimeCheckIp) String() string { return proto.CompactTextString(m) } func (*UptimeCheckIp) ProtoMessage() {} -func (*UptimeCheckIp) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{1} } +func (*UptimeCheckIp) Descriptor() ([]byte, []int) { return fileDescriptor10, []int{1} } func (m *UptimeCheckIp) GetRegion() UptimeCheckRegion { if m != nil { @@ -677,9 +677,9 @@ func init() { proto.RegisterEnum("google.monitoring.v3.GroupResourceType", GroupResourceType_name, GroupResourceType_value) } -func init() { proto.RegisterFile("google/monitoring/v3/uptime.proto", fileDescriptor5) } +func init() { proto.RegisterFile("google/monitoring/v3/uptime.proto", fileDescriptor10) } -var fileDescriptor5 = []byte{ +var fileDescriptor10 = []byte{ // 1021 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x4e, 0xe3, 0x46, 0x14, 0x5e, 0x13, 0xc8, 0xcf, 0x21, 0xb0, 0x66, 0x4a, 0xdb, 0x60, 0x89, 0x15, 0xbb, 0xbd, 0x28, diff --git a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go index 5e2fb2a7c6..a2ee162d59 100644 --- a/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/monitoring/v3/uptime_service.pb.go @@ -7,8 +7,8 @@ import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" import _ "google.golang.org/genproto/googleapis/api/annotations" -import google_protobuf4 "github.com/golang/protobuf/ptypes/empty" -import google_protobuf5 "google.golang.org/genproto/protobuf/field_mask" +import google_protobuf5 "github.com/golang/protobuf/ptypes/empty" +import google_protobuf6 "google.golang.org/genproto/protobuf/field_mask" import ( context "golang.org/x/net/context" @@ -40,7 +40,7 @@ type ListUptimeCheckConfigsRequest struct { func (m *ListUptimeCheckConfigsRequest) Reset() { *m = ListUptimeCheckConfigsRequest{} } func (m *ListUptimeCheckConfigsRequest) String() string { return proto.CompactTextString(m) } func (*ListUptimeCheckConfigsRequest) ProtoMessage() {} -func (*ListUptimeCheckConfigsRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{0} } +func (*ListUptimeCheckConfigsRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{0} } func (m *ListUptimeCheckConfigsRequest) GetParent() string { if m != nil { @@ -78,7 +78,7 @@ type ListUptimeCheckConfigsResponse struct { func (m *ListUptimeCheckConfigsResponse) Reset() { *m = ListUptimeCheckConfigsResponse{} } func (m *ListUptimeCheckConfigsResponse) String() string { return proto.CompactTextString(m) } func (*ListUptimeCheckConfigsResponse) ProtoMessage() {} -func (*ListUptimeCheckConfigsResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{1} } +func (*ListUptimeCheckConfigsResponse) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{1} } func (m *ListUptimeCheckConfigsResponse) GetUptimeCheckConfigs() []*UptimeCheckConfig { if m != nil { @@ -105,7 +105,7 @@ type GetUptimeCheckConfigRequest struct { func (m *GetUptimeCheckConfigRequest) Reset() { *m = GetUptimeCheckConfigRequest{} } func (m *GetUptimeCheckConfigRequest) String() string { return proto.CompactTextString(m) } func (*GetUptimeCheckConfigRequest) ProtoMessage() {} -func (*GetUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{2} } +func (*GetUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{2} } func (m *GetUptimeCheckConfigRequest) GetName() string { if m != nil { @@ -127,7 +127,7 @@ type CreateUptimeCheckConfigRequest struct { func (m *CreateUptimeCheckConfigRequest) Reset() { *m = CreateUptimeCheckConfigRequest{} } func (m *CreateUptimeCheckConfigRequest) String() string { return proto.CompactTextString(m) } func (*CreateUptimeCheckConfigRequest) ProtoMessage() {} -func (*CreateUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{3} } +func (*CreateUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{3} } func (m *CreateUptimeCheckConfigRequest) GetParent() string { if m != nil { @@ -149,7 +149,7 @@ type UpdateUptimeCheckConfigRequest struct { // configuration are updated with values from the new configuration. If this // field is empty, then the current configuration is completely replaced with // the new configuration. - UpdateMask *google_protobuf5.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` + UpdateMask *google_protobuf6.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` // Required. If an `"updateMask"` has been specified, this field gives // the values for the set of fields mentioned in the `"updateMask"`. If an // `"updateMask"` has not been given, this uptime check configuration replaces @@ -163,9 +163,9 @@ type UpdateUptimeCheckConfigRequest struct { func (m *UpdateUptimeCheckConfigRequest) Reset() { *m = UpdateUptimeCheckConfigRequest{} } func (m *UpdateUptimeCheckConfigRequest) String() string { return proto.CompactTextString(m) } func (*UpdateUptimeCheckConfigRequest) ProtoMessage() {} -func (*UpdateUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{4} } +func (*UpdateUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{4} } -func (m *UpdateUptimeCheckConfigRequest) GetUpdateMask() *google_protobuf5.FieldMask { +func (m *UpdateUptimeCheckConfigRequest) GetUpdateMask() *google_protobuf6.FieldMask { if m != nil { return m.UpdateMask } @@ -190,7 +190,7 @@ type DeleteUptimeCheckConfigRequest struct { func (m *DeleteUptimeCheckConfigRequest) Reset() { *m = DeleteUptimeCheckConfigRequest{} } func (m *DeleteUptimeCheckConfigRequest) String() string { return proto.CompactTextString(m) } func (*DeleteUptimeCheckConfigRequest) ProtoMessage() {} -func (*DeleteUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{5} } +func (*DeleteUptimeCheckConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{5} } func (m *DeleteUptimeCheckConfigRequest) GetName() string { if m != nil { @@ -217,7 +217,7 @@ type ListUptimeCheckIpsRequest struct { func (m *ListUptimeCheckIpsRequest) Reset() { *m = ListUptimeCheckIpsRequest{} } func (m *ListUptimeCheckIpsRequest) String() string { return proto.CompactTextString(m) } func (*ListUptimeCheckIpsRequest) ProtoMessage() {} -func (*ListUptimeCheckIpsRequest) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{6} } +func (*ListUptimeCheckIpsRequest) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{6} } func (m *ListUptimeCheckIpsRequest) GetPageSize() int32 { if m != nil { @@ -250,7 +250,7 @@ type ListUptimeCheckIpsResponse struct { func (m *ListUptimeCheckIpsResponse) Reset() { *m = ListUptimeCheckIpsResponse{} } func (m *ListUptimeCheckIpsResponse) String() string { return proto.CompactTextString(m) } func (*ListUptimeCheckIpsResponse) ProtoMessage() {} -func (*ListUptimeCheckIpsResponse) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{7} } +func (*ListUptimeCheckIpsResponse) Descriptor() ([]byte, []int) { return fileDescriptor11, []int{7} } func (m *ListUptimeCheckIpsResponse) GetUptimeCheckIps() []*UptimeCheckIp { if m != nil { @@ -303,7 +303,7 @@ type UptimeCheckServiceClient interface { // Deletes an uptime check configuration. Note that this method will fail // if the uptime check configuration is referenced by an alert policy or // other dependent configs that would be rendered invalid by the deletion. - DeleteUptimeCheckConfig(ctx context.Context, in *DeleteUptimeCheckConfigRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) + DeleteUptimeCheckConfig(ctx context.Context, in *DeleteUptimeCheckConfigRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) // Returns the list of IPs that checkers run from ListUptimeCheckIps(ctx context.Context, in *ListUptimeCheckIpsRequest, opts ...grpc.CallOption) (*ListUptimeCheckIpsResponse, error) } @@ -352,8 +352,8 @@ func (c *uptimeCheckServiceClient) UpdateUptimeCheckConfig(ctx context.Context, return out, nil } -func (c *uptimeCheckServiceClient) DeleteUptimeCheckConfig(ctx context.Context, in *DeleteUptimeCheckConfigRequest, opts ...grpc.CallOption) (*google_protobuf4.Empty, error) { - out := new(google_protobuf4.Empty) +func (c *uptimeCheckServiceClient) DeleteUptimeCheckConfig(ctx context.Context, in *DeleteUptimeCheckConfigRequest, opts ...grpc.CallOption) (*google_protobuf5.Empty, error) { + out := new(google_protobuf5.Empty) err := grpc.Invoke(ctx, "/google.monitoring.v3.UptimeCheckService/DeleteUptimeCheckConfig", in, out, c.cc, opts...) if err != nil { return nil, err @@ -388,7 +388,7 @@ type UptimeCheckServiceServer interface { // Deletes an uptime check configuration. Note that this method will fail // if the uptime check configuration is referenced by an alert policy or // other dependent configs that would be rendered invalid by the deletion. - DeleteUptimeCheckConfig(context.Context, *DeleteUptimeCheckConfigRequest) (*google_protobuf4.Empty, error) + DeleteUptimeCheckConfig(context.Context, *DeleteUptimeCheckConfigRequest) (*google_protobuf5.Empty, error) // Returns the list of IPs that checkers run from ListUptimeCheckIps(context.Context, *ListUptimeCheckIpsRequest) (*ListUptimeCheckIpsResponse, error) } @@ -538,9 +538,9 @@ var _UptimeCheckService_serviceDesc = grpc.ServiceDesc{ Metadata: "google/monitoring/v3/uptime_service.proto", } -func init() { proto.RegisterFile("google/monitoring/v3/uptime_service.proto", fileDescriptor6) } +func init() { proto.RegisterFile("google/monitoring/v3/uptime_service.proto", fileDescriptor11) } -var fileDescriptor6 = []byte{ +var fileDescriptor11 = []byte{ // 735 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdf, 0x4e, 0x13, 0x4f, 0x14, 0xce, 0xb4, 0xfc, 0x08, 0x1c, 0xf2, 0xf3, 0xcf, 0xd8, 0x40, 0x5d, 0xa4, 0xa9, 0x35, 0x51, diff --git a/vendor/k8s.io/kubernetes/CHANGELOG-1.9.md b/vendor/k8s.io/kubernetes/CHANGELOG-1.9.md index 6099944ef5..8e5e6d0f1d 100644 --- a/vendor/k8s.io/kubernetes/CHANGELOG-1.9.md +++ b/vendor/k8s.io/kubernetes/CHANGELOG-1.9.md @@ -1,23 +1,31 @@ -- [v1.9.2](#v192) - - [Downloads for v1.9.2](#downloads-for-v192) +- [v1.9.3](#v193) + - [Downloads for v1.9.3](#downloads-for-v193) - [Client Binaries](#client-binaries) - [Server Binaries](#server-binaries) - [Node Binaries](#node-binaries) - - [Changelog since v1.9.1](#changelog-since-v191) + - [Changelog since v1.9.2](#changelog-since-v192) + - [Action Required](#action-required) - [Other notable changes](#other-notable-changes) -- [v1.9.1](#v191) - - [Downloads for v1.9.1](#downloads-for-v191) +- [v1.9.2](#v192) + - [Downloads for v1.9.2](#downloads-for-v192) - [Client Binaries](#client-binaries-1) - [Server Binaries](#server-binaries-1) - [Node Binaries](#node-binaries-1) - - [Changelog since v1.9.0](#changelog-since-v190) + - [Changelog since v1.9.1](#changelog-since-v191) - [Other notable changes](#other-notable-changes-1) -- [v1.9.0](#v190) - - [Downloads for v1.9.0](#downloads-for-v190) +- [v1.9.1](#v191) + - [Downloads for v1.9.1](#downloads-for-v191) - [Client Binaries](#client-binaries-2) - [Server Binaries](#server-binaries-2) - [Node Binaries](#node-binaries-2) + - [Changelog since v1.9.0](#changelog-since-v190) + - [Other notable changes](#other-notable-changes-2) +- [v1.9.0](#v190) + - [Downloads for v1.9.0](#downloads-for-v190) + - [Client Binaries](#client-binaries-3) + - [Server Binaries](#server-binaries-3) + - [Node Binaries](#node-binaries-3) - [1.9 Release Notes](#19-release-notes) - [WARNING: etcd backup strongly recommended](#warning-etcd-backup-strongly-recommended) - [Introduction to 1.9.0](#introduction-to-190) @@ -105,48 +113,138 @@ - [External Dependencies](#external-dependencies) - [v1.9.0-beta.2](#v190-beta2) - [Downloads for v1.9.0-beta.2](#downloads-for-v190-beta2) - - [Client Binaries](#client-binaries-3) - - [Server Binaries](#server-binaries-3) - - [Node Binaries](#node-binaries-3) - - [Changelog since v1.9.0-beta.1](#changelog-since-v190-beta1) - - [Other notable changes](#other-notable-changes-2) -- [v1.9.0-beta.1](#v190-beta1) - - [Downloads for v1.9.0-beta.1](#downloads-for-v190-beta1) - [Client Binaries](#client-binaries-4) - [Server Binaries](#server-binaries-4) - [Node Binaries](#node-binaries-4) - - [Changelog since v1.9.0-alpha.3](#changelog-since-v190-alpha3) - - [Action Required](#action-required) + - [Changelog since v1.9.0-beta.1](#changelog-since-v190-beta1) - [Other notable changes](#other-notable-changes-3) -- [v1.9.0-alpha.3](#v190-alpha3) - - [Downloads for v1.9.0-alpha.3](#downloads-for-v190-alpha3) +- [v1.9.0-beta.1](#v190-beta1) + - [Downloads for v1.9.0-beta.1](#downloads-for-v190-beta1) - [Client Binaries](#client-binaries-5) - [Server Binaries](#server-binaries-5) - [Node Binaries](#node-binaries-5) - - [Changelog since v1.9.0-alpha.2](#changelog-since-v190-alpha2) + - [Changelog since v1.9.0-alpha.3](#changelog-since-v190-alpha3) - [Action Required](#action-required-1) - [Other notable changes](#other-notable-changes-4) -- [v1.9.0-alpha.2](#v190-alpha2) - - [Downloads for v1.9.0-alpha.2](#downloads-for-v190-alpha2) +- [v1.9.0-alpha.3](#v190-alpha3) + - [Downloads for v1.9.0-alpha.3](#downloads-for-v190-alpha3) - [Client Binaries](#client-binaries-6) - [Server Binaries](#server-binaries-6) - [Node Binaries](#node-binaries-6) - - [Changelog since v1.8.0](#changelog-since-v180) + - [Changelog since v1.9.0-alpha.2](#changelog-since-v190-alpha2) - [Action Required](#action-required-2) - [Other notable changes](#other-notable-changes-5) -- [v1.9.0-alpha.1](#v190-alpha1) - - [Downloads for v1.9.0-alpha.1](#downloads-for-v190-alpha1) +- [v1.9.0-alpha.2](#v190-alpha2) + - [Downloads for v1.9.0-alpha.2](#downloads-for-v190-alpha2) - [Client Binaries](#client-binaries-7) - [Server Binaries](#server-binaries-7) - [Node Binaries](#node-binaries-7) - - [Changelog since v1.8.0-alpha.3](#changelog-since-v180-alpha3) + - [Changelog since v1.8.0](#changelog-since-v180) - [Action Required](#action-required-3) - [Other notable changes](#other-notable-changes-6) +- [v1.9.0-alpha.1](#v190-alpha1) + - [Downloads for v1.9.0-alpha.1](#downloads-for-v190-alpha1) + - [Client Binaries](#client-binaries-8) + - [Server Binaries](#server-binaries-8) + - [Node Binaries](#node-binaries-8) + - [Changelog since v1.8.0-alpha.3](#changelog-since-v180-alpha3) + - [Action Required](#action-required-4) + - [Other notable changes](#other-notable-changes-7) +# v1.9.3 + +[Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.9/examples) + +## Downloads for v1.9.3 + + +filename | sha256 hash +-------- | ----------- +[kubernetes.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes.tar.gz) | `b495325eacd1354514b20ef1f0b99c6a41277842fc93b6cf5c9cb6e8657c266f` +[kubernetes-src.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-src.tar.gz) | `f99a016dc616be37e7fe161ff435335a2442ebcede622486e7a9cf0bacedb625` + +### Client Binaries + +filename | sha256 hash +-------- | ----------- +[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-darwin-386.tar.gz) | `084dd17c182acbc1ee248ea9f9fc720224be6245f13d9904cd7ca44205eb38ed` +[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-darwin-amd64.tar.gz) | `c6ae13f8da18322ca3651b289c8e48475839e6f4c741ae12342cd69bde467773` +[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-386.tar.gz) | `231d9255c11d38b88c6b7febe43d1ea9564c6b36b34cb905450c7beb7c46e051` +[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-amd64.tar.gz) | `2f509c05f0c4e1c1ac9e98879a1924f24546905349457904344d79dc639217be` +[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-arm64.tar.gz) | `d8fe5dc1bc80d5dfb60e811c0bfcd392b2761f76400fc4c48b17d4d4cd0aabf1` +[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-arm.tar.gz) | `7c084e01a97379256746ada2b980e36e727acc23aaa614d98e4e0a144faad37e` +[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-ppc64le.tar.gz) | `669629d372ebe169140238f106c6d97b53a1895f4ac8393147fbddddf83eeb47` +[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-linux-s390x.tar.gz) | `1627933c04ba9a155ac63c0a9a90ada32badd618c2e2919d3044cd5039963cc4` +[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-windows-386.tar.gz) | `68de0d599a5e09195479602390343a017296b3aa774b4a783455581e1065cc8d` +[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-client-windows-amd64.tar.gz) | `e8872561f33258a8509e90aa955c5b57d6b5d9a657864bf5002e21285a8f4792` + +### Server Binaries + +filename | sha256 hash +-------- | ----------- +[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-server-linux-amd64.tar.gz) | `09ab78a1b091ce8affb39d5218ba780eb36bc8026d557ed6d5efcd5a51b7927a` +[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-server-linux-arm64.tar.gz) | `f3e38a8ffae0b5f2ac0c776a0b4586630e8b258f2802237ebda4d612f6d41d9e` +[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-server-linux-arm.tar.gz) | `eeba15fc5db374e6e1b66b846988422e751752d930e4c2c89f5a92de5f466010` +[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-server-linux-ppc64le.tar.gz) | `ce05d9cf268b213e9a57dcbb5f9d570c62e72a15f8af9e692f4a26a8f40d8df1` +[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-server-linux-s390x.tar.gz) | `1ca63330add758e7638357eba79753d1af610ea5de8b082aa740ef4852abd51a` + +### Node Binaries + +filename | sha256 hash +-------- | ----------- +[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-linux-amd64.tar.gz) | `c40f983c11f93752a40180cb719ddd473cbf07f43a3af5d2b575411c85b76f88` +[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-linux-arm64.tar.gz) | `7a0c5c313d14d88bd11010d416c0614e7dc2362e78e1ffb65ee098bfe944b881` +[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-linux-arm.tar.gz) | `7a3e288cb04e3fe5f2537645bd74a68d7b471c15c6eb51eb9d5e1ac6edfc7e9f` +[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-linux-ppc64le.tar.gz) | `401f763112d20cf2c613d065beecd47387bb11d82a49fd2222a2ac38a4e06c20` +[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-linux-s390x.tar.gz) | `9a6d921e1cef37dcbaac61be13a70410cd03bc26335b7730cce6d9d3c8506b22` +[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.9.3/kubernetes-node-windows-amd64.tar.gz) | `0db90e50c23ef16e9bfa5a990647bd4299a809166a2a37764e880b1910feee49` + +## Changelog since v1.9.2 + +### Action Required + +* Bug fix: webhooks now do not skip cluster-scoped resources ([#58185](https://github.com/kubernetes/kubernetes/pull/58185), [@caesarxuchao](https://github.com/caesarxuchao)) + * Action required: Before upgrading your Kubernetes clusters, double check if you had configured webhooks for cluster-scoped objects (e.g., nodes, persistentVolume), these webhooks will start to take effect. Delete/modify the configs if that's not desirable. + +### Other notable changes + +* CustomResourceDefinitions: OpenAPI v3 validation schemas containing `$ref`references are no longer permitted (valid references could not be constructed previously because property ids were not permitted either). Before upgrading, ensure CRD definitions do not include those `$ref` fields. ([#58438](https://github.com/kubernetes/kubernetes/pull/58438), [@carlory](https://github.com/carlory)) +* Ensure IP is set for Azure internal load balancer. ([#59083](https://github.com/kubernetes/kubernetes/pull/59083), [@feiskyer](https://github.com/feiskyer)) +* Configurable etcd quota backend bytes in GCE ([#59259](https://github.com/kubernetes/kubernetes/pull/59259), [@wojtek-t](https://github.com/wojtek-t)) +* Updates Calico version to v2.6.7 (Fixed a bug where Felix would crash when parsing a NetworkPolicy with a named port. See https://github.com/projectcalico/calico/releases/tag/v2.6.7) ([#59130](https://github.com/kubernetes/kubernetes/pull/59130), [@caseydavenport](https://github.com/caseydavenport)) +* Cluster Autoscaler 1.1.1 (details: https://github.com/kubernetes/autoscaler/releases/tag/cluster-autoscaler-1.1.1) ([#59272](https://github.com/kubernetes/kubernetes/pull/59272), [@mwielgus](https://github.com/mwielgus)) +* cloudprovider/openstack: fix bug the tries to use octavia client to query flip ([#59075](https://github.com/kubernetes/kubernetes/pull/59075), [@jrperritt](https://github.com/jrperritt)) +* Fixed a bug which caused the apiserver reboot failure in the presence of malfunctioning webhooks. ([#59073](https://github.com/kubernetes/kubernetes/pull/59073), [@caesarxuchao](https://github.com/caesarxuchao)) +* Configurable etcd compaction frequency in GCE ([#59106](https://github.com/kubernetes/kubernetes/pull/59106), [@wojtek-t](https://github.com/wojtek-t)) +* Prevent kubelet from getting wedged if initialization of modules returns an error. ([#59020](https://github.com/kubernetes/kubernetes/pull/59020), [@brendandburns](https://github.com/brendandburns)) +* [GCE] Apiserver uses `InternalIP` as the most preferred kubelet address type by default. ([#59019](https://github.com/kubernetes/kubernetes/pull/59019), [@MrHohn](https://github.com/MrHohn)) +* Expose Metrics Server metrics via /metric endpoint. ([#57456](https://github.com/kubernetes/kubernetes/pull/57456), [@kawych](https://github.com/kawych)) +* Get windows kernel version directly from registry ([#58498](https://github.com/kubernetes/kubernetes/pull/58498), [@feiskyer](https://github.com/feiskyer)) +* Fixes a bug where kubelet crashes trying to free memory under memory pressure ([#58574](https://github.com/kubernetes/kubernetes/pull/58574), [@yastij](https://github.com/yastij)) +* Updated priority of mirror pod according to PriorityClassName. ([#58485](https://github.com/kubernetes/kubernetes/pull/58485), [@k82cn](https://github.com/k82cn)) +* Access to externally managed IP addresses via the kube-apiserver service proxy subresource is no longer allowed by default. This can be re-enabled via the `ServiceProxyAllowExternalIPs` feature gate, but will be disallowed completely in 1.11 ([#57265](https://github.com/kubernetes/kubernetes/pull/57265), [@brendandburns](https://github.com/brendandburns)) +* Detach and clear bad disk URI ([#58345](https://github.com/kubernetes/kubernetes/pull/58345), [@rootfs](https://github.com/rootfs)) +* Add apiserver metric for number of requests dropped because of inflight limit. ([#58340](https://github.com/kubernetes/kubernetes/pull/58340), [@gmarek](https://github.com/gmarek)) +* Add apiserver metric for current inflight-request usage. ([#58342](https://github.com/kubernetes/kubernetes/pull/58342), [@gmarek](https://github.com/gmarek)) +* kube-apiserver is changed to use SSH tunnels for webhook iff the webhook is not directly routable from apiserver's network environment. ([#58644](https://github.com/kubernetes/kubernetes/pull/58644), [@yguo0905](https://github.com/yguo0905)) +* Update Calico version to v2.6.6 ([#58482](https://github.com/kubernetes/kubernetes/pull/58482), [@tmjd](https://github.com/tmjd)) +* Fix garbage collection and resource quota when the controller-manager uses --leader-elect=false ([#57340](https://github.com/kubernetes/kubernetes/pull/57340), [@jmcmeek](https://github.com/jmcmeek)) +* kube-apiserver: fixes loading of `--admission-control-config-file` containing AdmissionConfiguration apiserver.k8s.io/v1alpha1 config object ([#58441](https://github.com/kubernetes/kubernetes/pull/58441), [@liggitt](https://github.com/liggitt)) +* Fix a bug affecting nested data volumes such as secret, configmap, etc. ([#57422](https://github.com/kubernetes/kubernetes/pull/57422), [@joelsmith](https://github.com/joelsmith)) +* Reduce Metrics Server memory requirement ([#58391](https://github.com/kubernetes/kubernetes/pull/58391), [@kawych](https://github.com/kawych)) +* GCP: allow a master to not include a metadata concealment firewall rule (if it's not running the metadata proxy). ([#58104](https://github.com/kubernetes/kubernetes/pull/58104), [@ihmccreery](https://github.com/ihmccreery)) +* Bump GCE metadata proxy to v0.1.9 to pick up security fixes. ([#58221](https://github.com/kubernetes/kubernetes/pull/58221), [@ihmccreery](https://github.com/ihmccreery)) +* Fixes an issue where the resourceVersion of an object in a DELETE watch event was not the resourceVersion of the delete itself, but of the last update to the object. This could disrupt the ability of clients clients to re-establish watches properly. ([#58547](https://github.com/kubernetes/kubernetes/pull/58547), [@liggitt](https://github.com/liggitt)) +* Fixed encryption key and encryption provider rotation ([#58375](https://github.com/kubernetes/kubernetes/pull/58375), [@liggitt](https://github.com/liggitt)) +* Correctly handle transient connection reset errors on GET requests from client library. ([#58520](https://github.com/kubernetes/kubernetes/pull/58520), [@porridge](https://github.com/porridge)) +* Avoid controller-manager to crash when enabling IP alias for K8s cluster. ([#58557](https://github.com/kubernetes/kubernetes/pull/58557), [@jingax10](https://github.com/jingax10)) + + + # v1.9.2 [Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.9/examples) diff --git a/vendor/k8s.io/kubernetes/Godeps/Godeps.json b/vendor/k8s.io/kubernetes/Godeps/Godeps.json index e7e78a8b96..d299f962c2 100644 --- a/vendor/k8s.io/kubernetes/Godeps/Godeps.json +++ b/vendor/k8s.io/kubernetes/Godeps/Godeps.json @@ -2882,47 +2882,47 @@ }, { "ImportPath": "google.golang.org/api/cloudmonitoring/v2beta2", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/compute/v0.alpha", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/compute/v0.beta", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/compute/v1", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/container/v1", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/gensupport", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/googleapi", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/googleapi/internal/uritemplates", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/logging/v2beta1", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/monitoring/v3", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/api/pubsub/v1", - "Rev": "654f863362977d69086620b5f72f13e911da2410" + "Rev": "c0dae069ee96c9261a04c81efd9e0f1e55f565ac" }, { "ImportPath": "google.golang.org/genproto/googleapis/rpc/status", diff --git a/vendor/k8s.io/kubernetes/api/openapi-spec/swagger.json b/vendor/k8s.io/kubernetes/api/openapi-spec/swagger.json index 8acb4c1e60..fb244e316c 100644 --- a/vendor/k8s.io/kubernetes/api/openapi-spec/swagger.json +++ b/vendor/k8s.io/kubernetes/api/openapi-spec/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "title": "Kubernetes", - "version": "v1.9.3" + "version": "v1.9.4" }, "paths": { "/api/": { diff --git a/vendor/k8s.io/kubernetes/build/build-image/cross/Dockerfile b/vendor/k8s.io/kubernetes/build/build-image/cross/Dockerfile index 3fe8aebc66..830dcbcdef 100644 --- a/vendor/k8s.io/kubernetes/build/build-image/cross/Dockerfile +++ b/vendor/k8s.io/kubernetes/build/build-image/cross/Dockerfile @@ -15,7 +15,7 @@ # This file creates a standard build environment for building cross # platform go binary for the architecture kubernetes cares about. -FROM golang:1.9.2 +FROM golang:1.9.3 ENV GOARM 7 ENV KUBE_DYNAMIC_CROSSPLATFORMS \ diff --git a/vendor/k8s.io/kubernetes/build/build-image/cross/VERSION b/vendor/k8s.io/kubernetes/build/build-image/cross/VERSION index c67c6bbfd8..6cdbb2f223 100644 --- a/vendor/k8s.io/kubernetes/build/build-image/cross/VERSION +++ b/vendor/k8s.io/kubernetes/build/build-image/cross/VERSION @@ -1 +1 @@ -v1.9.2-1 +v1.9.3-1 diff --git a/vendor/k8s.io/kubernetes/build/root/WORKSPACE b/vendor/k8s.io/kubernetes/build/root/WORKSPACE index 30e5976192..bdb9484b98 100644 --- a/vendor/k8s.io/kubernetes/build/root/WORKSPACE +++ b/vendor/k8s.io/kubernetes/build/root/WORKSPACE @@ -55,21 +55,21 @@ load("@io_bazel_rules_docker//docker:docker.bzl", "docker_repositories", "docker go_rules_dependencies() -# The upstream version of rules_go is broken in a number of ways. Until it's fixed, explicitly download and use go1.9.2 ourselves. +# The upstream version of rules_go is broken in a number of ways. Until it's fixed, explicitly download and use go1.9.3 ourselves. go_download_sdk( name = "go_sdk", sdks = { - "darwin_amd64": ("go1.9.2.darwin-amd64.tar.gz", "73fd5840d55f5566d8db6c0ffdd187577e8ebe650c783f68bd27cbf95bde6743"), - "linux_386": ("go1.9.2.linux-386.tar.gz", "574b2c4b1a248e58ef7d1f825beda15429610a2316d9cbd3096d8d3fa8c0bc1a"), - "linux_amd64": ("go1.9.2.linux-amd64.tar.gz", "de874549d9a8d8d8062be05808509c09a88a248e77ec14eb77453530829ac02b"), - "linux_armv6l": ("go1.9.2.linux-armv6l.tar.gz", "8a6758c8d390e28ef2bcea511f62dcb43056f38c1addc06a8bc996741987e7bb"), - "windows_386": ("go1.9.2.windows-386.zip", "35d3be5d7b97c6d11ffb76c1b19e20a824e427805ee918e82c08a2e5793eda20"), - "windows_amd64": ("go1.9.2.windows-amd64.zip", "682ec3626a9c45b657c2456e35cadad119057408d37f334c6c24d88389c2164c"), - "freebsd_386": ("go1.9.2.freebsd-386.tar.gz", "809dcb0a8457c8d0abf954f20311a1ee353486d0ae3f921e9478189721d37677"), - "freebsd_amd64": ("go1.9.2.freebsd-amd64.tar.gz", "8be985c3e251c8e007fa6ecd0189bc53e65cc519f4464ddf19fa11f7ed251134"), - "linux_arm64": ("go1.9.2.linux-arm64.tar.gz", "0016ac65ad8340c84f51bc11dbb24ee8265b0a4597dbfdf8d91776fc187456fa"), - "linux_ppc64le": ("go1.9.2.linux-ppc64le.tar.gz", "adb440b2b6ae9e448c253a20836d8e8aa4236f731d87717d9c7b241998dc7f9d"), - "linux_s390x": ("go1.9.2.linux-s390x.tar.gz", "a7137b4fbdec126823a12a4b696eeee2f04ec616e9fb8a54654c51d5884c1345"), + "darwin_amd64": ("go1.9.3.darwin-amd64.tar.gz", "f84b39c2ed7df0c2f1648e2b90b2198a6783db56b53700dabfa58afd6335d324"), + "linux_386": ("go1.9.3.linux-386.tar.gz", "bc0782ac8116b2244dfe2a04972bbbcd7f1c2da455a768ab47b32864bcd0d49d"), + "linux_amd64": ("go1.9.3.linux-amd64.tar.gz", "a4da5f4c07dfda8194c4621611aeb7ceaab98af0b38bfb29e1be2ebb04c3556c"), + "linux_armv6l": ("go1.9.3.linux-armv6l.tar.gz", "926d6cd6c21ef3419dca2e5da8d4b74b99592ab1feb5a62a4da244e6333189d2"), + "windows_386": ("go1.9.3.windows-386.zip", "cab7d4e008adefed322d36dee87a4c1775ab60b25ce587a2b55d90c75d0bafbc"), + "windows_amd64": ("go1.9.3.windows-amd64.zip", "4eee59bb5b70abc357aebd0c54f75e46322eb8b58bbdabc026fdd35834d65e1e"), + "freebsd_386": ("go1.9.3.freebsd-386.tar.gz", "a755739e3be0415344d62ea3b168bdcc9a54f7862ac15832684ff2d3e8127a03"), + "freebsd_amd64": ("go1.9.3.freebsd-amd64.tar.gz", "f95066089a88749c45fae798422d04e254fe3b622ff030d12bdf333402b186ec"), + "linux_arm64": ("go1.9.3.linux-arm64.tar.gz", "065d79964023ccb996e9dbfbf94fc6969d2483fbdeeae6d813f514c5afcd98d9"), + "linux_ppc64le": ("go1.9.3.linux-ppc64le.tar.gz", "c802194b1af0cd904689923d6d32f3ed68f9d5f81a3e4a82406d9ce9be163681"), + "linux_s390x": ("go1.9.3.linux-s390x.tar.gz", "85e9a257664f84154e583e0877240822bb2fe4308209f5ff57d80d16e2fb95c5"), }, ) diff --git a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/OWNERS b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/OWNERS new file mode 100644 index 0000000000..222788b954 --- /dev/null +++ b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/OWNERS @@ -0,0 +1,6 @@ +approvers: +- floreks +- maciaszczykm +reviewers: +- floreks +- maciaszczykm diff --git a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-controller.yaml b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-controller.yaml index 59bf7c4daf..7068d72eb4 100644 --- a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-controller.yaml +++ b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-controller.yaml @@ -29,7 +29,7 @@ spec: spec: containers: - name: kubernetes-dashboard - image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.8.0 + image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.3 resources: limits: cpu: 100m diff --git a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-rbac.yaml b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-rbac.yaml index 658ffd9486..3c222b21db 100644 --- a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-rbac.yaml +++ b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-rbac.yaml @@ -7,10 +7,6 @@ metadata: name: kubernetes-dashboard-minimal namespace: kube-system rules: - # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret. -- apiGroups: [""] - resources: ["secrets"] - verbs: ["create"] # Allow Dashboard to get, update and delete Dashboard exclusive secrets. - apiGroups: [""] resources: ["secrets"] @@ -26,6 +22,10 @@ rules: resources: ["services"] resourceNames: ["heapster"] verbs: ["proxy"] +- apiGroups: [""] + resources: ["services/proxy"] + resourceNames: ["heapster", "http:heapster:", "https:heapster:"] + verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-secret.yaml b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-secret.yaml index f26235bec3..a79b6a7ce3 100644 --- a/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-secret.yaml +++ b/vendor/k8s.io/kubernetes/cluster/addons/dashboard/dashboard-secret.yaml @@ -8,3 +8,14 @@ metadata: name: kubernetes-dashboard-certs namespace: kube-system type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + # Allows editing resource and makes sure it is created first. + addonmanager.kubernetes.io/mode: EnsureExists + name: kubernetes-dashboard-key-holder + namespace: kube-system +type: Opaque diff --git a/vendor/k8s.io/kubernetes/cluster/gce/config-default.sh b/vendor/k8s.io/kubernetes/cluster/gce/config-default.sh index d3d5fc6077..cd2c6c242f 100755 --- a/vendor/k8s.io/kubernetes/cluster/gce/config-default.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/config-default.sh @@ -271,14 +271,19 @@ ENABLE_RESCHEDULER="${KUBE_ENABLE_RESCHEDULER:-true}" # IP_ALIAS_SUBNETWORK is the subnetwork to allocate from. If empty, a # new subnetwork will be created for the cluster. ENABLE_IP_ALIASES=${KUBE_GCE_ENABLE_IP_ALIASES:-false} +NODE_IPAM_MODE=${KUBE_GCE_NODE_IPAM_MODE:-RangeAllocator} if [ ${ENABLE_IP_ALIASES} = true ]; then # Size of ranges allocated to each node. Currently supports only /32 and /24. IP_ALIAS_SIZE=${KUBE_GCE_IP_ALIAS_SIZE:-/24} IP_ALIAS_SUBNETWORK=${KUBE_GCE_IP_ALIAS_SUBNETWORK:-${INSTANCE_PREFIX}-subnet-default} # Reserve the services IP space to avoid being allocated for other GCP resources. SERVICE_CLUSTER_IP_SUBNETWORK=${KUBE_GCE_SERVICE_CLUSTER_IP_SUBNETWORK:-${INSTANCE_PREFIX}-subnet-services} + NODE_IPAM_MODE=${KUBE_GCE_NODE_IPAM_MODE:-CloudAllocator} + SECONDARY_RANGE_NAME=${SECONDARY_RANGE_NAME:-} # Add to the provider custom variables. PROVIDER_VARS="${PROVIDER_VARS:-} ENABLE_IP_ALIASES" + PROVIDER_VARS="${PROVIDER_VARS:-} NODE_IPAM_MODE" + PROVIDER_VARS="${PROVIDER_VARS:-} SECONDARY_RANGE_NAME" fi # Enable GCE Alpha features. diff --git a/vendor/k8s.io/kubernetes/cluster/gce/config-test.sh b/vendor/k8s.io/kubernetes/cluster/gce/config-test.sh index 918f8b67fd..00ac5e3f6d 100755 --- a/vendor/k8s.io/kubernetes/cluster/gce/config-test.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/config-test.sh @@ -293,14 +293,19 @@ ENABLE_RESCHEDULER="${KUBE_ENABLE_RESCHEDULER:-true}" # IP_ALIAS_SUBNETWORK is the subnetwork to allocate from. If empty, a # new subnetwork will be created for the cluster. ENABLE_IP_ALIASES=${KUBE_GCE_ENABLE_IP_ALIASES:-false} +NODE_IPAM_MODE=${KUBE_GCE_NODE_IPAM_MODE:-RangeAllocator} if [ ${ENABLE_IP_ALIASES} = true ]; then # Size of ranges allocated to each node. gcloud current supports only /32 and /24. IP_ALIAS_SIZE=${KUBE_GCE_IP_ALIAS_SIZE:-/24} IP_ALIAS_SUBNETWORK=${KUBE_GCE_IP_ALIAS_SUBNETWORK:-${INSTANCE_PREFIX}-subnet-default} # Reserve the services IP space to avoid being allocated for other GCP resources. SERVICE_CLUSTER_IP_SUBNETWORK=${KUBE_GCE_SERVICE_CLUSTER_IP_SUBNETWORK:-${INSTANCE_PREFIX}-subnet-services} + NODE_IPAM_MODE=${KUBE_GCE_NODE_IPAM_MODE:-CloudAllocator} + SECONDARY_RANGE_NAME=${SECONDARY_RANGE_NAME:-} # Add to the provider custom variables. PROVIDER_VARS="${PROVIDER_VARS:-} ENABLE_IP_ALIASES" + PROVIDER_VARS="${PROVIDER_VARS:-} NODE_IPAM_MODE" + PROVIDER_VARS="${PROVIDER_VARS:-} SECONDARY_RANGE_NAME" fi # Enable GCE Alpha features. diff --git a/vendor/k8s.io/kubernetes/cluster/gce/container-linux/configure-helper.sh b/vendor/k8s.io/kubernetes/cluster/gce/container-linux/configure-helper.sh index 8a6a1a6496..cd68d4cfc6 100755 --- a/vendor/k8s.io/kubernetes/cluster/gce/container-linux/configure-helper.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/container-linux/configure-helper.sh @@ -1124,7 +1124,7 @@ function start-kube-controller-manager { params+=" --terminated-pod-gc-threshold=${TERMINATED_POD_GC_THRESHOLD}" fi if [[ "${ENABLE_IP_ALIASES:-}" == 'true' ]]; then - params+=" --cidr-allocator-type=CloudAllocator" + params+=" --cidr-allocator-type=${NODE_IPAM_MODE}" params+=" --configure-cloud-routes=false" fi if [[ -n "${FEATURE_GATES:-}" ]]; then diff --git a/vendor/k8s.io/kubernetes/cluster/gce/container-linux/master-helper.sh b/vendor/k8s.io/kubernetes/cluster/gce/container-linux/master-helper.sh index 3cd3ee3a3e..84e86a0350 100755 --- a/vendor/k8s.io/kubernetes/cluster/gce/container-linux/master-helper.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/container-linux/master-helper.sh @@ -79,9 +79,16 @@ function create-master-instance-internal() { preemptible_master="--preemptible --maintenance-policy TERMINATE" fi + local enable_ip_aliases + if [[ "${NODE_IPAM_MODE:-}" == "CloudAllocator" ]]; then + enable_ip_aliases=true + else + enable_ip_aliases=false + fi + local network=$(make-gcloud-network-argument \ "${NETWORK_PROJECT}" "${REGION}" "${NETWORK}" "${SUBNETWORK:-}" \ - "${address:-}" "${ENABLE_IP_ALIASES:-}" "${IP_ALIAS_SIZE:-}") + "${address:-}" "${enable_ip_aliases:-}" "${IP_ALIAS_SIZE:-}") local metadata="kube-env=${KUBE_TEMP}/master-kube-env.yaml" metadata="${metadata},user-data=${KUBE_ROOT}/cluster/gce/container-linux/master.yaml" diff --git a/vendor/k8s.io/kubernetes/cluster/gce/gci/configure-helper.sh b/vendor/k8s.io/kubernetes/cluster/gce/gci/configure-helper.sh index ae3ef79f2c..8f3f8756a6 100644 --- a/vendor/k8s.io/kubernetes/cluster/gce/gci/configure-helper.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/gci/configure-helper.sh @@ -1849,7 +1849,7 @@ function start-kube-controller-manager { params+=" --terminated-pod-gc-threshold=${TERMINATED_POD_GC_THRESHOLD}" fi if [[ "${ENABLE_IP_ALIASES:-}" == 'true' ]]; then - params+=" --cidr-allocator-type=CloudAllocator" + params+=" --cidr-allocator-type=${NODE_IPAM_MODE}" params+=" --configure-cloud-routes=false" fi if [[ -n "${FEATURE_GATES:-}" ]]; then diff --git a/vendor/k8s.io/kubernetes/cluster/gce/gci/master-helper.sh b/vendor/k8s.io/kubernetes/cluster/gce/gci/master-helper.sh index e6fac224cf..0efab2bf8d 100755 --- a/vendor/k8s.io/kubernetes/cluster/gce/gci/master-helper.sh +++ b/vendor/k8s.io/kubernetes/cluster/gce/gci/master-helper.sh @@ -94,9 +94,16 @@ function create-master-instance-internal() { preemptible_master="--preemptible --maintenance-policy TERMINATE" fi + local enable_ip_aliases + if [[ "${NODE_IPAM_MODE:-}" == "CloudAllocator" ]]; then + enable_ip_aliases=true + else + enable_ip_aliases=false + fi + local network=$(make-gcloud-network-argument \ "${NETWORK_PROJECT}" "${REGION}" "${NETWORK}" "${SUBNETWORK:-}" \ - "${address:-}" "${ENABLE_IP_ALIASES:-}" "${IP_ALIAS_SIZE:-}") + "${address:-}" "${enable_ip_aliases:-}" "${IP_ALIAS_SIZE:-}") local metadata="kube-env=${KUBE_TEMP}/master-kube-env.yaml" metadata="${metadata},user-data=${KUBE_ROOT}/cluster/gce/gci/master.yaml" diff --git a/vendor/k8s.io/kubernetes/cluster/gce/upgrade-aliases.sh b/vendor/k8s.io/kubernetes/cluster/gce/upgrade-aliases.sh new file mode 100755 index 0000000000..d7ff3c69aa --- /dev/null +++ b/vendor/k8s.io/kubernetes/cluster/gce/upgrade-aliases.sh @@ -0,0 +1,171 @@ +#!/bin/bash + +# Copyright 2018 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# !!!EXPERIMENTAL!!! Upgrade a K8s cluster from routes to IP aliases for +# node connectivity on GCE. This is only for migration. + +set -o errexit +set -o nounset +set -o pipefail + +if [[ "${KUBERNETES_PROVIDER:-gce}" != "gce" ]]; then + echo "ERR: KUBERNETES_PROVIDER must be gce" >&2 + exit 1 +fi + +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. +source "${KUBE_ROOT}/hack/lib/util.sh" +source "${KUBE_ROOT}/cluster/kube-util.sh" + +# Print the number of routes used for K8s cluster node connectivity. +# +# Assumed vars: +# PROJECT +function get-k8s-node-routes-count() { + local k8s_node_routes_count=$(gcloud compute routes list \ + --project=${PROJECT} --filter='description=k8s-node-route' \ + --format='value(name)' | wc -l) + echo -n "${k8s_node_routes_count}" +} + +# Detect the subnetwork where the K8s cluster resides. +# +# Assumed vars: +# KUBE_MASTER +# PROJECT +# ZONE +# Vars set: +# IP_ALIAS_SUBNETWORK +function detect-k8s-subnetwork() { + local subnetwork_url=$(gcloud compute instances describe \ + ${KUBE_MASTER} --project=${PROJECT} --zone=${ZONE} \ + --format='value(networkInterfaces[0].subnetwork)') + if [ -n ${subnetwork_url} ]; then + IP_ALIAS_SUBNETWORK=$(echo ${subnetwork_url##*/}) + fi +} + +# Set IP_ALIAS_SUBNETWORK's allowSubnetCidrRoutesOverlap to a boolean value. +# $1: true or false for the desired allowSubnetCidrRoutesOverlap. +# +# Assumed vars: +# IP_ALIAS_SUBNETWORK +# GCE_API_ENDPOINT +# PROJECT +# REGION +function set-allow-subnet-cidr-routes-overlap() { + local allow_subnet_cidr_routes_overlap + allow_subnet_cidr_routes_overlap=$(gcloud beta compute networks subnets \ + describe ${IP_ALIAS_SUBNETWORK} --project=${PROJECT} --region=${REGION} \ + --format='value(allowSubnetCidrRoutesOverlap)') + local allow_overlap=$1 + if [ ${allow_subnet_cidr_routes_overlap,,} = ${allow_overlap} ]; then + echo "Subnet ${IP_ALIAS_SUBNETWORK}'s allowSubnetCidrRoutesOverlap is already set as $1" + return + fi + + echo "Setting subnet \"${IP_ALIAS_SUBNETWORK}\" allowSubnetCidrRoutesOverlap to $1" + local fingerprint=$(gcloud beta compute networks subnets describe \ + ${IP_ALIAS_SUBNETWORK} --project=${PROJECT} --region=${REGION} \ + --format='value(fingerprint)') + local access_token=$(gcloud auth print-access-token) + local request="{\"allowSubnetCidrRoutesOverlap\":$1, \"fingerprint\":\"${fingerprint}\"}" + local subnetwork_url="${GCE_API_ENDPOINT}projects/${PROJECT}/regions/${REGION}/subnetworks/${IP_ALIAS_SUBNETWORK}" + until curl -s --header "Content-Type: application/json" --header "Authorization: Bearer ${access_token}" \ + -X PATCH -d "${request}" "${subnetwork_url}" --output /dev/null; do + printf "." + sleep 1 + done +} + +# Add secondary ranges to K8s subnet. +# +# Assumed vars: +# IP_ALIAS_SUBNETWORK +# PROJECT +# REGION +# CLUSTER_IP_RANGE +# SERVICE_CLUSTER_IP_RANGE +function add-k8s-subnet-secondary-ranges() { + local secondary_ranges=$(gcloud beta compute networks subnets describe "${IP_ALIAS_SUBNETWORK}" \ + --project="${PROJECT}" --region="${REGION}" \ + --format='value(secondaryIpRanges)') + if [[ "${secondary_ranges}" =~ "pods-default" && "${secondary_ranges}" =~ "services-default" ]]; then + echo "${secondary_ranges} already contains both pods-default and services-default secondary ranges" + return + fi + + echo "Adding secondary ranges: pods-default (${CLUSTER_IP_RANGE}), services-default (${SERVICE_CLUSTER_IP_RANGE})" + until gcloud beta compute networks subnets update ${IP_ALIAS_SUBNETWORK} \ + --project=${PROJECT} --region=${REGION} \ + --add-secondary-ranges="pods-default=${CLUSTER_IP_RANGE},services-default=${SERVICE_CLUSTER_IP_RANGE}"; do + printf "." + sleep 1 + done +} + +# Delete all K8s node routes. +# +# Assumed vars: +# PROJECT +function delete-k8s-node-routes() { + local -a routes + local -r batch=200 + routes=( $(gcloud compute routes list \ + --project=${PROJECT} --filter='description=k8s-node-route' \ + --format='value(name)') ) + while (( "${#routes[@]}" > 0 )); do + echo Deleting k8s node routes "${routes[*]::${batch}}" + gcloud compute routes delete --project "${PROJECT}" --quiet "${routes[@]::${batch}}" + routes=( "${routes[@]:${batch}}" ) + done +} + +detect-project +detect-master + +k8s_node_routes_count=$(get-k8s-node-routes-count) +if [[ "${k8s_node_routes_count}" -eq 0 ]]; then + echo "No k8s node routes found and IP alias should already be enabled. Exiting..." + exit 0 +fi +echo "Found ${k8s_node_routes_count} K8s node routes. Proceeding to upgrade them to IP aliases based connectivity..." + +detect-k8s-subnetwork +if [ -z ${IP_ALIAS_SUBNETWORK} ]; then + echo "No k8s cluster subnetwork found. Exiting..." + exit 1 +fi +echo "k8s cluster sits on subnetwork \"${IP_ALIAS_SUBNETWORK}\"" + +set-allow-subnet-cidr-routes-overlap true +add-k8s-subnet-secondary-ranges + +echo "Changing K8s master envs and restarting..." +export KUBE_GCE_IP_ALIAS_SUBNETWORK=${IP_ALIAS_SUBNETWORK} +export KUBE_GCE_NODE_IPAM_MODE="IPAMFromCluster" +export KUBE_GCE_ENABLE_IP_ALIASES=true +export SECONDARY_RANGE_NAME="pods-default" +export STORAGE_BACKEND="etcd3" +export STORAGE_MEDIA_TYPE="application/vnd.kubernetes.protobuf" +export ETCD_IMAGE=3.1.10 +export ETCD_VERSION=3.1.10 + +# Upgrade master with updated kube envs +${KUBE_ROOT}/cluster/gce/upgrade.sh -M -l + +delete-k8s-node-routes +set-allow-subnet-cidr-routes-overlap false diff --git a/vendor/k8s.io/kubernetes/cluster/images/etcd/Dockerfile b/vendor/k8s.io/kubernetes/cluster/images/etcd/Dockerfile index 1d75d1787f..5e7eaf9f51 100644 --- a/vendor/k8s.io/kubernetes/cluster/images/etcd/Dockerfile +++ b/vendor/k8s.io/kubernetes/cluster/images/etcd/Dockerfile @@ -16,4 +16,4 @@ FROM BASEIMAGE EXPOSE 2379 2380 4001 7001 COPY etcd* etcdctl* /usr/local/bin/ -COPY migrate-if-needed.sh attachlease rollback /usr/local/bin/ +COPY migrate-if-needed.sh start-stop-etcd.sh attachlease rollback /usr/local/bin/ diff --git a/vendor/k8s.io/kubernetes/cluster/images/etcd/Makefile b/vendor/k8s.io/kubernetes/cluster/images/etcd/Makefile index 13a2ee4c26..b5a2c3f6c8 100644 --- a/vendor/k8s.io/kubernetes/cluster/images/etcd/Makefile +++ b/vendor/k8s.io/kubernetes/cluster/images/etcd/Makefile @@ -28,6 +28,8 @@ # That binary will be set to the last tag from $(TAGS). TAGS?=2.2.1 2.3.7 3.0.17 3.1.11 REGISTRY_TAG?=3.1.11 +# ROLLBACK_REGISTRY_TAG specified the tag that REGISTRY_TAG may be rolled back to. +ROLLBACK_REGISTRY_TAG?=3.0.17 ARCH?=amd64 REGISTRY?=gcr.io/google_containers GOLANG_VERSION?=1.7.6 @@ -56,10 +58,10 @@ build: find ./ -maxdepth 1 -type f | xargs cp -t $(TEMP_DIR) # Compile attachlease - docker run -i -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \ + docker run --interactive -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \ /bin/bash -c "CGO_ENABLED=0 go build -o /build/attachlease k8s.io/kubernetes/cluster/images/etcd/attachlease" # Compile rollback - docker run -i -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \ + docker run --interactive -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes -v $(TEMP_DIR):/build -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \ /bin/bash -c "CGO_ENABLED=0 go build -o /build/rollback k8s.io/kubernetes/cluster/images/etcd/rollback" @@ -80,7 +82,7 @@ else # For each release create a tmp dir 'etcd_release_tmp_dir' and unpack the release tar there. for tag in $(TAGS); do \ etcd_release_tmp_dir=$(shell mktemp -d); \ - docker run -i -v $$etcd_release_tmp_dir:/etcdbin golang:$(GOLANG_VERSION) /bin/bash -c \ + docker run --interactive -v $$etcd_release_tmp_dir:/etcdbin golang:$(GOLANG_VERSION) /bin/bash -c \ "git clone https://github.com/coreos/etcd /go/src/github.com/coreos/etcd \ && cd /go/src/github.com/coreos/etcd \ && git checkout v$$tag \ @@ -113,5 +115,127 @@ ifeq ($(ARCH),amd64) gcloud docker -- push $(REGISTRY)/etcd:$(REGISTRY_TAG) endif -all: build -.PHONY: build push +ETCD2_ROLLBACK_NEW_TAG=3.0.17 +ETCD2_ROLLBACK_OLD_TAG=2.2.1 + +# Test a rollback to etcd2 from the earliest etcd3 version. +test-rollback-etcd2: + mkdir -p $(TEMP_DIR)/rollback-etcd2 + cd $(TEMP_DIR)/rollback-etcd2 + + @echo "Starting $(ETCD2_ROLLBACK_NEW_TAG) etcd and writing some sample data." + docker run --tty --interactive -v $(TEMP_DIR)/rollback-etcd2:/var/etcd \ + -e "TARGET_STORAGE=etcd3" \ + -e "TARGET_VERSION=$(ETCD2_ROLLBACK_NEW_TAG)" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + 'INITIAL_CLUSTER=etcd-$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd3 START_VERSION=$(ETCD2_ROLLBACK_NEW_TAG) start_etcd && \ + ETCDCTL_API=3 /usr/local/bin/etcdctl-$(ETCD2_ROLLBACK_NEW_TAG) --endpoints http://127.0.0.1:$${ETCD_PORT} put /registry/k1 value1 && \ + stop_etcd && \ + [ $$(cat /var/etcd/data/version.txt) = $(ETCD2_ROLLBACK_NEW_TAG)/etcd3 ]' + + @echo "Rolling back to the previous version of etcd and recording keyspace to a flat file." + docker run --tty --interactive -v $(TEMP_DIR)/rollback-etcd2:/var/etcd \ + -e "TARGET_STORAGE=etcd2" \ + -e "TARGET_VERSION=$(ETCD2_ROLLBACK_OLD_TAG)" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + 'INITIAL_CLUSTER=etcd-$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd2 START_VERSION=$(ETCD2_ROLLBACK_OLD_TAG) start_etcd && \ + /usr/local/bin/etcdctl-$(ETCD2_ROLLBACK_OLD_TAG) --endpoint 127.0.0.1:$${ETCD_PORT} get /registry/k1 > /var/etcd/keyspace.txt && \ + stop_etcd' + + @echo "Checking if rollback successfully downgraded etcd to $(ETCD2_ROLLBACK_OLD_TAG)" + docker run --tty --interactive -v $(TEMP_DIR)/rollback-etcd2:/var/etcd \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + '[ $$(cat /var/etcd/data/version.txt) = $(ETCD2_ROLLBACK_OLD_TAG)/etcd2 ] && \ + grep -q value1 /var/etcd/keyspace.txt' + +# Test a rollback from the latest version to the previous version. +test-rollback: + mkdir -p $(TEMP_DIR)/rollback-test + cd $(TEMP_DIR)/rollback-test + + @echo "Starting $(REGISTRY_TAG) etcd and writing some sample data." + docker run --tty --interactive -v $(TEMP_DIR)/rollback-test:/var/etcd \ + -e "TARGET_STORAGE=etcd3" \ + -e "TARGET_VERSION=$(REGISTRY_TAG)" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + 'INITIAL_CLUSTER=etcd-$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd3 START_VERSION=$(REGISTRY_TAG) start_etcd && \ + ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints http://127.0.0.1:$${ETCD_PORT} put /registry/k1 value1 && \ + stop_etcd' + + @echo "Rolling back to the previous version of etcd and recording keyspace to a flat file." + docker run --tty --interactive -v $(TEMP_DIR)/rollback-test:/var/etcd \ + -e "TARGET_STORAGE=etcd3" \ + -e "TARGET_VERSION=$(ROLLBACK_REGISTRY_TAG)" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + 'INITIAL_CLUSTER=etcd-$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd3 START_VERSION=$(ROLLBACK_REGISTRY_TAG) start_etcd && \ + ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints http://127.0.0.1:$${ETCD_PORT} get --prefix / > /var/etcd/keyspace.txt && \ + stop_etcd' + + @echo "Checking if rollback successfully downgraded etcd to $(ROLLBACK_REGISTRY_TAG)" + docker run --tty --interactive -v $(TEMP_DIR)/rollback-test:/var/etcd \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + '[ $$(cat /var/etcd/data/version.txt) = $(ROLLBACK_REGISTRY_TAG)/etcd3 ] && \ + grep -q value1 /var/etcd/keyspace.txt' + +# Test migrating from each supported versions to the latest version. +test-migrate: + for tag in $(TAGS); do \ + echo "Testing migration from $${tag} to $(REGISTRY_TAG)" && \ + mkdir -p $(TEMP_DIR)/migrate-$${tag} && \ + cd $(TEMP_DIR)/migrate-$${tag} && \ + MAJOR_VERSION=$$(echo $${tag} | cut -c 1) && \ + echo "Starting etcd $${tag} and writing sample data to keyspace" && \ + docker run --tty --interactive -v $(TEMP_DIR)/migrate-$${tag}:/var/etcd \ + -e "TARGET_STORAGE=etcd$${MAJOR_VERSION}" \ + -e "TARGET_VERSION=$${tag}" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + "INITIAL_CLUSTER=etcd-\$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd$${MAJOR_VERSION} START_VERSION=$${tag} start_etcd && \ + if [ $${MAJOR_VERSION} == 2 ]; then \ + /usr/local/bin/etcdctl --endpoint http://127.0.0.1:\$${ETCD_PORT} set /registry/k1 value1; \ + else \ + ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints http://127.0.0.1:\$${ETCD_PORT} put /registry/k1 value1; \ + fi && \ + stop_etcd" && \ + echo " Migrating from $${tag} to $(REGISTRY_TAG) and capturing keyspace" && \ + docker run --tty --interactive -v $(TEMP_DIR)/migrate-$${tag}:/var/etcd \ + -e "TARGET_STORAGE=etcd3" \ + -e "TARGET_VERSION=$(REGISTRY_TAG)" \ + -e "DATA_DIRECTORY=/var/etcd/data" \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + 'INITIAL_CLUSTER=etcd-$$(hostname)=http://localhost:2380 \ + /usr/local/bin/migrate-if-needed.sh && \ + source /usr/local/bin/start-stop-etcd.sh && \ + START_STORAGE=etcd3 START_VERSION=$(REGISTRY_TAG) start_etcd && \ + ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints http://127.0.0.1:$${ETCD_PORT} get --prefix / > /var/etcd/keyspace.txt && \ + stop_etcd' && \ + echo "Checking if migrate from $${tag} successfully upgraded etcd to $(REGISTRY_TAG)" && \ + docker run --tty --interactive -v $(TEMP_DIR)/migrate-$${tag}:/var/etcd \ + gcr.io/google_containers/etcd-$(ARCH):$(REGISTRY_TAG) /bin/sh -c \ + '[ $$(cat /var/etcd/data/version.txt) = $(REGISTRY_TAG)/etcd3 ] && \ + grep -q value1 /var/etcd/keyspace.txt'; \ + done + +test: test-rollback test-rollback-etcd2 test-migrate + +all: build test +.PHONY: build push test-rollback test-rollback-etcd2 test-migrate test diff --git a/vendor/k8s.io/kubernetes/cluster/images/etcd/README.md b/vendor/k8s.io/kubernetes/cluster/images/etcd/README.md index e7dfde8bf6..3f87269f5f 100644 --- a/vendor/k8s.io/kubernetes/cluster/images/etcd/README.md +++ b/vendor/k8s.io/kubernetes/cluster/images/etcd/README.md @@ -7,6 +7,14 @@ For other architectures, `etcd` is cross-compiled from source. Arch-specific `bu #### How to release +First, run the migration and rollback tests. + +```console +$ make build test +``` + +Next, build and push the docker images for all supported architectures. + ```console # Build for linux/amd64 (default) $ make push ARCH=amd64 diff --git a/vendor/k8s.io/kubernetes/cluster/images/etcd/migrate-if-needed.sh b/vendor/k8s.io/kubernetes/cluster/images/etcd/migrate-if-needed.sh index 9e65f926d8..d85613b32a 100755 --- a/vendor/k8s.io/kubernetes/cluster/images/etcd/migrate-if-needed.sh +++ b/vendor/k8s.io/kubernetes/cluster/images/etcd/migrate-if-needed.sh @@ -18,7 +18,7 @@ # This script performs etcd upgrade based on the following environmental # variables: # TARGET_STORAGE - API of etcd to be used (supported: 'etcd2', 'etcd3') -# TARGET_VERSION - etcd release to be used (supported: '2.2.1', '2.3.7', '3.0.17') +# TARGET_VERSION - etcd release to be used (supported: '2.2.1', '2.3.7', '3.0.17', '3.1.11') # DATA_DIRECTORY - directory with etcd data # # The current etcd version and storage format is detected based on the @@ -28,7 +28,7 @@ # The update workflow support the following upgrade steps: # - 2.2.1/etcd2 -> 2.3.7/etcd2 # - 2.3.7/etcd2 -> 3.0.17/etcd2 -# - 3.0.17/etcd2 -> 3.0.17/etcd3 +# - 3.0.17/etcd3 -> 3.1.11/etcd3 # # NOTE: The releases supported in this script has to match release binaries # present in the etcd image (to make this script work correctly). @@ -39,6 +39,72 @@ set -o errexit set -o nounset +source $(dirname "$0")/start-stop-etcd.sh + +# Rollback to previous minor version of etcd 3.x, if needed. +# +# Warning: For HA etcd clusters (any cluster with more than one member), all members must be stopped before rolling back, zero +# downtime rollbacks are not supported. +rollback_etcd3_minor_version() { + if [ ${TARGET_MINOR_VERSION} != $((${CURRENT_MINOR_VERSION}-1)) ]; then + echo "Rollback from ${CURRENT_VERSION} to ${TARGET_VERSION} not supported, only rollbacks to the previous minor version are supported." + exit 1 + fi + echo "Performing etcd ${CURRENT_VERSION} -> ${TARGET_VERSION} rollback" + ROLLBACK_BACKUP_DIR="${DATA_DIRECTORY}.bak" + rm -rf "${ROLLBACK_BACKUP_DIR}" + SNAPSHOT_FILE="${DATA_DIRECTORY}.snapshot.db" + rm -rf "${SNAPSHOT_FILE}" + ETCD_CMD="/usr/local/bin/etcd-${CURRENT_VERSION}" + ETCDCTL_CMD="/usr/local/bin/etcdctl-${CURRENT_VERSION}" + + # Start CURRENT_VERSION of etcd. + START_VERSION="${CURRENT_VERSION}" + START_STORAGE="${CURRENT_STORAGE}" + echo "Starting etcd version ${START_VERSION} to capture rollback snapshot." + if ! start_etcd; then + echo "Unable to automatically downgrade etcd: starting etcd version ${START_VERSION} to capture rollback snapshot failed." + echo "See https://coreos.com/etcd/docs/3.1.11/op-guide/recovery.html for manual downgrade options." + exit 1 + else + ETCDCTL_API=3 ${ETCDCTL_CMD} snapshot --endpoints "http://127.0.0.1:${ETCD_PORT}" save "${SNAPSHOT_FILE}" + fi + stop_etcd + + # Backup the data before rolling back. + mv "${DATA_DIRECTORY}" "${ROLLBACK_BACKUP_DIR}" + ETCDCTL_CMD="/usr/local/bin/etcdctl-${TARGET_VERSION}" + NAME="etcd-$(hostname)" + ETCDCTL_API=3 ${ETCDCTL_CMD} snapshot restore "${SNAPSHOT_FILE}" \ + --data-dir "${DATA_DIRECTORY}" --name "${NAME}" --initial-cluster "${INITIAL_CLUSTER}" + + CURRENT_VERSION="${TARGET_VERSION}" + echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}" +} + +# Rollback from "3.0.x" version in 'etcd3' mode to "2.2.1" version in 'etcd2' mode, if needed. +rollback_to_etcd2() { + if [ "$(echo ${CURRENT_VERSION} | cut -c1-4)" != "3.0." -o "${TARGET_VERSION}" != "2.2.1" ]; then + echo "etcd3 -> etcd2 downgrade is supported only between 3.0.x and 2.2.1" + return 0 + fi + echo "Backup and remove all existing v2 data" + ROLLBACK_BACKUP_DIR="${DATA_DIRECTORY}.bak" + rm -rf "${ROLLBACK_BACKUP_DIR}" + mkdir -p "${ROLLBACK_BACKUP_DIR}" + cp -r "${DATA_DIRECTORY}" "${ROLLBACK_BACKUP_DIR}" + echo "Performing etcd3 -> etcd2 rollback" + ${ROLLBACK} --data-dir "${DATA_DIRECTORY}" + if [ "$?" -ne "0" ]; then + echo "Rollback to etcd2 failed" + exit 1 + fi + CURRENT_STORAGE="etcd2" + CURRENT_VERSION="2.2.1" + echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}" +} + + if [ -z "${TARGET_STORAGE:-}" ]; then echo "TARGET_STORAGE variable unset - unexpected failure" exit 1 @@ -51,6 +117,10 @@ if [ -z "${DATA_DIRECTORY:-}" ]; then echo "DATA_DIRECTORY variable unset - unexpected failure" exit 1 fi +if [ -z "${INITIAL_CLUSTER:-}" ]; then + echo "Warn: INITIAL_CLUSTER variable unset - defaulting to etcd-$(hostname)=http://localhost:2380" + INITIAL_CLUSTER="etcd-$(hostname)=http://localhost:2380" +fi echo "$(date +'%Y-%m-%d %H:%M:%S') Detecting if migration is needed" @@ -68,7 +138,7 @@ fi # NOTE: SUPPORTED_VERSION has to match release binaries present in the # etcd image (to make this script work correctly). # We cannot use array since sh doesn't support it. -SUPPORTED_VERSIONS_STRING="2.2.1 2.3.7 3.0.17" +SUPPORTED_VERSIONS_STRING="2.2.1 2.3.7 3.0.17 3.1.11" SUPPORTED_VERSIONS=$(echo "${SUPPORTED_VERSIONS_STRING}" | tr " " "\n") VERSION_FILE="version.txt" @@ -96,58 +166,6 @@ if [ -z "$(ls -A ${DATA_DIRECTORY})" ]; then exit 0 fi -# Starts 'etcd' version ${START_VERSION} and writes to it: -# 'etcd_version' -> "${START_VERSION}" -# Successful write confirms that etcd is up and running. -# Sets ETCD_PID at the end. -# Returns 0 if etcd was successfully started, non-0 otherwise. -start_etcd() { - # Use random ports, so that apiserver cannot connect to etcd. - ETCD_PORT=18629 - ETCD_PEER_PORT=2380 - # Avoid collisions between etcd and event-etcd. - case "${DATA_DIRECTORY}" in - *event*) - ETCD_PORT=18631 - ETCD_PEER_PORT=2381 - ;; - esac - local ETCD_CMD="${ETCD:-/usr/local/bin/etcd-${START_VERSION}}" - local ETCDCTL_CMD="${ETCDCTL:-/usr/local/bin/etcdctl-${START_VERSION}}" - local API_VERSION="$(echo ${START_STORAGE} | cut -c5-5)" - if [ "${API_VERSION}" = "2" ]; then - ETCDCTL_CMD="${ETCDCTL_CMD} --debug --endpoint=http://127.0.0.1:${ETCD_PORT} set" - else - ETCDCTL_CMD="${ETCDCTL_CMD} --endpoints=http://127.0.0.1:${ETCD_PORT} put" - fi - ${ETCD_CMD} \ - --name="etcd-$(hostname)" \ - --debug \ - --data-dir=${DATA_DIRECTORY} \ - --listen-client-urls http://127.0.0.1:${ETCD_PORT} \ - --advertise-client-urls http://127.0.0.1:${ETCD_PORT} \ - --listen-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} \ - --initial-advertise-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} & - ETCD_PID=$! - # Wait until we can write to etcd. - for i in $(seq 240); do - sleep 0.5 - ETCDCTL_API="${API_VERSION}" ${ETCDCTL_CMD} 'etcd_version' ${START_VERSION} - if [ "$?" -eq "0" ]; then - echo "Etcd on port ${ETCD_PORT} is up." - return 0 - fi - done - echo "Timeout while waiting for etcd on port ${ETCD_PORT}" - return 1 -} - -# Stops etcd with ${ETCD_PID} pid. -stop_etcd() { - kill "${ETCD_PID-}" >/dev/null 2>&1 || : - wait "${ETCD_PID-}" >/dev/null 2>&1 || : -} - ATTACHLEASE="${ATTACHLEASE:-/usr/local/bin/attachlease}" ROLLBACK="${ROLLBACK:-/usr/local/bin/rollback}" @@ -163,6 +181,24 @@ if [ "${CURRENT_VERSION}" = "2.2.1" -a "${CURRENT_VERSION}" != "${TARGET_VERSION echo "Backup done in ${BACKUP_DIR}" fi +CURRENT_MINOR_VERSION="$(echo ${CURRENT_VERSION} | awk -F'.' '{print $2}')" +TARGET_MINOR_VERSION="$(echo ${TARGET_VERSION} | awk -F'.' '{print $2}')" + +# "rollback-if-needed" +case "${CURRENT_STORAGE}-${TARGET_STORAGE}" in + "etcd3-etcd3") + [ ${TARGET_MINOR_VERSION} -lt ${CURRENT_MINOR_VERSION} ] && rollback_etcd3_minor_version + break + ;; + "etcd3-etcd2") + rollback_to_etcd2 + break + ;; + *) + break + ;; +esac + # Do the roll-forward migration if needed. # The migration goes as following: # 1. for all versions starting one after the current version of etcd @@ -227,7 +263,7 @@ for step in ${SUPPORTED_VERSIONS}; do echo "Starting etcd ${step} in v3 mode failed" exit 1 fi - ${ETCDCTL_CMD} rm --recursive "${ETCD_DATA_PREFIX}" + ${ETCDCTL_CMD} --endpoints "http://127.0.0.1:${ETCD_PORT}" rm --recursive "${ETCD_DATA_PREFIX}" # Kill etcd and wait until this is down. stop_etcd echo "Successfully remove v2 data" @@ -239,28 +275,4 @@ for step in ${SUPPORTED_VERSIONS}; do fi done -# Do the rollback of needed. -# NOTE: Rollback is only supported from "3.0.x" version in 'etcd3' mode to -# "2.2.1" version in 'etcd2' mode. -if [ "${CURRENT_STORAGE}" = "etcd3" -a "${TARGET_STORAGE}" = "etcd2" ]; then - if [ "$(echo ${CURRENT_VERSION} | cut -c1-4)" != "3.0." -o "${TARGET_VERSION}" != "2.2.1" ]; then - echo "etcd3 -> etcd2 downgrade is supported only between 3.0.x and 2.2.1" - return 0 - fi - echo "Backup and remove all existing v2 data" - ROLLBACK_BACKUP_DIR="${DATA_DIRECTORY}.bak" - rm -rf "${ROLLBACK_BACKUP_DIR}" - mkdir -p "${ROLLBACK_BACKUP_DIR}" - cp -r "${DATA_DIRECTORY}" "${ROLLBACK_BACKUP_DIR}" - echo "Performing etcd3 -> etcd2 rollback" - ${ROLLBACK} --data-dir "${DATA_DIRECTORY}" - if [ "$?" -ne "0" ]; then - echo "Rollback to etcd2 failed" - exit 1 - fi - CURRENT_STORAGE="etcd2" - CURRENT_VERSION="2.2.1" - echo "${CURRENT_VERSION}/${CURRENT_STORAGE}" > "${DATA_DIRECTORY}/${VERSION_FILE}" -fi - echo "$(date +'%Y-%m-%d %H:%M:%S') Migration finished" diff --git a/vendor/k8s.io/kubernetes/cluster/images/etcd/start-stop-etcd.sh b/vendor/k8s.io/kubernetes/cluster/images/etcd/start-stop-etcd.sh new file mode 100755 index 0000000000..5a8ba8b7f1 --- /dev/null +++ b/vendor/k8s.io/kubernetes/cluster/images/etcd/start-stop-etcd.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# Copyright 2016 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Starts 'etcd' version ${START_VERSION} and writes to it: +# 'etcd_version' -> "${START_VERSION}" +# Successful write confirms that etcd is up and running. +# Sets ETCD_PID at the end. +# Returns 0 if etcd was successfully started, non-0 otherwise. +start_etcd() { + # Use random ports, so that apiserver cannot connect to etcd. + ETCD_PORT=18629 + ETCD_PEER_PORT=2380 + # Avoid collisions between etcd and event-etcd. + case "${DATA_DIRECTORY}" in + *event*) + ETCD_PORT=18631 + ETCD_PEER_PORT=2381 + ;; + esac + local ETCD_CMD="${ETCD:-/usr/local/bin/etcd-${START_VERSION}}" + local ETCDCTL_CMD="${ETCDCTL:-/usr/local/bin/etcdctl-${START_VERSION}}" + local API_VERSION="$(echo ${START_STORAGE} | cut -c5-5)" + if [ "${API_VERSION}" = "2" ]; then + ETCDCTL_CMD="${ETCDCTL_CMD} --debug --endpoint=http://127.0.0.1:${ETCD_PORT} set" + else + ETCDCTL_CMD="${ETCDCTL_CMD} --endpoints=http://127.0.0.1:${ETCD_PORT} put" + fi + ${ETCD_CMD} \ + --name="etcd-$(hostname)" \ + --initial-cluster="etcd-$(hostname)=http://127.0.0.1:${ETCD_PEER_PORT}" \ + --debug \ + --data-dir=${DATA_DIRECTORY} \ + --listen-client-urls http://127.0.0.1:${ETCD_PORT} \ + --advertise-client-urls http://127.0.0.1:${ETCD_PORT} \ + --listen-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} \ + --initial-advertise-peer-urls http://127.0.0.1:${ETCD_PEER_PORT} & + ETCD_PID=$! + # Wait until we can write to etcd. + for i in $(seq 240); do + sleep 0.5 + ETCDCTL_API="${API_VERSION}" ${ETCDCTL_CMD} 'etcd_version' ${START_VERSION} + if [ "$?" -eq "0" ]; then + echo "Etcd on port ${ETCD_PORT} is up." + return 0 + fi + done + echo "Timeout while waiting for etcd on port ${ETCD_PORT}" + return 1 +} + +# Stops etcd with ${ETCD_PID} pid. +stop_etcd() { + kill "${ETCD_PID-}" >/dev/null 2>&1 || : + wait "${ETCD_PID-}" >/dev/null 2>&1 || : +} diff --git a/vendor/k8s.io/kubernetes/cluster/saltbase/salt/etcd/etcd.manifest b/vendor/k8s.io/kubernetes/cluster/saltbase/salt/etcd/etcd.manifest index 233598bed5..9a2585f5d6 100644 --- a/vendor/k8s.io/kubernetes/cluster/saltbase/salt/etcd/etcd.manifest +++ b/vendor/k8s.io/kubernetes/cluster/saltbase/salt/etcd/etcd.manifest @@ -60,6 +60,9 @@ }, { "name": "DATA_DIRECTORY", "value": "/var/etcd/data{{ suffix }}" + }, + { "name": "INITIAL_CLUSTER", + "value": "{{ etcd_cluster }}" } ], "livenessProbe": { diff --git a/vendor/k8s.io/kubernetes/hack/lib/golang.sh b/vendor/k8s.io/kubernetes/hack/lib/golang.sh index b9649ce6d0..84c709c5d2 100755 --- a/vendor/k8s.io/kubernetes/hack/lib/golang.sh +++ b/vendor/k8s.io/kubernetes/hack/lib/golang.sh @@ -323,7 +323,7 @@ EOF go_version=($(go version)) local minimum_go_version minimum_go_version=go1.9.1 - if [[ "${go_version[2]}" < "${minimum_go_version}" && "${go_version[2]}" != "devel" ]]; then + if [[ "${minimum_go_version}" != $(echo -e "${minimum_go_version}\n${go_version[2]}" | sort -s -t. -k 1,1 -k 2,2n -k 3,3n | head -n1) && "${go_version[2]}" != "devel" ]]; then kube::log::usage_from_stdin < 0 { - allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...) + if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeSubpath) { + allErrs = append(allErrs, field.Forbidden(fldPath.Child("subPath"), "subPath is disabled by feature-gate")) + } else { + allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...) + } } if mnt.MountPropagation != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go index 25dd774ab8..4c1d146abd 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go @@ -4456,6 +4456,68 @@ func TestValidateVolumeMounts(t *testing.T) { } } +func TestValidateDisabledSubpath(t *testing.T) { + utilfeature.DefaultFeatureGate.Set("VolumeSubpath=false") + defer utilfeature.DefaultFeatureGate.Set("VolumeSubpath=true") + + volumes := []core.Volume{ + {Name: "abc", VolumeSource: core.VolumeSource{PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ClaimName: "testclaim1"}}}, + {Name: "abc-123", VolumeSource: core.VolumeSource{PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{ClaimName: "testclaim2"}}}, + {Name: "123", VolumeSource: core.VolumeSource{HostPath: &core.HostPathVolumeSource{Path: "/foo/baz", Type: newHostPathType(string(core.HostPathUnset))}}}, + } + vols, v1err := ValidateVolumes(volumes, field.NewPath("field")) + if len(v1err) > 0 { + t.Errorf("Invalid test volume - expected success %v", v1err) + return + } + + container := core.Container{ + SecurityContext: nil, + } + + goodVolumeDevices := []core.VolumeDevice{ + {Name: "xyz", DevicePath: "/foofoo"}, + {Name: "uvw", DevicePath: "/foofoo/share/test"}, + } + + cases := map[string]struct { + mounts []core.VolumeMount + expectError bool + }{ + "subpath not specified": { + []core.VolumeMount{ + { + Name: "abc-123", + MountPath: "/bab", + }, + }, + false, + }, + "subpath specified": { + []core.VolumeMount{ + { + Name: "abc-123", + MountPath: "/bab", + SubPath: "baz", + }, + }, + true, + }, + } + + for name, test := range cases { + errs := ValidateVolumeMounts(test.mounts, GetVolumeDeviceMap(goodVolumeDevices), vols, &container, field.NewPath("field")) + + if len(errs) != 0 && !test.expectError { + t.Errorf("test %v failed: %+v", name, errs) + } + + if len(errs) == 0 && test.expectError { + t.Errorf("test %v failed, expected error", name) + } + } +} + func TestValidateMountPropagation(t *testing.T) { bTrue := true bFalse := false diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/BUILD b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/BUILD index 84de7fed6f..0da1432416 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/BUILD @@ -52,6 +52,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/client-go/tools/cache:go_default_library", "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library", diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_blobDiskController.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_blobDiskController.go index a6eda963ef..21cea1a60d 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_blobDiskController.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_blobDiskController.go @@ -91,7 +91,7 @@ func (c *BlobDiskController) CreateVolume(name, storageAccount, storageAccountTy accounts = append(accounts, accountWithLocation{Name: storageAccount}) } else { // find a storage account - accounts, err = c.common.cloud.getStorageAccounts() + accounts, err = c.common.cloud.getStorageAccounts(storageAccountType, location) if err != nil { // TODO: create a storage account and container return "", "", 0, err diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_instances.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_instances.go index 6c47089163..bea1cb2ff3 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_instances.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_instances.go @@ -111,10 +111,8 @@ func (az *Cloud) InstanceID(name types.NodeName) (string, error) { return "", err } if isLocalInstance { - externalInstanceID, err := az.metadata.Text("instance/compute/vmId") - if err == nil { - return externalInstanceID, nil - } + nodeName := mapNodeNameToVMName(name) + return az.getMachineID(nodeName), nil } } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_loadbalancer.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_loadbalancer.go index 5e28357e85..c6c60dbce7 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_loadbalancer.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_loadbalancer.go @@ -375,10 +375,12 @@ func (az *Cloud) findServiceIPAddress(clusterName string, service *v1.Service, i return "", err } if !existsLb { - return "", fmt.Errorf("Expected to find an IP address for service %s but did not", service.Name) + glog.V(2).Infof("Expected to find an IP address for service %s but did not. Assuming it has been removed", service.Name) + return "", nil } if len(lbStatus.Ingress) < 1 { - return "", fmt.Errorf("Expected to find an IP address for service %s but it had no ingresses", service.Name) + glog.V(2).Infof("Expected to find an IP address for service %s but it had no ingresses. Assuming it has been removed", service.Name) + return "", nil } return lbStatus.Ingress[0].IP, nil diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storage.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storage.go index 641fb8fd6a..5ceed1bcd2 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storage.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storage.go @@ -19,56 +19,75 @@ package azure import ( "fmt" + "github.com/Azure/azure-sdk-for-go/arm/storage" + "github.com/Azure/go-autorest/autorest/to" "github.com/golang/glog" ) +const ( + defaultStorageAccountType = string(storage.StandardLRS) + fileShareAccountNamePrefix = "f" +) + // CreateFileShare creates a file share, using a matching storage account -func (az *Cloud) CreateFileShare(name, storageAccount, storageType, location string, requestGB int) (string, string, error) { - var err error - accounts := []accountWithLocation{} - if len(storageAccount) > 0 { - accounts = append(accounts, accountWithLocation{Name: storageAccount}) - } else { - // find a storage account - accounts, err = az.getStorageAccounts() +func (az *Cloud) CreateFileShare(shareName, accountName, accountType, location string, requestGiB int) (string, string, error) { + if len(accountName) == 0 { + // find a storage account that matches accountType + accounts, err := az.getStorageAccounts(accountType, location) if err != nil { - // TODO: create a storage account and container - return "", "", err + return "", "", fmt.Errorf("could not list storage accounts for account type %s: %v", accountType, err) } - } - for _, account := range accounts { - glog.V(4).Infof("account %s type %s location %s", account.Name, account.StorageType, account.Location) - if ((storageType == "" || account.StorageType == storageType) && (location == "" || account.Location == location)) || len(storageAccount) > 0 { - // find the access key with this account - key, err := az.getStorageAccesskey(account.Name) - if err != nil { - err = fmt.Errorf("could not get storage key for storage account %s: %v", account.Name, err) - continue + + if len(accounts) > 0 { + accountName = accounts[0].Name + glog.V(4).Infof("found a matching account %s type %s location %s", accounts[0].Name, accounts[0].StorageType, accounts[0].Location) + } + + if len(accountName) == 0 { + // not found a matching account, now create a new account in current resource group + accountName = generateStorageAccountName(fileShareAccountNamePrefix) + if location == "" { + location = az.Location } + if accountType == "" { + accountType = defaultStorageAccountType + } + + glog.V(2).Infof("azureFile - no matching account found, begin to create a new account %s in resource group %s, location: %s, accountType: %s", + accountName, az.ResourceGroup, location, accountType) + cp := storage.AccountCreateParameters{ + Sku: &storage.Sku{Name: storage.SkuName(accountType)}, + Tags: &map[string]*string{"created-by": to.StringPtr("azure-file")}, + Location: &location} + cancel := make(chan struct{}) - err = az.createFileShare(account.Name, key, name, requestGB) + _, errchan := az.StorageAccountClient.Create(az.ResourceGroup, accountName, cp, cancel) + err := <-errchan if err != nil { - err = fmt.Errorf("failed to create share %s in account %s: %v", name, account.Name, err) - continue + return "", "", fmt.Errorf(fmt.Sprintf("Failed to create storage account %s, error: %s", accountName, err)) } - glog.V(4).Infof("created share %s in account %s", name, account.Name) - return account.Name, key, err } } - if err == nil { - err = fmt.Errorf("failed to find a matching storage account") + // find the access key with this account + accountKey, err := az.getStorageAccesskey(accountName) + if err != nil { + return "", "", fmt.Errorf("could not get storage key for storage account %s: %v", accountName, err) + } + + if err := az.createFileShare(accountName, accountKey, shareName, requestGiB); err != nil { + return "", "", fmt.Errorf("failed to create share %s in account %s: %v", shareName, accountName, err) } - return "", "", err + glog.V(4).Infof("created share %s in account %s", shareName, accountName) + return accountName, accountKey, nil } // DeleteFileShare deletes a file share using storage account name and key -func (az *Cloud) DeleteFileShare(accountName, key, name string) error { - err := az.deleteFileShare(accountName, key, name) - if err != nil { +func (az *Cloud) DeleteFileShare(accountName, accountKey, shareName string) error { + if err := az.deleteFileShare(accountName, accountKey, shareName); err != nil { return err } - glog.V(4).Infof("share %s deleted", name) + glog.V(4).Infof("share %s deleted", shareName) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storageaccount.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storageaccount.go index ad69c0a532..787444c941 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storageaccount.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_storageaccount.go @@ -27,8 +27,8 @@ type accountWithLocation struct { Name, StorageType, Location string } -// getStorageAccounts gets the storage accounts' name, type, location in a resource group -func (az *Cloud) getStorageAccounts() ([]accountWithLocation, error) { +// getStorageAccounts gets name, type, location of all storage accounts in a resource group which matches matchingAccountType +func (az *Cloud) getStorageAccounts(matchingAccountType, matchingLocation string) ([]accountWithLocation, error) { az.operationPollRateLimiter.Accept() glog.V(10).Infof("StorageAccountClient.ListByResourceGroup(%v): start", az.ResourceGroup) result, err := az.StorageAccountClient.ListByResourceGroup(az.ResourceGroup) @@ -37,22 +37,22 @@ func (az *Cloud) getStorageAccounts() ([]accountWithLocation, error) { return nil, err } if result.Value == nil { - return nil, fmt.Errorf("no storage accounts from resource group %s", az.ResourceGroup) + return nil, fmt.Errorf("unexpected error when listing storage accounts from resource group %s", az.ResourceGroup) } accounts := []accountWithLocation{} for _, acct := range *result.Value { - if acct.Name != nil { - name := *acct.Name - loc := "" - if acct.Location != nil { - loc = *acct.Location + if acct.Name != nil && acct.Location != nil && acct.Sku != nil { + storageType := string((*acct.Sku).Name) + if matchingAccountType != "" && !strings.EqualFold(matchingAccountType, storageType) { + continue } - storageType := "" - if acct.Sku != nil { - storageType = string((*acct.Sku).Name) + + location := *acct.Location + if matchingLocation != "" && !strings.EqualFold(matchingLocation, location) { + continue } - accounts = append(accounts, accountWithLocation{Name: name, StorageType: storageType, Location: loc}) + accounts = append(accounts, accountWithLocation{Name: *acct.Name, StorageType: storageType, Location: location}) } } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util.go index c692b64e51..01be3461fb 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util.go @@ -33,6 +33,7 @@ import ( "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/uuid" ) const ( @@ -52,6 +53,8 @@ const ( // nodeLabelRole specifies the role of a node nodeLabelRole = "kubernetes.io/role" + + storageAccountNameMaxLength = 24 ) var providerIDRE = regexp.MustCompile(`^` + CloudProviderName + `://(?:.*)/Microsoft.Compute/virtualMachines/(.+)$`) @@ -228,7 +231,7 @@ func (az *Cloud) getAgentPoolAvailabiliySets(nodes []*v1.Node) (agentPoolAvailab func (az *Cloud) mapLoadBalancerNameToAvailabilitySet(lbName string, clusterName string) (availabilitySetName string) { availabilitySetName = strings.TrimSuffix(lbName, InternalLoadBalancerNameSuffix) - if strings.EqualFold(clusterName, lbName) { + if strings.EqualFold(clusterName, availabilitySetName) { availabilitySetName = az.Config.PrimaryAvailabilitySetName } @@ -516,3 +519,13 @@ func ExtractDiskData(diskData interface{}) (provisioningState string, diskState } return provisioningState, diskState, nil } + +// get a storage account by UUID +func generateStorageAccountName(accountNamePrefix string) string { + uniqueID := strings.Replace(string(uuid.NewUUID()), "-", "", -1) + accountName := strings.ToLower(accountNamePrefix + uniqueID) + if len(accountName) > storageAccountNameMaxLength { + return accountName[:storageAccountNameMaxLength-1] + } + return accountName +} diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util_test.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util_test.go index 46f351f47b..4b1b4133c0 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util_test.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/azure/azure_util_test.go @@ -51,3 +51,75 @@ func TestGetVmssInstanceID(t *testing.T) { } } } + +func TestMapLoadBalancerNameToAvailabilitySet(t *testing.T) { + az := getTestCloud() + az.PrimaryAvailabilitySetName = "primary" + + cases := []struct { + description string + lbName string + clusterName string + expectedVMSet string + }{ + { + description: "default external LB should map to primary vmset", + lbName: "azure", + clusterName: "azure", + expectedVMSet: "primary", + }, + { + description: "default internal LB should map to primary vmset", + lbName: "azure-internal", + clusterName: "azure", + expectedVMSet: "primary", + }, + { + description: "non-default external LB should map to its own vmset", + lbName: "azuretest", + clusterName: "azure", + expectedVMSet: "azuretest", + }, + { + description: "non-default internal LB should map to its own vmset", + lbName: "azuretest-internal", + clusterName: "azure", + expectedVMSet: "azuretest", + }, + } + + for _, c := range cases { + vmset := az.mapLoadBalancerNameToAvailabilitySet(c.lbName, c.clusterName) + assert.Equal(t, c.expectedVMSet, vmset, c.description) + } +} + +func TestGenerateStorageAccountName(t *testing.T) { + tests := []struct { + prefix string + }{ + { + prefix: "", + }, + { + prefix: "pvc", + }, + { + prefix: "1234512345123451234512345", + }, + } + + for _, test := range tests { + accountName := generateStorageAccountName(test.prefix) + if len(accountName) > storageAccountNameMaxLength || len(accountName) < 3 { + t.Errorf("input prefix: %s, output account name: %s, length not in [3,%d]", test.prefix, accountName, storageAccountNameMaxLength) + } + + for _, char := range accountName { + if (char < 'a' || char > 'z') && (char < '0' || char > '9') { + t.Errorf("input prefix: %s, output account name: %s, there is non-digit or non-letter(%q)", test.prefix, accountName, char) + break + } + } + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_instances.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_instances.go index 2a17d44299..606322d65c 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_instances.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/gce/gce_instances.go @@ -26,7 +26,6 @@ import ( "cloud.google.com/go/compute/metadata" "github.com/golang/glog" - computealpha "google.golang.org/api/compute/v0.alpha" computebeta "google.golang.org/api/compute/v0.beta" compute "google.golang.org/api/compute/v1" @@ -387,7 +386,7 @@ func (gce *GCECloud) AddAliasToInstance(nodeName types.NodeName, alias *net.IPNe if err != nil { return err } - instance, err := gce.serviceAlpha.Instances.Get(gce.projectID, v1instance.Zone, v1instance.Name).Do() + instance, err := gce.serviceBeta.Instances.Get(gce.projectID, v1instance.Zone, v1instance.Name).Do() if err != nil { return err } @@ -401,14 +400,16 @@ func (gce *GCECloud) AddAliasToInstance(nodeName types.NodeName, alias *net.IPNe nodeName, instance.NetworkInterfaces) } - iface := instance.NetworkInterfaces[0] - iface.AliasIpRanges = append(iface.AliasIpRanges, &computealpha.AliasIpRange{ + iface := &computebeta.NetworkInterface{} + iface.Name = instance.NetworkInterfaces[0].Name + iface.Fingerprint = instance.NetworkInterfaces[0].Fingerprint + iface.AliasIpRanges = append(iface.AliasIpRanges, &computebeta.AliasIpRange{ IpCidrRange: alias.String(), SubnetworkRangeName: gce.secondaryRangeName, }) mc := newInstancesMetricContext("addalias", v1instance.Zone) - op, err := gce.serviceAlpha.Instances.UpdateNetworkInterface( + op, err := gce.serviceBeta.Instances.UpdateNetworkInterface( gce.projectID, lastComponent(instance.Zone), instance.Name, iface.Name, iface).Do() if err != nil { return mc.Observe(err) diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack.go index a2a517a4d3..93a6cb9a57 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "io/ioutil" + "net" "net/http" "regexp" "strings" @@ -440,7 +441,7 @@ func getAddressesByName(client *gophercloud.ServiceClient, name types.NodeName) return nodeAddresses(srv) } -func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName) (string, error) { +func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName, needIPv6 bool) (string, error) { addrs, err := getAddressesByName(client, name) if err != nil { return "", err @@ -449,12 +450,20 @@ func getAddressByName(client *gophercloud.ServiceClient, name types.NodeName) (s } for _, addr := range addrs { - if addr.Type == v1.NodeInternalIP { + isIPv6 := net.ParseIP(addr.Address).To4() == nil + if (addr.Type == v1.NodeInternalIP) && (isIPv6 == needIPv6) { return addr.Address, nil } } - return addrs[0].Address, nil + for _, addr := range addrs { + isIPv6 := net.ParseIP(addr.Address).To4() == nil + if (addr.Type == v1.NodeExternalIP) && (isIPv6 == needIPv6) { + return addr.Address, nil + } + } + // It should never return an address from a different IP Address family than the one needed + return "", ErrNoAddressFound } // getAttachedInterfacesByID returns the node interfaces of the specified instance. diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack_routes.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack_routes.go index c5f0974dad..2bffa8387d 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack_routes.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/openstack/openstack_routes.go @@ -18,6 +18,7 @@ package openstack import ( "errors" + "net" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" @@ -145,7 +146,10 @@ func (r *Routes) CreateRoute(clusterName string, nameHint string, route *cloudpr onFailure := NewCaller() - addr, err := getAddressByName(r.compute, route.TargetNode) + ip, _, _ := net.ParseCIDR(route.DestinationCIDR) + isCIDRv6 := ip.To4() == nil + addr, err := getAddressByName(r.compute, route.TargetNode, isCIDRv6) + if err != nil { return err } @@ -217,7 +221,10 @@ func (r *Routes) DeleteRoute(clusterName string, route *cloudprovider.Route) err onFailure := NewCaller() - addr, err := getAddressByName(r.compute, route.TargetNode) + ip, _, _ := net.ParseCIDR(route.DestinationCIDR) + isCIDRv6 := ip.To4() == nil + addr, err := getAddressByName(r.compute, route.TargetNode, isCIDRv6) + if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/BUILD b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/BUILD index 91de27e7ad..4237bc88f7 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/BUILD @@ -28,7 +28,6 @@ go_library( "//vendor/gopkg.in/gcfg.v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/client-go/informers:go_default_library", "//vendor/k8s.io/client-go/tools/cache:go_default_library", ], diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/nodemanager.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/nodemanager.go index a30b9135b0..770cd6d416 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/nodemanager.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/nodemanager.go @@ -33,6 +33,7 @@ type NodeInfo struct { dataCenter *vclib.Datacenter vm *vclib.VirtualMachine vcServer string + vmUUID string } type NodeManager struct { @@ -53,6 +54,7 @@ type NodeManager struct { type NodeDetails struct { NodeName string vm *vclib.VirtualMachine + VMUUID string } // TODO: Make it configurable in vsphere.conf @@ -74,7 +76,10 @@ func (nm *NodeManager) DiscoverNode(node *v1.Node) error { var globalErr *error queueChannel = make(chan *VmSearch, QUEUE_SIZE) - nodeUUID := node.Status.NodeInfo.SystemUUID + nodeUUID := GetUUIDFromProviderID(node.Spec.ProviderID) + + glog.V(4).Infof("Discovering node %s with uuid %s", node.ObjectMeta.Name, nodeUUID) + vmFound := false globalErr = nil @@ -178,7 +183,7 @@ func (nm *NodeManager) DiscoverNode(node *v1.Node) error { glog.V(4).Infof("Found node %s as vm=%+v in vc=%s and datacenter=%s", node.Name, vm, res.vc, res.datacenter.Name()) - nodeInfo := &NodeInfo{dataCenter: res.datacenter, vm: vm, vcServer: res.vc} + nodeInfo := &NodeInfo{dataCenter: res.datacenter, vm: vm, vcServer: res.vc, vmUUID: nodeUUID} nm.addNodeInfo(node.ObjectMeta.Name, nodeInfo) for range queueChannel { } @@ -311,7 +316,7 @@ func (nm *NodeManager) GetNodeDetails() ([]NodeDetails, error) { } nm.nodeInfoMap[nodeName] = n glog.V(4).Infof("Updated NodeInfo %q for node %q.", nodeInfo, nodeName) - nodeDetails = append(nodeDetails, NodeDetails{nodeName, n.vm}) + nodeDetails = append(nodeDetails, NodeDetails{nodeName, n.vm, n.vmUUID}) } return nodeDetails, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go index b3719a4506..2662230bc6 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -35,7 +35,6 @@ import ( "golang.org/x/net/context" "k8s.io/api/core/v1" k8stypes "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/informers" "k8s.io/client-go/tools/cache" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" @@ -54,8 +53,6 @@ const ( MacOuiVC = "00:50:56" MacOuiEsx = "00:0c:29" CleanUpDummyVMRoutineInterval = 5 - UUIDPath = "/sys/class/dmi/id/product_serial" - UUIDPrefix = "VMware-" ) var cleanUpRoutineInitialized = false @@ -72,6 +69,7 @@ type VSphere struct { vsphereInstanceMap map[string]*VSphereInstance // Responsible for managing discovery of k8s node, their location etc. nodeManager *NodeManager + vmUUID string } // Represents a vSphere instance where one or more kubernetes nodes are running. @@ -211,21 +209,23 @@ func init() { // Initialize passes a Kubernetes clientBuilder interface to the cloud provider func (vs *VSphere) Initialize(clientBuilder controller.ControllerClientBuilder) { +} + +// Initialize Node Informers +func (vs *VSphere) SetInformers(informerFactory informers.SharedInformerFactory) { if vs.cfg == nil { return } // Only on controller node it is required to register listeners. // Register callbacks for node updates - client := clientBuilder.ClientOrDie("vsphere-cloud-provider") - factory := informers.NewSharedInformerFactory(client, 5*time.Minute) - nodeInformer := factory.Core().V1().Nodes() - nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + glog.V(4).Infof("Setting up node informers for vSphere Cloud Provider") + nodeInformer := informerFactory.Core().V1().Nodes().Informer() + nodeInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: vs.NodeAdded, DeleteFunc: vs.NodeDeleted, }) - go nodeInformer.Informer().Run(wait.NeverStop) - glog.V(4).Infof("vSphere cloud provider initialized") + glog.V(4).Infof("Node informers in vSphere cloud provider initialized") } // Creates new worker node interface and returns @@ -237,7 +237,11 @@ func newWorkerNode() (*VSphere, error) { glog.Errorf("Failed to get hostname. err: %+v", err) return nil, err } - + vs.vmUUID, err = GetVMUUID() + if err != nil { + glog.Errorf("Failed to get uuid. err: %+v", err) + return nil, err + } return &vs, nil } @@ -403,6 +407,11 @@ func newControllerNode(cfg VSphereConfig) (*VSphere, error) { glog.Errorf("Failed to get hostname. err: %+v", err) return nil, err } + vs.vmUUID, err = GetVMUUID() + if err != nil { + glog.Errorf("Failed to get uuid. err: %+v", err) + return nil, err + } runtime.SetFinalizer(&vs, logout) return &vs, nil } @@ -584,7 +593,23 @@ func (vs *VSphere) ExternalID(nodeName k8stypes.NodeName) (string, error) { // InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running. // If false is returned with no error, the instance will be immediately deleted by the cloud controller manager. func (vs *VSphere) InstanceExistsByProviderID(providerID string) (bool, error) { - _, err := vs.InstanceID(convertToK8sType(providerID)) + var nodeName string + nodes, err := vs.nodeManager.GetNodeDetails() + if err != nil { + glog.Errorf("Error while obtaining Kubernetes node nodeVmDetail details. error : %+v", err) + return false, err + } + for _, node := range nodes { + if node.VMUUID == GetUUIDFromProviderID(providerID) { + nodeName = node.NodeName + break + } + } + if nodeName == "" { + msg := fmt.Sprintf("Error while obtaining Kubernetes nodename for providerID %s.", providerID) + return false, errors.New(msg) + } + _, err = vs.InstanceID(convertToK8sType(nodeName)) if err == nil { return true, nil } @@ -597,7 +622,7 @@ func (vs *VSphere) InstanceID(nodeName k8stypes.NodeName) (string, error) { instanceIDInternal := func() (string, error) { if vs.hostName == convertToString(nodeName) { - return vs.hostName, nil + return vs.vmUUID, nil } // Below logic can be performed only on master node where VC details are preset. @@ -631,7 +656,7 @@ func (vs *VSphere) InstanceID(nodeName k8stypes.NodeName) (string, error) { return "", err } if isActive { - return convertToString(nodeName), nil + return vs.vmUUID, nil } glog.Warningf("The VM: %s is not in %s state", convertToString(nodeName), vclib.ActivePowerState) return "", cloudprovider.InstanceNotFound diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere_util.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere_util.go index 0f4edb155a..78af14f750 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere_util.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere_util.go @@ -35,6 +35,7 @@ import ( "path/filepath" "github.com/vmware/govmomi/vim25/mo" + "k8s.io/api/core/v1" k8stypes "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" @@ -47,6 +48,11 @@ const ( Folder = "Folder" VirtualMachine = "VirtualMachine" DummyDiskName = "kube-dummyDisk.vmdk" + + UUIDPath = "/sys/class/dmi/id/product_serial" + UUIDPrefix = "VMware-" + ProviderPrefix = "vsphere://" + vSphereConfFileEnvVar = "VSPHERE_CONF_FILE" ) // GetVSphere reads vSphere configuration from system environment and construct vSphere object @@ -532,8 +538,74 @@ func (vs *VSphere) checkDiskAttached(ctx context.Context, nodes []k8stypes.NodeN if err != nil { return nodesToRetry, err } - glog.V(9).Infof("Verifying volume for nodeName: %q with nodeuuid: %s", nodeName, node.Status.NodeInfo.SystemUUID, vmMoMap) - vclib.VerifyVolumePathsForVM(vmMoMap[strings.ToLower(node.Status.NodeInfo.SystemUUID)], nodeVolumes[nodeName], convertToString(nodeName), attached) + + nodeUUID := strings.ToLower(GetUUIDFromProviderID(node.Spec.ProviderID)) + glog.V(9).Infof("Verifying volume for node %s with nodeuuid %q: %s", nodeName, nodeUUID, vmMoMap) + vclib.VerifyVolumePathsForVM(vmMoMap[nodeUUID], nodeVolumes[nodeName], convertToString(nodeName), attached) } return nodesToRetry, nil } + +func (vs *VSphere) IsDummyVMPresent(vmName string) (bool, error) { + isDummyVMPresent := false + + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + vsi, err := vs.getVSphereInstanceForServer(vs.cfg.Workspace.VCenterIP, ctx) + if err != nil { + return isDummyVMPresent, err + } + + dc, err := vclib.GetDatacenter(ctx, vsi.conn, vs.cfg.Workspace.Datacenter) + if err != nil { + return isDummyVMPresent, err + } + + vmFolder, err := dc.GetFolderByPath(ctx, vs.cfg.Workspace.Folder) + if err != nil { + return isDummyVMPresent, err + } + + vms, err := vmFolder.GetVirtualMachines(ctx) + if err != nil { + return isDummyVMPresent, err + } + + for _, vm := range vms { + if vm.Name() == vmName { + isDummyVMPresent = true + break + } + } + + return isDummyVMPresent, nil +} + +func GetVMUUID() (string, error) { + id, err := ioutil.ReadFile(UUIDPath) + if err != nil { + return "", fmt.Errorf("error retrieving vm uuid: %s", err) + } + uuidFromFile := string(id[:]) + //strip leading and trailing white space and new line char + uuid := strings.TrimSpace(uuidFromFile) + // check the uuid starts with "VMware-" + if !strings.HasPrefix(uuid, UUIDPrefix) { + return "", fmt.Errorf("Failed to match Prefix, UUID read from the file is %v", uuidFromFile) + } + // Strip the prefix and white spaces and - + uuid = strings.Replace(uuid[len(UUIDPrefix):(len(uuid))], " ", "", -1) + uuid = strings.Replace(uuid, "-", "", -1) + if len(uuid) != 32 { + return "", fmt.Errorf("Length check failed, UUID read from the file is %v", uuidFromFile) + } + // need to add dashes, e.g. "564d395e-d807-e18a-cb25-b79f65eb2b9f" + uuid = fmt.Sprintf("%s-%s-%s-%s-%s", uuid[0:8], uuid[8:12], uuid[12:16], uuid[16:20], uuid[20:32]) + return uuid, nil +} + +func GetUUIDFromProviderID(providerID string) string { + return strings.TrimPrefix(providerID, ProviderPrefix) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate.go b/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate.go index 4d2f2337d7..b6f01ef546 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate.go @@ -104,8 +104,19 @@ func oldPodsRunning(newRS *extensions.ReplicaSet, oldRSs []*extensions.ReplicaSe if newRS != nil && newRS.UID == rsUID { continue } - if len(podList.Items) > 0 { - return true + for _, pod := range podList.Items { + switch pod.Status.Phase { + case v1.PodFailed, v1.PodSucceeded: + // Don't count pods in terminal state. + continue + case v1.PodUnknown: + // This happens in situation like when the node is temporarily disconnected from the cluster. + // If we can't be sure that the pod is not running, we have to count it. + return true + default: + // Pod is not in terminal phase. + return true + } } } return false diff --git a/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate_test.go b/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate_test.go index 2cf8661780..923fd8e614 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate_test.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/deployment/recreate_test.go @@ -90,32 +90,134 @@ func TestOldPodsRunning(t *testing.T) { oldRSs []*extensions.ReplicaSet podMap map[types.UID]*v1.PodList - expected bool + hasOldPodsRunning bool }{ { - name: "no old RSs", - expected: false, + name: "no old RSs", + hasOldPodsRunning: false, }, { - name: "old RSs with running pods", - oldRSs: []*extensions.ReplicaSet{rsWithUID("some-uid"), rsWithUID("other-uid")}, - podMap: podMapWithUIDs([]string{"some-uid", "other-uid"}), - expected: true, + name: "old RSs with running pods", + oldRSs: []*extensions.ReplicaSet{rsWithUID("some-uid"), rsWithUID("other-uid")}, + podMap: podMapWithUIDs([]string{"some-uid", "other-uid"}), + hasOldPodsRunning: true, }, { - name: "old RSs without pods but with non-zero status replicas", - oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-blabla", 0, 1, nil)}, - expected: true, + name: "old RSs without pods but with non-zero status replicas", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 1, nil)}, + hasOldPodsRunning: true, }, { - name: "old RSs without pods or non-zero status replicas", - oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-blabla", 0, 0, nil)}, - expected: false, + name: "old RSs without pods or non-zero status replicas", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + hasOldPodsRunning: false, + }, + { + name: "old RSs with zero status replicas but pods in terminal state are present", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + podMap: map[types.UID]*v1.PodList{ + "uid-1": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodFailed, + }, + }, + { + Status: v1.PodStatus{ + Phase: v1.PodSucceeded, + }, + }, + }, + }, + }, + hasOldPodsRunning: false, + }, + { + name: "old RSs with zero status replicas but pod in unknown phase present", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + podMap: map[types.UID]*v1.PodList{ + "uid-1": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodUnknown, + }, + }, + }, + }, + }, + hasOldPodsRunning: true, + }, + { + name: "old RSs with zero status replicas with pending pod present", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + podMap: map[types.UID]*v1.PodList{ + "uid-1": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodPending, + }, + }, + }, + }, + }, + hasOldPodsRunning: true, + }, + { + name: "old RSs with zero status replicas with running pod present", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + podMap: map[types.UID]*v1.PodList{ + "uid-1": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodRunning, + }, + }, + }, + }, + }, + hasOldPodsRunning: true, + }, + { + name: "old RSs with zero status replicas but pods in terminal state and pending are present", + oldRSs: []*extensions.ReplicaSet{newRSWithStatus("rs-1", 0, 0, nil)}, + podMap: map[types.UID]*v1.PodList{ + "uid-1": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodFailed, + }, + }, + { + Status: v1.PodStatus{ + Phase: v1.PodSucceeded, + }, + }, + }, + }, + "uid-2": { + Items: []v1.Pod{}, + }, + "uid-3": { + Items: []v1.Pod{ + { + Status: v1.PodStatus{ + Phase: v1.PodPending, + }, + }, + }, + }, + }, + hasOldPodsRunning: true, }, } for _, test := range tests { - if expected, got := test.expected, oldPodsRunning(test.newRS, test.oldRSs, test.podMap); expected != got { + if expected, got := test.hasOldPodsRunning, oldPodsRunning(test.newRS, test.oldRSs, test.podMap); expected != got { t.Errorf("%s: expected %t, got %t", test.name, expected, got) } } diff --git a/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync.go b/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync.go index 4995f42554..eeff4a6d5f 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync.go @@ -244,9 +244,7 @@ func (op *updateOp) validateRange(ctx context.Context, sync *NodeSync, node *v1. // alias. func (op *updateOp) updateNodeFromAlias(ctx context.Context, sync *NodeSync, node *v1.Node, aliasRange *net.IPNet) error { if sync.mode != SyncFromCloud { - sync.kubeAPI.EmitNodeWarningEvent(node.Name, InvalidModeEvent, - "Cannot sync from cloud in mode %q", sync.mode) - return fmt.Errorf("cannot sync from cloud in mode %q", sync.mode) + glog.Warningf("Detect mode %q while expect to sync from cloud", sync.mode) } glog.V(2).Infof("Updating node spec with alias range, node.PodCIDR = %v", aliasRange) @@ -276,9 +274,7 @@ func (op *updateOp) updateNodeFromAlias(ctx context.Context, sync *NodeSync, nod // updateAliasFromNode updates the cloud alias given the node allocation. func (op *updateOp) updateAliasFromNode(ctx context.Context, sync *NodeSync, node *v1.Node) error { if sync.mode != SyncFromCluster { - sync.kubeAPI.EmitNodeWarningEvent( - node.Name, InvalidModeEvent, "Cannot sync to cloud in mode %q", sync.mode) - return fmt.Errorf("cannot sync to cloud in mode %q", sync.mode) + glog.Warningf("Detect mode %q while expect to sync from cluster", sync.mode) } _, aliasRange, err := net.ParseCIDR(node.Spec.PodCIDR) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync_test.go b/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync_test.go index d326848043..18e1335366 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync_test.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/node/ipam/sync/sync_test.go @@ -145,11 +145,9 @@ func TestNodeSyncUpdate(t *testing.T) { events: []fakeEvent{{"node1", "CloudCIDRAllocatorMismatch"}}, }, { - desc: "update alias from node", - mode: SyncFromCloud, - node: nodeWithCIDRRange, - events: []fakeEvent{{"node1", "CloudCIDRAllocatorInvalidMode"}}, - wantError: true, + desc: "update alias from node", + mode: SyncFromCloud, + node: nodeWithCIDRRange, }, { desc: "update alias from node", @@ -165,12 +163,10 @@ func TestNodeSyncUpdate(t *testing.T) { // XXX/bowei -- validation }, { - desc: "update node from alias", - mode: SyncFromCluster, - node: nodeWithoutCIDRRange, - fake: fakeAPIs{aliasRange: test.MustParseCIDR("10.1.2.3/16")}, - events: []fakeEvent{{"node1", "CloudCIDRAllocatorInvalidMode"}}, - wantError: true, + desc: "update node from alias", + mode: SyncFromCluster, + node: nodeWithoutCIDRRange, + fake: fakeAPIs{aliasRange: test.MustParseCIDR("10.1.2.3/16")}, }, { desc: "allocate range", diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go index 48ee40181d..fbe2a0109f 100644 --- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go @@ -219,6 +219,20 @@ const ( // // Implement IPVS-based in-cluster service load balancing SupportIPVSProxyMode utilfeature.Feature = "SupportIPVSProxyMode" + + // owner: @joelsmith + // deprecated: v1.10 + // + // Mount secret, configMap, downwardAPI and projected volumes ReadOnly. Note: this feature + // gate is present only for backward compatability, it will be removed in the 1.11 release. + ReadOnlyAPIDataVolumes utilfeature.Feature = "ReadOnlyAPIDataVolumes" + + // owner: @saad-ali + // ga + // + // Allow mounting a subpath of a volume in a container + // Do not remove this feature gate even though it's GA + VolumeSubpath utilfeature.Feature = "VolumeSubpath" ) func init() { @@ -259,6 +273,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS PVCProtection: {Default: false, PreRelease: utilfeature.Alpha}, ResourceLimitsPriorityFunction: {Default: false, PreRelease: utilfeature.Alpha}, SupportIPVSProxyMode: {Default: false, PreRelease: utilfeature.Beta}, + VolumeSubpath: {Default: true, PreRelease: utilfeature.GA}, // inherited features from generic apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: @@ -274,4 +289,5 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS // features that enable backwards compatability but are scheduled to be removed ServiceProxyAllowExternalIPs: {Default: false, PreRelease: utilfeature.Deprecated}, + ReadOnlyAPIDataVolumes: {Default: true, PreRelease: utilfeature.Deprecated}, } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux_test.go index c255967d73..3bbec062cb 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux_test.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux_test.go @@ -95,6 +95,18 @@ func (mi *fakeMountInterface) ExistsPath(pathname string) bool { return true } +func (mi *fakeMountInterface) PrepareSafeSubpath(subPath mount.Subpath) (newHostPath string, cleanupAction func(), err error) { + return "", nil, nil +} + +func (mi *fakeMountInterface) CleanSubPaths(_, _ string) error { + return nil +} + +func (mi *fakeMountInterface) SafeMakeDir(_, _ string, _ os.FileMode) error { + return nil +} + func fakeContainerMgrMountInt() mount.Interface { return &fakeMountInterface{ []mount.MountPoint{ diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go index 32dbc745b3..fc632f6342 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go @@ -46,7 +46,7 @@ type HandlerRunner interface { // RuntimeHelper wraps kubelet to make container runtime // able to get necessary informations like the RunContainerOptions, DNS settings, Host IP. type RuntimeHelper interface { - GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, err error) + GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, cleanupAction func(), err error) GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error) // GetPodCgroupParent returns the CgroupName identifer, and its literal cgroupfs form on the host // of a pod. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go index 9d41bcd287..2600f121fa 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/testing/fake_runtime_helper.go @@ -34,12 +34,12 @@ type FakeRuntimeHelper struct { Err error } -func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, error) { +func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) { var opts kubecontainer.RunContainerOptions if len(container.TerminationMessagePath) != 0 { opts.PodContainerDir = f.PodContainerDir } - return &opts, nil + return &opts, nil, nil } func (f *FakeRuntimeHelper) GetPodCgroupParent(pod *v1.Pod) string { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 35f9d8baf1..f0930e3757 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -300,9 +300,11 @@ func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ku // Restore from the checkpoint path // NOTE: This MUST happen before creating the apiserver source // below, or the checkpoint would override the source of truth. - updatechannel := cfg.Channel(kubetypes.ApiserverSource) + + var updatechannel chan<- interface{} if bootstrapCheckpointPath != "" { glog.Infof("Adding checkpoint path: %v", bootstrapCheckpointPath) + updatechannel = cfg.Channel(kubetypes.ApiserverSource) err := cfg.Restore(bootstrapCheckpointPath, updatechannel) if err != nil { return nil, err @@ -311,6 +313,9 @@ func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ku if kubeDeps.KubeClient != nil { glog.Infof("Watching apiserver") + if updatechannel == nil { + updatechannel = cfg.Channel(kubetypes.ApiserverSource) + } config.NewSourceApiserver(kubeDeps.KubeClient, nodeName, updatechannel) } return cfg, nil diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go index 6241f4ba34..a4cb85a56b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go @@ -63,6 +63,7 @@ import ( kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" utilfile "k8s.io/kubernetes/pkg/util/file" + mountutil "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/volume" volumeutil "k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util/volumehelper" @@ -163,7 +164,7 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol } // makeMounts determines the mount points for the given container. -func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap) ([]kubecontainer.Mount, error) { +func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, mounter mountutil.Interface) ([]kubecontainer.Mount, func(), error) { // Kubernetes only mounts on /etc/hosts if: // - container is not an infrastructure (pause) container // - container is not already mounting on /etc/hosts @@ -173,13 +174,14 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h mountEtcHostsFile := len(podIP) > 0 && runtime.GOOS != "windows" glog.V(3).Infof("container: %v/%v/%v podIP: %q creating hosts mount: %v", pod.Namespace, pod.Name, container.Name, podIP, mountEtcHostsFile) mounts := []kubecontainer.Mount{} - for _, mount := range container.VolumeMounts { + var cleanupAction func() = nil + for i, mount := range container.VolumeMounts { // do not mount /etc/hosts if container is already mounting on the path mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath) vol, ok := podVolumes[mount.Name] if !ok || vol.Mounter == nil { glog.Errorf("Mount cannot be satisfied for container %q, because the volume is missing or the volume mounter is nil: %+v", container.Name, mount) - return nil, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name) + return nil, cleanupAction, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name) } relabelVolume := false @@ -192,25 +194,33 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h } hostPath, err := volume.GetPath(vol.Mounter) if err != nil { - return nil, err + return nil, cleanupAction, err } if mount.SubPath != "" { + if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeSubpath) { + return nil, cleanupAction, fmt.Errorf("volume subpaths are disabled") + } + if filepath.IsAbs(mount.SubPath) { - return nil, fmt.Errorf("error SubPath `%s` must not be an absolute path", mount.SubPath) + return nil, cleanupAction, fmt.Errorf("error SubPath `%s` must not be an absolute path", mount.SubPath) } err = volumevalidation.ValidatePathNoBacksteps(mount.SubPath) if err != nil { - return nil, fmt.Errorf("unable to provision SubPath `%s`: %v", mount.SubPath, err) + return nil, cleanupAction, fmt.Errorf("unable to provision SubPath `%s`: %v", mount.SubPath, err) } fileinfo, err := os.Lstat(hostPath) if err != nil { - return nil, err + return nil, cleanupAction, err } perm := fileinfo.Mode() - hostPath = filepath.Join(hostPath, mount.SubPath) + volumePath, err := filepath.EvalSymlinks(hostPath) + if err != nil { + return nil, cleanupAction, err + } + hostPath = filepath.Join(volumePath, mount.SubPath) if subPathExists, err := utilfile.FileOrSymlinkExists(hostPath); err != nil { glog.Errorf("Could not determine if subPath %s exists; will not attempt to change its permissions", hostPath) @@ -219,17 +229,25 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h // incorrect ownership and mode. For example, the sub path directory must have at least g+rwx // when the pod specifies an fsGroup, and if the directory is not created here, Docker will // later auto-create it with the incorrect mode 0750 - if err := os.MkdirAll(hostPath, perm); err != nil { - glog.Errorf("failed to mkdir:%s", hostPath) - return nil, err - } - - // chmod the sub path because umask may have prevented us from making the sub path with the same - // permissions as the mounter path - if err := os.Chmod(hostPath, perm); err != nil { - return nil, err + // Make extra care not to escape the volume! + if err := mounter.SafeMakeDir(hostPath, volumePath, perm); err != nil { + glog.Errorf("failed to mkdir %q: %v", hostPath, err) + return nil, cleanupAction, err } } + hostPath, cleanupAction, err = mounter.PrepareSafeSubpath(mountutil.Subpath{ + VolumeMountIndex: i, + Path: hostPath, + VolumeName: mount.Name, + VolumePath: volumePath, + PodDir: podDir, + ContainerName: container.Name, + }) + if err != nil { + // Don't pass detailed error back to the user because it could give information about host filesystem + glog.Errorf("failed to prepare subPath for volumeMount %q of container %q: %v", mount.Name, container.Name, err) + return nil, cleanupAction, fmt.Errorf("failed to prepare subPath for volumeMount %q of container %q", mount.Name, container.Name) + } } // Docker Volume Mounts fail on Windows if it is not of the form C:/ @@ -245,15 +263,17 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h propagation, err := translateMountPropagation(mount.MountPropagation) if err != nil { - return nil, err + return nil, cleanupAction, err } glog.V(5).Infof("Pod %q container %q mount %q has propagation %q", format.Pod(pod), container.Name, mount.Name, propagation) + mustMountRO := vol.Mounter.GetAttributes().ReadOnly && utilfeature.DefaultFeatureGate.Enabled(features.ReadOnlyAPIDataVolumes) + mounts = append(mounts, kubecontainer.Mount{ Name: mount.Name, ContainerPath: containerPath, HostPath: hostPath, - ReadOnly: mount.ReadOnly, + ReadOnly: mount.ReadOnly || mustMountRO, SELinuxRelabel: relabelVolume, Propagation: propagation, }) @@ -262,11 +282,11 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h hostAliases := pod.Spec.HostAliases hostsMount, err := makeHostsMount(podDir, podIP, hostName, hostDomain, hostAliases, pod.Spec.HostNetwork) if err != nil { - return nil, err + return nil, cleanupAction, err } mounts = append(mounts, *hostsMount) } - return mounts, nil + return mounts, cleanupAction, nil } // translateMountPropagation transforms v1.MountPropagationMode to @@ -432,17 +452,17 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string { // GenerateRunContainerOptions generates the RunContainerOptions, which can be used by // the container runtime to set parameters for launching a container. -func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, error) { +func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) { opts, err := kl.containerManager.GetResources(pod, container) if err != nil { - return nil, err + return nil, nil, err } cgroupParent := kl.GetPodCgroupParent(pod) opts.CgroupParent = cgroupParent hostname, hostDomainName, err := kl.GeneratePodHostNameAndDomain(pod) if err != nil { - return nil, err + return nil, nil, err } opts.Hostname = hostname podName := volumehelper.GetUniquePodName(pod) @@ -452,7 +472,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai // TODO(random-liu): Move following convert functions into pkg/kubelet/container devices, err := kl.makeGPUDevices(pod, container) if err != nil { - return nil, err + return nil, nil, err } opts.Devices = append(opts.Devices, devices...) @@ -461,20 +481,20 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai blkutil := volumeutil.NewBlockVolumePathHandler() blkVolumes, err := kl.makeBlockVolumes(pod, container, volumes, blkutil) if err != nil { - return nil, err + return nil, nil, err } opts.Devices = append(opts.Devices, blkVolumes...) } - mounts, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIP, volumes) + mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIP, volumes, kl.mounter) if err != nil { - return nil, err + return nil, cleanupAction, err } opts.Mounts = append(opts.Mounts, mounts...) envs, err := kl.makeEnvironmentVariables(pod, container, podIP) if err != nil { - return nil, err + return nil, cleanupAction, err } opts.Envs = append(opts.Envs, envs...) @@ -494,7 +514,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai opts.EnableHostUserNamespace = kl.enableHostUserNamespace(pod) } - return opts, nil + return opts, cleanupAction, nil } var masterServices = sets.NewString("kubernetes") diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go index f313f80e05..1a7cf12f30 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go @@ -47,6 +47,7 @@ import ( containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" "k8s.io/kubernetes/pkg/kubelet/server/portforward" "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" + "k8s.io/kubernetes/pkg/util/mount" volumetest "k8s.io/kubernetes/pkg/volume/testing" ) @@ -303,6 +304,7 @@ func TestMakeMounts(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { + fm := &mount.FakeMounter{} pod := v1.Pod{ Spec: v1.PodSpec{ HostNetwork: true, @@ -315,7 +317,7 @@ func TestMakeMounts(t *testing.T) { return } - mounts, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes) + mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm) // validate only the error if we expect an error if tc.expectErr { @@ -338,7 +340,7 @@ func TestMakeMounts(t *testing.T) { t.Errorf("Failed to enable feature gate for MountPropagation: %v", err) return } - mounts, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes) + mounts, _, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm) if !tc.expectErr { expectedPrivateMounts := []kubecontainer.Mount{} for _, mount := range tc.expectedMounts { @@ -353,6 +355,62 @@ func TestMakeMounts(t *testing.T) { } } +func TestDisabledSubpath(t *testing.T) { + fm := &mount.FakeMounter{} + pod := v1.Pod{ + Spec: v1.PodSpec{ + HostNetwork: true, + }, + } + podVolumes := kubecontainer.VolumeMap{ + "disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/disk"}}, + } + + cases := map[string]struct { + container v1.Container + expectError bool + }{ + "subpath not specified": { + v1.Container{ + VolumeMounts: []v1.VolumeMount{ + { + MountPath: "/mnt/path3", + Name: "disk", + ReadOnly: true, + }, + }, + }, + false, + }, + "subpath specified": { + v1.Container{ + VolumeMounts: []v1.VolumeMount{ + { + MountPath: "/mnt/path3", + SubPath: "/must/not/be/absolute", + Name: "disk", + ReadOnly: true, + }, + }, + }, + true, + }, + } + + utilfeature.DefaultFeatureGate.Set("VolumeSubpath=false") + defer utilfeature.DefaultFeatureGate.Set("VolumeSubpath=true") + + for name, test := range cases { + _, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", "", podVolumes, fm) + if err != nil && !test.expectError { + t.Errorf("test %v failed: %v", name, err) + } + if err == nil && test.expectError { + t.Errorf("test %v failed: expected error", name) + } + } +} + func TestMakeBlockVolumes(t *testing.T) { testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */) defer testKubelet.Cleanup() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go index de0b6fdd7f..f0088e2a06 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -107,11 +107,15 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb restartCount = containerStatus.RestartCount + 1 } - containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef) + containerConfig, cleanupAction, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef) + if cleanupAction != nil { + defer cleanupAction() + } if err != nil { m.recordContainerEvent(pod, container, "", v1.EventTypeWarning, events.FailedToCreateContainer, "Error: %v", grpc.ErrorDesc(err)) return grpc.ErrorDesc(err), ErrCreateContainerConfig } + containerID, err := m.runtimeService.CreateContainer(podSandboxID, containerConfig, podSandboxConfig) if err != nil { m.recordContainerEvent(pod, container, containerID, v1.EventTypeWarning, events.FailedToCreateContainer, "Error: %v", grpc.ErrorDesc(err)) @@ -173,20 +177,20 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb } // generateContainerConfig generates container config for kubelet runtime v1. -func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, error) { - opts, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) +func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, func(), error) { + opts, cleanupAction, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) if err != nil { - return nil, err + return nil, nil, err } uid, username, err := m.getImageUser(container.Image) if err != nil { - return nil, err + return nil, cleanupAction, err } // Verify RunAsNonRoot. Non-root verification only supports numeric user. if err := verifyRunAsNonRoot(pod, container, uid, username); err != nil { - return nil, err + return nil, cleanupAction, err } command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs) @@ -223,7 +227,7 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Contai } config.Envs = envs - return config, nil + return config, cleanupAction, nil } // generateLinuxContainerConfig generates linux container config for kubelet runtime v1. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_test.go index c91a3a82e3..7fac95e529 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_test.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_test.go @@ -207,7 +207,7 @@ func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerInde container := &pod.Spec.Containers[containerIndex] podIP := "" restartCount := 0 - opts, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) + opts, _, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) containerLogsPath := buildContainerLogsPath(container.Name, restartCount) restartCountUint32 := uint32(restartCount) envs := make([]*runtimeapi.KeyValue, len(opts.Envs)) @@ -259,7 +259,7 @@ func TestGenerateContainerConfig(t *testing.T) { } expectedConfig := makeExpectedConfig(m, pod, 0) - containerConfig, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image) + containerConfig, _, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image) assert.NoError(t, err) assert.Equal(t, expectedConfig, containerConfig, "generate container config for kubelet runtime v1.") @@ -288,7 +288,7 @@ func TestGenerateContainerConfig(t *testing.T) { }, } - _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image) + _, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image) assert.Error(t, err) imageId, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil) @@ -300,7 +300,7 @@ func TestGenerateContainerConfig(t *testing.T) { podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsUser = nil podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsNonRoot = &runAsNonRootTrue - _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image) + _, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image) assert.Error(t, err, "RunAsNonRoot should fail for non-numeric username") } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index 85a06794ee..86d4708190 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -143,7 +143,7 @@ func makeFakeContainer(t *testing.T, m *kubeGenericRuntimeManager, template cont sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt) assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template) - containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image) + containerConfig, _, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image) assert.NoError(t, err, "generateContainerConfig for container template %+v", template) podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go index b35288b4aa..b15edf2c10 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go @@ -842,7 +842,7 @@ func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, r } // TODO: determine how this should be handled for rkt - opts, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP) + opts, _, err := r.runtimeHelper.GenerateRunContainerOptions(pod, &c, podIP) if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go index eb7cf14275..cb70c07f86 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go @@ -19,6 +19,8 @@ package util import ( "fmt" "net/url" + "path/filepath" + "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -45,3 +47,14 @@ func parseEndpoint(endpoint string) (string, string, error) { return u.Scheme, "", fmt.Errorf("protocol %q not supported", u.Scheme) } } + +func pathWithinBase(fullPath, basePath string) bool { + rel, err := filepath.Rel(basePath, fullPath) + if err != nil { + return false + } + if strings.HasPrefix(rel, "..") { + return false + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go index 5fd2e9c689..77f14ea525 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go @@ -31,3 +31,12 @@ func CreateListener(endpoint string) (net.Listener, error) { func GetAddressAndDialer(endpoint string) (string, func(addr string, timeout time.Duration) (net.Conn, error), error) { return "", nil, fmt.Errorf("GetAddressAndDialer is unsupported in this build") } + +// LockAndCheckSubPath empty implementation +func LockAndCheckSubPath(volumePath, subPath string) ([]uintptr, error) { + return []uintptr{}, nil +} + +// UnlockPath empty implementation +func UnlockPath(fileHandles []uintptr) { +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler/reconciler.go b/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler/reconciler.go index 2cb07477c7..23cc6eedfd 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler/reconciler.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler/reconciler.go @@ -179,7 +179,7 @@ func (rc *reconciler) reconcile() { glog.Errorf(mountedVolume.GenerateErrorDetailed(fmt.Sprintf("operationExecutor.NewVolumeHandler for UnmountVolume failed"), err).Error()) continue } - err = volumeHandler.UnmountVolumeHandler(mountedVolume.MountedVolume, rc.actualStateOfWorld) + err = volumeHandler.UnmountVolumeHandler(mountedVolume.MountedVolume, rc.actualStateOfWorld, rc.kubeletPodsDir) if err != nil && !nestedpendingoperations.IsAlreadyExists(err) && !exponentialbackoff.IsExponentialBackoff(err) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats.go index b6855df401..9777d88745 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats.go @@ -23,18 +23,32 @@ import ( "os" "runtime" "sync" - "syscall" "time" "unsafe" "github.com/golang/glog" cadvisorapi "github.com/google/cadvisor/info/v1" + "golang.org/x/sys/windows" "k8s.io/apimachinery/pkg/util/wait" ) +// MemoryStatusEx is the same as Windows structure MEMORYSTATUSEX +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx +type MemoryStatusEx struct { + Length uint32 + MemoryLoad uint32 + TotalPhys uint64 + AvailPhys uint64 + TotalPageFile uint64 + AvailPageFile uint64 + TotalVirtual uint64 + AvailVirtual uint64 + AvailExtendedVirtual uint64 +} + var ( - modkernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetPhysicallyInstalledSystemMemory = modkernel32.NewProc("GetPhysicallyInstalledSystemMemory") + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") ) // NewPerfCounterClient creates a client using perf counters @@ -163,20 +177,24 @@ func (p *perfCounterNodeStatsClient) convertCPUValue(cpuValue uint64) uint64 { } func getPhysicallyInstalledSystemMemoryBytes() (uint64, error) { - var physicalMemoryKiloBytes uint64 - - if ok := getPhysicallyInstalledSystemMemory(&physicalMemoryKiloBytes); !ok { + // We use GlobalMemoryStatusEx instead of GetPhysicallyInstalledSystemMemory + // on Windows node for the following reasons: + // 1. GetPhysicallyInstalledSystemMemory retrieves the amount of physically + // installed RAM from the computer's SMBIOS firmware tables. + // https://msdn.microsoft.com/en-us/library/windows/desktop/cc300158(v=vs.85).aspx + // On some VM, it is unable to read data from SMBIOS and fails with ERROR_INVALID_DATA. + // 2. On Linux node, total physical memory is read from MemTotal in /proc/meminfo. + // GlobalMemoryStatusEx returns the amount of physical memory that is available + // for the operating system to use. The amount returned by GlobalMemoryStatusEx + // is closer in parity with Linux + // https://www.kernel.org/doc/Documentation/filesystems/proc.txt + var statex MemoryStatusEx + statex.Length = uint32(unsafe.Sizeof(statex)) + ret, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&statex))) + + if ret == 0 { return 0, errors.New("unable to read physical memory") } - return physicalMemoryKiloBytes * 1024, nil // convert kilobytes to bytes -} - -func getPhysicallyInstalledSystemMemory(totalMemoryInKilobytes *uint64) bool { - ret, _, _ := syscall.Syscall(procGetPhysicallyInstalledSystemMemory.Addr(), 1, - uintptr(unsafe.Pointer(totalMemoryInKilobytes)), - 0, - 0) - - return ret != 0 + return statex.TotalPhys, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/master/tunneler/ssh.go b/vendor/k8s.io/kubernetes/pkg/master/tunneler/ssh.go index 97beb0c045..562c09adc5 100644 --- a/vendor/k8s.io/kubernetes/pkg/master/tunneler/ssh.go +++ b/vendor/k8s.io/kubernetes/pkg/master/tunneler/ssh.go @@ -59,7 +59,12 @@ func TunnelSyncHealthChecker(tunneler Tunneler) func(req *http.Request) error { return fmt.Errorf("Tunnel sync is taking too long: %d", lag) } sshKeyLag := tunneler.SecondsSinceSSHKeySync() - if sshKeyLag > 600 { + // Since we are syncing ssh-keys every 5 minutes, the allowed + // lag since last sync should be more than 2x higher than that + // to allow for single failure, which can always happen. + // For now set it to 3x, which is 15 minutes. + // For more details see: http://pr.k8s.io/59347 + if sshKeyLag > 900 { return fmt.Errorf("SSHKey sync is taking too long: %d", sshKeyLag) } return nil diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/BUILD b/vendor/k8s.io/kubernetes/pkg/util/mount/BUILD index af94fd0380..1914475e56 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/BUILD @@ -59,7 +59,17 @@ go_test( }), importpath = "k8s.io/kubernetes/pkg/util/mount", library = ":go_default_library", - deps = ["//vendor/k8s.io/utils/exec/testing:go_default_library"], + deps = [ + "//vendor/k8s.io/utils/exec/testing:go_default_library", + ] + select({ + "@io_bazel_rules_go//go/platform:linux_amd64": [ + "//vendor/github.com/golang/glog:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows_amd64": [ + "//vendor/github.com/stretchr/testify/assert:go_default_library", + ], + "//conditions:default": [], + }), ) filegroup( diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount.go b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount.go index 1dedc5b7ae..8572ff3383 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount.go @@ -20,6 +20,7 @@ package mount import ( "fmt" + "os" "github.com/golang/glog" ) @@ -138,3 +139,15 @@ func (m *execMounter) MakeDir(pathname string) error { func (m *execMounter) ExistsPath(pathname string) bool { return m.wrappedMounter.ExistsPath(pathname) } + +func (m *execMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return m.wrappedMounter.PrepareSafeSubpath(subPath) +} + +func (m *execMounter) CleanSubPaths(podDir string, volumeName string) error { + return m.wrappedMounter.CleanSubPaths(podDir, volumeName) +} + +func (m *execMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return m.wrappedMounter.SafeMakeDir(pathname, base, perm) +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_test.go b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_test.go index 5882477f71..248f49631b 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_test.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_test.go @@ -20,6 +20,7 @@ package mount import ( "fmt" + "os" "reflect" "strings" "testing" @@ -151,3 +152,14 @@ func (fm *fakeMounter) ExistsPath(pathname string) bool { func (fm *fakeMounter) GetFileType(pathname string) (FileType, error) { return FileTypeFile, nil } +func (fm *fakeMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return subPath.Path, nil, nil +} + +func (fm *fakeMounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} + +func (fm *fakeMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_unsupported.go index 136704b23e..666a57063e 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/exec_mount_unsupported.go @@ -20,6 +20,7 @@ package mount import ( "errors" + "os" ) type execMounter struct{} @@ -85,3 +86,15 @@ func (mounter *execMounter) MakeFile(pathname string) error { func (mounter *execMounter) ExistsPath(pathname string) bool { return true } + +func (mounter *execMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return subPath.Path, nil, nil +} + +func (mounter *execMounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} + +func (mounter *execMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/fake.go b/vendor/k8s.io/kubernetes/pkg/util/mount/fake.go index f4e2e411de..4bc32ff21c 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/fake.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/fake.go @@ -197,3 +197,14 @@ func (f *FakeMounter) MakeFile(pathname string) error { func (f *FakeMounter) ExistsPath(pathname string) bool { return false } + +func (f *FakeMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return subPath.Path, nil, nil +} + +func (f *FakeMounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} +func (mounter *FakeMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount.go index 953b571900..bd57421de9 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount.go @@ -19,7 +19,10 @@ limitations under the License. package mount import ( + "os" "path/filepath" + "strings" + "syscall" ) type FileType string @@ -81,9 +84,45 @@ type Interface interface { // MakeDir creates a new directory. // Will operate in the host mount namespace if kubelet is running in a container MakeDir(pathname string) error + // SafeMakeDir makes sure that the created directory does not escape given + // base directory mis-using symlinks. The directory is created in the same + // mount namespace as where kubelet is running. Note that the function makes + // sure that it creates the directory somewhere under the base, nothing + // else. E.g. if the directory already exists, it may exists outside of the + // base due to symlinks. + SafeMakeDir(pathname string, base string, perm os.FileMode) error // ExistsPath checks whether the path exists. // Will operate in the host mount namespace if kubelet is running in a container ExistsPath(pathname string) bool + // CleanSubPaths removes any bind-mounts created by PrepareSafeSubpath in given + // pod volume directory. + CleanSubPaths(podDir string, volumeName string) error + // PrepareSafeSubpath does everything that's necessary to prepare a subPath + // that's 1) inside given volumePath and 2) immutable after this call. + // + // newHostPath - location of prepared subPath. It should be used instead of + // hostName when running the container. + // cleanupAction - action to run when the container is running or it failed to start. + // + // CleanupAction must be called immediately after the container with given + // subpath starts. On the other hand, Interface.CleanSubPaths must be called + // when the pod finishes. + PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) +} + +type Subpath struct { + // index of the VolumeMount for this container + VolumeMountIndex int + // Full path to the subpath directory on the host + Path string + // name of the volume that is a valid directory name. + VolumeName string + // Full path to the volume path + VolumePath string + // Path to the pod's directory, including pod UID + PodDir string + // Name of the container + ContainerName string } // Exec executes command where mount utilities are. This can be either the host, @@ -199,6 +238,13 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e return device, refCount, nil } +func isNotDirErr(err error) bool { + if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENOTDIR { + return true + } + return false +} + // IsNotMountPoint determines if a directory is a mountpoint. // It should return ErrNotExist when the directory does not exist. // This method uses the List() of all mountpoints @@ -208,7 +254,7 @@ func IsNotMountPoint(mounter Interface, file string) (bool, error) { // IsLikelyNotMountPoint provides a quick check // to determine whether file IS A mountpoint notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file) - if notMntErr != nil { + if notMntErr != nil && isNotDirErr(notMntErr) { return notMnt, notMntErr } // identified as mountpoint, so return this fact @@ -254,3 +300,16 @@ func isBind(options []string) (bool, []string) { return bind, bindRemountOpts } + +// pathWithinBase checks if give path is withing given base directory. +func pathWithinBase(fullPath, basePath string) bool { + rel, err := filepath.Rel(basePath, fullPath) + if err != nil { + return false + } + if strings.HasPrefix(rel, "..") { + // Needed to escape the base path + return false + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go index 71064f321e..8274ee4776 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux.go @@ -20,6 +20,7 @@ package mount import ( "fmt" + "io/ioutil" "os" "os/exec" "path" @@ -48,6 +49,11 @@ const ( fsckErrorsCorrected = 1 // 'fsck' found errors but exited without correcting them fsckErrorsUncorrected = 4 + + // place for subpath mounts + containerSubPathDirectoryName = "volume-subpaths" + // syscall.Openat flags used to traverse directories not following symlinks + nofollowFlags = syscall.O_RDONLY | syscall.O_NOFOLLOW ) // Mounter provides the default implementation of mount.Interface @@ -599,6 +605,7 @@ func isShared(path string, filename string) (bool, error) { } type mountInfo struct { + // Path of the mount point mountPoint string // list of "optional parameters", mount propagation is one of them optional []string @@ -618,6 +625,7 @@ func parseMountInfo(filename string) ([]mountInfo, error) { // the last split() item is empty string following the last \n continue } + // See `man proc` for authoritative description of format of the file. fields := strings.Fields(line) if len(fields) < 7 { return nil, fmt.Errorf("wrong number of fields in (expected %d, got %d): %s", 8, len(fields), line) @@ -626,6 +634,7 @@ func parseMountInfo(filename string) ([]mountInfo, error) { mountPoint: fields[4], optional: []string{}, } + // All fields until "-" are "optional fields". for i := 6; i < len(fields) && fields[i] != "-"; i++ { info.optional = append(info.optional, fields[i]) } @@ -661,3 +670,439 @@ func doMakeRShared(path string, mountInfoFilename string) error { return nil } + +func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + newHostPath, err = doBindSubPath(mounter, subPath, os.Getpid()) + // There is no action when the container starts. Bind-mount will be cleaned + // when container stops by CleanSubPaths. + cleanupAction = nil + return newHostPath, cleanupAction, err +} + +// This implementation is shared between Linux and NsEnterMounter +// kubeletPid is PID of kubelet in the PID namespace where bind-mount is done, +// i.e. pid on the *host* if kubelet runs in a container. +func doBindSubPath(mounter Interface, subpath Subpath, kubeletPid int) (hostPath string, err error) { + // Check early for symlink. This is just a pre-check to avoid bind-mount + // before the final check. + evalSubPath, err := filepath.EvalSymlinks(subpath.Path) + if err != nil { + return "", fmt.Errorf("evalSymlinks %q failed: %v", subpath.Path, err) + } + glog.V(5).Infof("doBindSubPath %q, full subpath %q for volumepath %q", subpath.Path, evalSubPath, subpath.VolumePath) + + evalSubPath = filepath.Clean(evalSubPath) + if !pathWithinBase(evalSubPath, subpath.VolumePath) { + return "", fmt.Errorf("subpath %q not within volume path %q", evalSubPath, subpath.VolumePath) + } + + // Prepare directory for bind mounts + // containerName is DNS label, i.e. safe as a directory name. + bindDir := filepath.Join(subpath.PodDir, containerSubPathDirectoryName, subpath.VolumeName, subpath.ContainerName) + err = os.MkdirAll(bindDir, 0750) + if err != nil && !os.IsExist(err) { + return "", fmt.Errorf("error creating directory %s: %s", bindDir, err) + } + bindPathTarget := filepath.Join(bindDir, strconv.Itoa(subpath.VolumeMountIndex)) + + success := false + defer func() { + // Cleanup subpath on error + if !success { + glog.V(4).Infof("doBindSubPath() failed for %q, cleaning up subpath", bindPathTarget) + if cleanErr := cleanSubPath(mounter, subpath); cleanErr != nil { + glog.Errorf("Failed to clean subpath %q: %v", bindPathTarget, cleanErr) + } + } + }() + + // Check it's not already bind-mounted + notMount, err := IsNotMountPoint(mounter, bindPathTarget) + if err != nil { + if !os.IsNotExist(err) { + return "", fmt.Errorf("error checking path %s for mount: %s", bindPathTarget, err) + } + // Ignore ErrorNotExist: the file/directory will be created below if it does not exist yet. + notMount = true + } + if !notMount { + // It's already mounted + glog.V(5).Infof("Skipping bind-mounting subpath %s: already mounted", bindPathTarget) + success = true + return bindPathTarget, nil + } + + // Create target of the bind mount. A directory for directories, empty file + // for everything else. + t, err := os.Lstat(subpath.Path) + if err != nil { + return "", fmt.Errorf("lstat %s failed: %s", subpath.Path, err) + } + if t.Mode()&os.ModeDir > 0 { + if err = os.Mkdir(bindPathTarget, 0750); err != nil && !os.IsExist(err) { + return "", fmt.Errorf("error creating directory %s: %s", bindPathTarget, err) + } + } else { + // "/bin/touch ". + // A file is enough for all possible targets (symlink, device, pipe, + // socket, ...), bind-mounting them into a file correctly changes type + // of the target file. + if err = ioutil.WriteFile(bindPathTarget, []byte{}, 0640); err != nil { + return "", fmt.Errorf("error creating file %s: %s", bindPathTarget, err) + } + } + + // Safe open subpath and get the fd + fd, err := doSafeOpen(evalSubPath, subpath.VolumePath) + if err != nil { + return "", fmt.Errorf("error opening subpath %v: %v", evalSubPath, err) + } + defer syscall.Close(fd) + + mountSource := fmt.Sprintf("/proc/%d/fd/%v", kubeletPid, fd) + + // Do the bind mount + glog.V(5).Infof("bind mounting %q at %q", mountSource, bindPathTarget) + if err = mounter.Mount(mountSource, bindPathTarget, "" /*fstype*/, []string{"bind"}); err != nil { + return "", fmt.Errorf("error mounting %s: %s", subpath.Path, err) + } + + success = true + glog.V(3).Infof("Bound SubPath %s into %s", subpath.Path, bindPathTarget) + return bindPathTarget, nil +} + +func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { + return doCleanSubPaths(mounter, podDir, volumeName) +} + +// This implementation is shared between Linux and NsEnterMounter +func doCleanSubPaths(mounter Interface, podDir string, volumeName string) error { + glog.V(4).Infof("Cleaning up subpath mounts for %s", podDir) + // scan /var/lib/kubelet/pods//volume-subpaths//* + subPathDir := filepath.Join(podDir, containerSubPathDirectoryName, volumeName) + containerDirs, err := ioutil.ReadDir(subPathDir) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return fmt.Errorf("error reading %s: %s", subPathDir, err) + } + + for _, containerDir := range containerDirs { + if !containerDir.IsDir() { + glog.V(4).Infof("Container file is not a directory: %s", containerDir.Name()) + continue + } + glog.V(4).Infof("Cleaning up subpath mounts for container %s", containerDir.Name()) + + // scan /var/lib/kubelet/pods//volume-subpaths///* + fullContainerDirPath := filepath.Join(subPathDir, containerDir.Name()) + subPaths, err := ioutil.ReadDir(fullContainerDirPath) + if err != nil { + return fmt.Errorf("error reading %s: %s", fullContainerDirPath, err) + } + for _, subPath := range subPaths { + if err = doCleanSubPath(mounter, fullContainerDirPath, subPath.Name()); err != nil { + return err + } + } + // Whole container has been processed, remove its directory. + if err := os.Remove(fullContainerDirPath); err != nil { + return fmt.Errorf("error deleting %s: %s", fullContainerDirPath, err) + } + glog.V(5).Infof("Removed %s", fullContainerDirPath) + } + // Whole pod volume subpaths have been cleaned up, remove its subpath directory. + if err := os.Remove(subPathDir); err != nil { + return fmt.Errorf("error deleting %s: %s", subPathDir, err) + } + glog.V(5).Infof("Removed %s", subPathDir) + + // Remove entire subpath directory if it's the last one + podSubPathDir := filepath.Join(podDir, containerSubPathDirectoryName) + if err := os.Remove(podSubPathDir); err != nil && !os.IsExist(err) { + return fmt.Errorf("error deleting %s: %s", podSubPathDir, err) + } + glog.V(5).Infof("Removed %s", podSubPathDir) + return nil +} + +// doCleanSubPath tears down the single subpath bind mount +func doCleanSubPath(mounter Interface, fullContainerDirPath, subPathIndex string) error { + // process /var/lib/kubelet/pods//volume-subpaths/// + glog.V(4).Infof("Cleaning up subpath mounts for subpath %v", subPathIndex) + fullSubPath := filepath.Join(fullContainerDirPath, subPathIndex) + notMnt, err := IsNotMountPoint(mounter, fullSubPath) + if err != nil { + return fmt.Errorf("error checking %s for mount: %s", fullSubPath, err) + } + // Unmount it + if !notMnt { + if err = mounter.Unmount(fullSubPath); err != nil { + return fmt.Errorf("error unmounting %s: %s", fullSubPath, err) + } + glog.V(5).Infof("Unmounted %s", fullSubPath) + } + // Remove it *non*-recursively, just in case there were some hiccups. + if err = os.Remove(fullSubPath); err != nil { + return fmt.Errorf("error deleting %s: %s", fullSubPath, err) + } + glog.V(5).Infof("Removed %s", fullSubPath) + return nil +} + +// cleanSubPath will teardown the subpath bind mount and any remove any directories if empty +func cleanSubPath(mounter Interface, subpath Subpath) error { + containerDir := filepath.Join(subpath.PodDir, containerSubPathDirectoryName, subpath.VolumeName, subpath.ContainerName) + + // Clean subdir bindmount + if err := doCleanSubPath(mounter, containerDir, strconv.Itoa(subpath.VolumeMountIndex)); err != nil && !os.IsNotExist(err) { + return err + } + + // Recusively remove directories if empty + if err := removeEmptyDirs(subpath.PodDir, containerDir); err != nil { + return err + } + + return nil +} + +// removeEmptyDirs works backwards from endDir to baseDir and removes each directory +// if it is empty. It stops once it encounters a directory that has content +func removeEmptyDirs(baseDir, endDir string) error { + if !pathWithinBase(endDir, baseDir) { + return fmt.Errorf("endDir %q is not within baseDir %q", endDir, baseDir) + } + + for curDir := endDir; curDir != baseDir; curDir = filepath.Dir(curDir) { + s, err := os.Stat(curDir) + if err != nil { + if os.IsNotExist(err) { + glog.V(5).Infof("curDir %q doesn't exist, skipping", curDir) + continue + } + return fmt.Errorf("error stat %q: %v", curDir, err) + } + if !s.IsDir() { + return fmt.Errorf("path %q not a directory", curDir) + } + + err = os.Remove(curDir) + if os.IsExist(err) { + glog.V(5).Infof("Directory %q not empty, not removing", curDir) + break + } else if err != nil { + return fmt.Errorf("error removing directory %q: %v", curDir, err) + } + glog.V(5).Infof("Removed directory %q", curDir) + } + return nil +} + +func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return doSafeMakeDir(pathname, base, perm) +} + +// This implementation is shared between Linux and NsEnterMounter +func doSafeMakeDir(pathname string, base string, perm os.FileMode) error { + glog.V(4).Infof("Creating directory %q within base %q", pathname, base) + + if !pathWithinBase(pathname, base) { + return fmt.Errorf("path %s is outside of allowed base %s", pathname, base) + } + + // Quick check if the directory already exists + s, err := os.Stat(pathname) + if err == nil { + // Path exists + if s.IsDir() { + // The directory already exists. It can be outside of the parent, + // but there is no race-proof check. + glog.V(4).Infof("Directory %s already exists", pathname) + return nil + } + return &os.PathError{Op: "mkdir", Path: pathname, Err: syscall.ENOTDIR} + } + + // Find all existing directories + existingPath, toCreate, err := findExistingPrefix(base, pathname) + if err != nil { + return fmt.Errorf("error opening directory %s: %s", pathname, err) + } + // Ensure the existing directory is inside allowed base + fullExistingPath, err := filepath.EvalSymlinks(existingPath) + if err != nil { + return fmt.Errorf("error opening directory %s: %s", existingPath, err) + } + if !pathWithinBase(fullExistingPath, base) { + return fmt.Errorf("path %s is outside of allowed base %s", fullExistingPath, err) + } + + glog.V(4).Infof("%q already exists, %q to create", fullExistingPath, filepath.Join(toCreate...)) + parentFD, err := doSafeOpen(fullExistingPath, base) + if err != nil { + return fmt.Errorf("cannot open directory %s: %s", existingPath, err) + } + childFD := -1 + defer func() { + if parentFD != -1 { + if err = syscall.Close(parentFD); err != nil { + glog.V(4).Infof("Closing FD %v failed for safemkdir(%v): %v", parentFD, pathname, err) + } + } + if childFD != -1 { + if err = syscall.Close(childFD); err != nil { + glog.V(4).Infof("Closing FD %v failed for safemkdir(%v): %v", childFD, pathname, err) + } + } + }() + + currentPath := fullExistingPath + // create the directories one by one, making sure nobody can change + // created directory into symlink. + for _, dir := range toCreate { + currentPath = filepath.Join(currentPath, dir) + glog.V(4).Infof("Creating %s", dir) + err = syscall.Mkdirat(parentFD, currentPath, uint32(perm)) + if err != nil { + return fmt.Errorf("cannot create directory %s: %s", currentPath, err) + } + // Dive into the created directory + childFD, err := syscall.Openat(parentFD, dir, nofollowFlags, 0) + if err != nil { + return fmt.Errorf("cannot open %s: %s", currentPath, err) + } + // We can be sure that childFD is safe to use. It could be changed + // by user after Mkdirat() and before Openat(), however: + // - it could not be changed to symlink - we use nofollowFlags + // - it could be changed to a file (or device, pipe, socket, ...) + // but either subsequent Mkdirat() fails or we mount this file + // to user's container. Security is no violated in both cases + // and user either gets error or the file that it can already access. + + if err = syscall.Close(parentFD); err != nil { + glog.V(4).Infof("Closing FD %v failed for safemkdir(%v): %v", parentFD, pathname, err) + } + parentFD = childFD + childFD = -1 + } + + // Everything was created. mkdirat(..., perm) above was affected by current + // umask and we must apply the right permissions to the last directory + // (that's the one that will be available to the container as subpath) + // so user can read/write it. This is the behavior of previous code. + // TODO: chmod all created directories, not just the last one. + // parentFD is the last created directory. + if err = syscall.Fchmod(parentFD, uint32(perm)&uint32(os.ModePerm)); err != nil { + return fmt.Errorf("chmod %q failed: %s", currentPath, err) + } + return nil +} + +// findExistingPrefix finds prefix of pathname that exists. In addition, it +// returns list of remaining directories that don't exist yet. +func findExistingPrefix(base, pathname string) (string, []string, error) { + rel, err := filepath.Rel(base, pathname) + if err != nil { + return base, nil, err + } + dirs := strings.Split(rel, string(filepath.Separator)) + + // Do OpenAt in a loop to find the first non-existing dir. Resolve symlinks. + // This should be faster than looping through all dirs and calling os.Stat() + // on each of them, as the symlinks are resolved only once with OpenAt(). + currentPath := base + fd, err := syscall.Open(currentPath, syscall.O_RDONLY, 0) + if err != nil { + return pathname, nil, fmt.Errorf("error opening %s: %s", currentPath, err) + } + defer func() { + if err = syscall.Close(fd); err != nil { + glog.V(4).Infof("Closing FD %v failed for findExistingPrefix(%v): %v", fd, pathname, err) + } + }() + for i, dir := range dirs { + childFD, err := syscall.Openat(fd, dir, syscall.O_RDONLY, 0) + if err != nil { + if os.IsNotExist(err) { + return currentPath, dirs[i:], nil + } + return base, nil, err + } + if err = syscall.Close(fd); err != nil { + glog.V(4).Infof("Closing FD %v failed for findExistingPrefix(%v): %v", fd, pathname, err) + } + fd = childFD + currentPath = filepath.Join(currentPath, dir) + } + return pathname, []string{}, nil +} + +// This implementation is shared between Linux and NsEnterMounter +// Open path and return its fd. +// Symlinks are disallowed (pathname must already resolve symlinks), +// and the path must be within the base directory. +func doSafeOpen(pathname string, base string) (int, error) { + // Calculate segments to follow + subpath, err := filepath.Rel(base, pathname) + if err != nil { + return -1, err + } + segments := strings.Split(subpath, string(filepath.Separator)) + + // Assumption: base is the only directory that we have under control. + // Base dir is not allowed to be a symlink. + parentFD, err := syscall.Open(base, nofollowFlags, 0) + if err != nil { + return -1, fmt.Errorf("cannot open directory %s: %s", base, err) + } + defer func() { + if parentFD != -1 { + if err = syscall.Close(parentFD); err != nil { + glog.V(4).Infof("Closing FD %v failed for safeopen(%v): %v", parentFD, pathname, err) + } + } + }() + + childFD := -1 + defer func() { + if childFD != -1 { + if err = syscall.Close(childFD); err != nil { + glog.V(4).Infof("Closing FD %v failed for safeopen(%v): %v", childFD, pathname, err) + } + } + }() + + currentPath := base + + // Follow the segments one by one using openat() to make + // sure the user cannot change already existing directories into symlinks. + for _, seg := range segments { + currentPath = filepath.Join(currentPath, seg) + if !pathWithinBase(currentPath, base) { + return -1, fmt.Errorf("path %s is outside of allowed base %s", currentPath, base) + } + + glog.V(5).Infof("Opening path %s", currentPath) + childFD, err = syscall.Openat(parentFD, seg, nofollowFlags, 0) + if err != nil { + return -1, fmt.Errorf("cannot open %s: %s", currentPath, err) + } + + // Close parentFD + if err = syscall.Close(parentFD); err != nil { + return -1, fmt.Errorf("closing fd for %q failed: %v", filepath.Dir(currentPath), err) + } + // Set child to new parent + parentFD = childFD + childFD = -1 + } + + // We made it to the end, return this fd, don't close it + finalFD := parentFD + parentFD = -1 + + return finalFD, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux_test.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux_test.go index 6d5d6e961f..25bdfc6fe6 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux_test.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_linux_test.go @@ -19,11 +19,17 @@ limitations under the License. package mount import ( + "fmt" "io/ioutil" "os" "path/filepath" "reflect" + "syscall" "testing" + + "strconv" + + "github.com/golang/glog" ) func TestReadProcMountsFrom(t *testing.T) { @@ -322,3 +328,1203 @@ func TestIsSharedFailure(t *testing.T) { } } } + +func TestPathWithinBase(t *testing.T) { + tests := []struct { + name string + fullPath string + basePath string + expected bool + }{ + { + name: "good subpath", + fullPath: "/a/b/c", + basePath: "/a", + expected: true, + }, + { + name: "good subpath 2", + fullPath: "/a/b/c", + basePath: "/a/b", + expected: true, + }, + { + name: "good subpath end slash", + fullPath: "/a/b/c/", + basePath: "/a/b", + expected: true, + }, + { + name: "good subpath backticks", + fullPath: "/a/b/../c", + basePath: "/a", + expected: true, + }, + { + name: "good subpath equal", + fullPath: "/a/b/c", + basePath: "/a/b/c", + expected: true, + }, + { + name: "good subpath equal 2", + fullPath: "/a/b/c/", + basePath: "/a/b/c", + expected: true, + }, + { + name: "good subpath root", + fullPath: "/a", + basePath: "/", + expected: true, + }, + { + name: "bad subpath parent", + fullPath: "/a/b/c", + basePath: "/a/b/c/d", + expected: false, + }, + { + name: "bad subpath outside", + fullPath: "/b/c", + basePath: "/a/b/c", + expected: false, + }, + { + name: "bad subpath prefix", + fullPath: "/a/b/cd", + basePath: "/a/b/c", + expected: false, + }, + { + name: "bad subpath backticks", + fullPath: "/a/../b", + basePath: "/a", + expected: false, + }, + } + for _, test := range tests { + if pathWithinBase(test.fullPath, test.basePath) != test.expected { + t.Errorf("test %q failed: expected %v", test.name, test.expected) + } + + } +} + +func TestSafeMakeDir(t *testing.T) { + defaultPerm := os.FileMode(0750) + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) error + path string + checkPath string + expectError bool + }{ + { + "directory-does-not-exist", + func(base string) error { + return nil + }, + "test/directory", + "test/directory", + false, + }, + { + "directory-exists", + func(base string) error { + return os.MkdirAll(filepath.Join(base, "test/directory"), 0750) + }, + "test/directory", + "test/directory", + false, + }, + { + "create-base", + func(base string) error { + return nil + }, + "", + "", + false, + }, + { + "escape-base-using-dots", + func(base string) error { + return nil + }, + "..", + "", + true, + }, + { + "escape-base-using-dots-2", + func(base string) error { + return nil + }, + "test/../../..", + "", + true, + }, + { + "follow-symlinks", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "destination"), defaultPerm); err != nil { + return err + } + return os.Symlink("destination", filepath.Join(base, "test")) + }, + "test/directory", + "destination/directory", + false, + }, + { + "follow-symlink-loop", + func(base string) error { + return os.Symlink("test", filepath.Join(base, "test")) + }, + "test/directory", + "", + true, + }, + { + "follow-symlink-multiple follow", + func(base string) error { + /* test1/dir points to test2 and test2/dir points to test1 */ + if err := os.MkdirAll(filepath.Join(base, "test1"), defaultPerm); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(base, "test2"), defaultPerm); err != nil { + return err + } + if err := os.Symlink(filepath.Join(base, "test2"), filepath.Join(base, "test1/dir")); err != nil { + return err + } + if err := os.Symlink(filepath.Join(base, "test1"), filepath.Join(base, "test2/dir")); err != nil { + return err + } + return nil + }, + "test1/dir/dir/dir/dir/dir/dir/dir/foo", + "test2/foo", + false, + }, + { + "danglink-symlink", + func(base string) error { + return os.Symlink("non-existing", filepath.Join(base, "test")) + }, + "test/directory", + "", + true, + }, + { + "non-directory", + func(base string) error { + return ioutil.WriteFile(filepath.Join(base, "test"), []byte{}, defaultPerm) + }, + "test/directory", + "", + true, + }, + { + "non-directory-final", + func(base string) error { + return ioutil.WriteFile(filepath.Join(base, "test"), []byte{}, defaultPerm) + }, + "test", + "", + true, + }, + { + "escape-with-relative-symlink", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "dir"), defaultPerm); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(base, "exists"), defaultPerm); err != nil { + return err + } + return os.Symlink("../exists", filepath.Join(base, "dir/test")) + }, + "dir/test", + "", + false, + }, + { + "escape-with-relative-symlink-not-exists", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "dir"), defaultPerm); err != nil { + return err + } + return os.Symlink("../not-exists", filepath.Join(base, "dir/test")) + }, + "dir/test", + "", + true, + }, + { + "escape-with-symlink", + func(base string) error { + return os.Symlink("/", filepath.Join(base, "test")) + }, + "test/directory", + "", + true, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "safe-make-dir-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + test.prepare(base) + pathToCreate := filepath.Join(base, test.path) + err = doSafeMakeDir(pathToCreate, base, defaultPerm) + if err != nil && !test.expectError { + t.Errorf("test %q: %s", test.name, err) + } + if err != nil { + glog.Infof("got error: %s", err) + } + if err == nil && test.expectError { + t.Errorf("test %q: expected error, got none", test.name) + } + + if test.checkPath != "" { + if _, err := os.Stat(filepath.Join(base, test.checkPath)); err != nil { + t.Errorf("test %q: cannot read path %s", test.name, test.checkPath) + } + } + + os.RemoveAll(base) + } + +} + +func validateDirEmpty(dir string) error { + files, err := ioutil.ReadDir(dir) + if err != nil { + return err + } + + if len(files) != 0 { + return fmt.Errorf("Directory %q is not empty", dir) + } + return nil +} + +func validateDirExists(dir string) error { + _, err := ioutil.ReadDir(dir) + if err != nil { + return err + } + return nil +} + +func validateDirNotExists(dir string) error { + _, err := ioutil.ReadDir(dir) + if os.IsNotExist(err) { + return nil + } + if err != nil { + return err + } + return fmt.Errorf("dir %q still exists", dir) +} + +func validateFileExists(file string) error { + if _, err := os.Stat(file); err != nil { + return err + } + return nil +} + +func TestRemoveEmptyDirs(t *testing.T) { + defaultPerm := os.FileMode(0750) + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) error + // Function that validates directory structure after the test + validate func(base string) error + baseDir string + endDir string + expectError bool + }{ + { + name: "all-empty", + prepare: func(base string) error { + return os.MkdirAll(filepath.Join(base, "a/b/c"), defaultPerm) + }, + validate: func(base string) error { + return validateDirEmpty(filepath.Join(base, "a")) + }, + baseDir: "a", + endDir: "a/b/c", + expectError: false, + }, + { + name: "dir-not-empty", + prepare: func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "a/b/c"), defaultPerm); err != nil { + return err + } + return os.Mkdir(filepath.Join(base, "a/b/d"), defaultPerm) + }, + validate: func(base string) error { + if err := validateDirNotExists(filepath.Join(base, "a/b/c")); err != nil { + return err + } + return validateDirExists(filepath.Join(base, "a/b")) + }, + baseDir: "a", + endDir: "a/b/c", + expectError: false, + }, + { + name: "path-not-within-base", + prepare: func(base string) error { + return os.MkdirAll(filepath.Join(base, "a/b/c"), defaultPerm) + }, + validate: func(base string) error { + return validateDirExists(filepath.Join(base, "a")) + }, + baseDir: "a", + endDir: "b/c", + expectError: true, + }, + { + name: "path-already-deleted", + prepare: func(base string) error { + return nil + }, + validate: func(base string) error { + return nil + }, + baseDir: "a", + endDir: "a/b/c", + expectError: false, + }, + { + name: "path-not-dir", + prepare: func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "a/b"), defaultPerm); err != nil { + return err + } + return ioutil.WriteFile(filepath.Join(base, "a/b", "c"), []byte{}, defaultPerm) + }, + validate: func(base string) error { + if err := validateDirExists(filepath.Join(base, "a/b")); err != nil { + return err + } + return validateFileExists(filepath.Join(base, "a/b/c")) + }, + baseDir: "a", + endDir: "a/b/c", + expectError: true, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "remove-empty-dirs-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + if err = test.prepare(base); err != nil { + os.RemoveAll(base) + t.Fatalf("failed to prepare test %q: %v", test.name, err.Error()) + } + + err = removeEmptyDirs(filepath.Join(base, test.baseDir), filepath.Join(base, test.endDir)) + if err != nil && !test.expectError { + t.Errorf("test %q failed: %v", test.name, err) + } + if err == nil && test.expectError { + t.Errorf("test %q failed: expected error, got success", test.name) + } + + if err = test.validate(base); err != nil { + t.Errorf("test %q failed validation: %v", test.name, err) + } + + os.RemoveAll(base) + } +} + +func TestCleanSubPaths(t *testing.T) { + defaultPerm := os.FileMode(0750) + testVol := "vol1" + + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) ([]MountPoint, error) + // Function that validates directory structure after the test + validate func(base string) error + expectError bool + }{ + { + name: "not-exists", + prepare: func(base string) ([]MountPoint, error) { + return nil, nil + }, + validate: func(base string) error { + return nil + }, + expectError: false, + }, + { + name: "subpath-not-mount", + prepare: func(base string) ([]MountPoint, error) { + return nil, os.MkdirAll(filepath.Join(base, containerSubPathDirectoryName, testVol, "container1", "0"), defaultPerm) + }, + validate: func(base string) error { + return validateDirNotExists(filepath.Join(base, containerSubPathDirectoryName)) + }, + expectError: false, + }, + { + name: "subpath-file", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol, "container1") + if err := os.MkdirAll(path, defaultPerm); err != nil { + return nil, err + } + return nil, ioutil.WriteFile(filepath.Join(path, "0"), []byte{}, defaultPerm) + }, + validate: func(base string) error { + return validateDirNotExists(filepath.Join(base, containerSubPathDirectoryName)) + }, + expectError: false, + }, + { + name: "subpath-container-not-dir", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol) + if err := os.MkdirAll(path, defaultPerm); err != nil { + return nil, err + } + return nil, ioutil.WriteFile(filepath.Join(path, "container1"), []byte{}, defaultPerm) + }, + validate: func(base string) error { + return validateDirExists(filepath.Join(base, containerSubPathDirectoryName, testVol)) + }, + expectError: true, + }, + { + name: "subpath-multiple-container-not-dir", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol) + if err := os.MkdirAll(filepath.Join(path, "container1"), defaultPerm); err != nil { + return nil, err + } + return nil, ioutil.WriteFile(filepath.Join(path, "container2"), []byte{}, defaultPerm) + }, + validate: func(base string) error { + path := filepath.Join(base, containerSubPathDirectoryName, testVol) + if err := validateDirNotExists(filepath.Join(path, "container1")); err != nil { + return err + } + return validateFileExists(filepath.Join(path, "container2")) + }, + expectError: true, + }, + { + name: "subpath-mount", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol, "container1", "0") + if err := os.MkdirAll(path, defaultPerm); err != nil { + return nil, err + } + mounts := []MountPoint{{Device: "/dev/sdb", Path: path}} + return mounts, nil + }, + validate: func(base string) error { + return validateDirNotExists(filepath.Join(base, containerSubPathDirectoryName)) + }, + }, + { + name: "subpath-mount-multiple", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol, "container1", "0") + path2 := filepath.Join(base, containerSubPathDirectoryName, testVol, "container1", "1") + path3 := filepath.Join(base, containerSubPathDirectoryName, testVol, "container2", "1") + if err := os.MkdirAll(path, defaultPerm); err != nil { + return nil, err + } + if err := os.MkdirAll(path2, defaultPerm); err != nil { + return nil, err + } + if err := os.MkdirAll(path3, defaultPerm); err != nil { + return nil, err + } + mounts := []MountPoint{ + {Device: "/dev/sdb", Path: path}, + {Device: "/dev/sdb", Path: path3}, + } + return mounts, nil + }, + validate: func(base string) error { + return validateDirNotExists(filepath.Join(base, containerSubPathDirectoryName)) + }, + }, + { + name: "subpath-mount-multiple-vols", + prepare: func(base string) ([]MountPoint, error) { + path := filepath.Join(base, containerSubPathDirectoryName, testVol, "container1", "0") + path2 := filepath.Join(base, containerSubPathDirectoryName, "vol2", "container1", "1") + if err := os.MkdirAll(path, defaultPerm); err != nil { + return nil, err + } + if err := os.MkdirAll(path2, defaultPerm); err != nil { + return nil, err + } + mounts := []MountPoint{ + {Device: "/dev/sdb", Path: path}, + } + return mounts, nil + }, + validate: func(base string) error { + baseSubdir := filepath.Join(base, containerSubPathDirectoryName) + if err := validateDirNotExists(filepath.Join(baseSubdir, testVol)); err != nil { + return err + } + return validateDirExists(baseSubdir) + }, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "clean-subpaths-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + mounts, err := test.prepare(base) + if err != nil { + os.RemoveAll(base) + t.Fatalf("failed to prepare test %q: %v", test.name, err.Error()) + } + + fm := &FakeMounter{MountPoints: mounts} + + err = doCleanSubPaths(fm, base, testVol) + if err != nil && !test.expectError { + t.Errorf("test %q failed: %v", test.name, err) + } + if err == nil && test.expectError { + t.Errorf("test %q failed: expected error, got success", test.name) + } + if err = test.validate(base); err != nil { + t.Errorf("test %q failed validation: %v", test.name, err) + } + + os.RemoveAll(base) + } +} + +var ( + testVol = "vol1" + testPod = "pod0" + testContainer = "container0" + testSubpath = 1 +) + +func setupFakeMounter(testMounts []string) *FakeMounter { + mounts := []MountPoint{} + for _, mountPoint := range testMounts { + mounts = append(mounts, MountPoint{Device: "/foo", Path: mountPoint}) + } + return &FakeMounter{MountPoints: mounts} +} + +func getTestPaths(base string) (string, string) { + return filepath.Join(base, testVol), + filepath.Join(base, testPod, containerSubPathDirectoryName, testVol, testContainer, strconv.Itoa(testSubpath)) +} + +func TestBindSubPath(t *testing.T) { + defaultPerm := os.FileMode(0750) + + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) ([]string, string, string, error) + expectError bool + }{ + { + name: "subpath-dir", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "dir0") + return nil, volpath, subpath, os.MkdirAll(subpath, defaultPerm) + }, + expectError: false, + }, + { + name: "subpath-dir-symlink", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "dir0") + if err := os.MkdirAll(subpath, defaultPerm); err != nil { + return nil, "", "", err + } + subpathLink := filepath.Join(volpath, "dirLink") + return nil, volpath, subpath, os.Symlink(subpath, subpathLink) + }, + expectError: false, + }, + { + name: "subpath-file", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "file0") + if err := os.MkdirAll(volpath, defaultPerm); err != nil { + return nil, "", "", err + } + return nil, volpath, subpath, ioutil.WriteFile(subpath, []byte{}, defaultPerm) + }, + expectError: false, + }, + { + name: "subpath-not-exists", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "file0") + return nil, volpath, subpath, nil + }, + expectError: true, + }, + { + name: "subpath-outside", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "dir0") + if err := os.MkdirAll(volpath, defaultPerm); err != nil { + return nil, "", "", err + } + return nil, volpath, subpath, os.Symlink(base, subpath) + }, + expectError: true, + }, + { + name: "subpath-symlink-child-outside", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpathDir := filepath.Join(volpath, "dir0") + subpath := filepath.Join(subpathDir, "child0") + if err := os.MkdirAll(subpathDir, defaultPerm); err != nil { + return nil, "", "", err + } + return nil, volpath, subpath, os.Symlink(base, subpath) + }, + expectError: true, + }, + { + name: "subpath-child-outside-exists", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpathDir := filepath.Join(volpath, "dir0") + child := filepath.Join(base, "child0") + subpath := filepath.Join(subpathDir, "child0") + if err := os.MkdirAll(volpath, defaultPerm); err != nil { + return nil, "", "", err + } + // touch file outside + if err := ioutil.WriteFile(child, []byte{}, defaultPerm); err != nil { + return nil, "", "", err + } + + // create symlink for subpath dir + return nil, volpath, subpath, os.Symlink(base, subpathDir) + }, + expectError: true, + }, + { + name: "subpath-child-outside-not-exists", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpathDir := filepath.Join(volpath, "dir0") + subpath := filepath.Join(subpathDir, "child0") + if err := os.MkdirAll(volpath, defaultPerm); err != nil { + return nil, "", "", err + } + // create symlink for subpath dir + return nil, volpath, subpath, os.Symlink(base, subpathDir) + }, + expectError: true, + }, + { + name: "subpath-child-outside-exists-middle-dir-symlink", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpathDir := filepath.Join(volpath, "dir0") + symlinkDir := filepath.Join(subpathDir, "linkDir0") + child := filepath.Join(base, "child0") + subpath := filepath.Join(symlinkDir, "child0") + if err := os.MkdirAll(subpathDir, defaultPerm); err != nil { + return nil, "", "", err + } + // touch file outside + if err := ioutil.WriteFile(child, []byte{}, defaultPerm); err != nil { + return nil, "", "", err + } + + // create symlink for middle dir + return nil, volpath, subpath, os.Symlink(base, symlinkDir) + }, + expectError: true, + }, + { + name: "subpath-backstepping", + prepare: func(base string) ([]string, string, string, error) { + volpath, _ := getTestPaths(base) + subpath := filepath.Join(volpath, "dir0") + symlinkBase := filepath.Join(volpath, "..") + if err := os.MkdirAll(volpath, defaultPerm); err != nil { + return nil, "", "", err + } + + // create symlink for subpath + return nil, volpath, subpath, os.Symlink(symlinkBase, subpath) + }, + expectError: true, + }, + { + name: "subpath-mountdir-already-exists", + prepare: func(base string) ([]string, string, string, error) { + volpath, subpathMount := getTestPaths(base) + if err := os.MkdirAll(subpathMount, defaultPerm); err != nil { + return nil, "", "", err + } + + subpath := filepath.Join(volpath, "dir0") + return nil, volpath, subpath, os.MkdirAll(subpath, defaultPerm) + }, + expectError: false, + }, + { + name: "subpath-mount-already-exists", + prepare: func(base string) ([]string, string, string, error) { + volpath, subpathMount := getTestPaths(base) + mounts := []string{subpathMount} + if err := os.MkdirAll(subpathMount, defaultPerm); err != nil { + return nil, "", "", err + } + + subpath := filepath.Join(volpath, "dir0") + return mounts, volpath, subpath, os.MkdirAll(subpath, defaultPerm) + }, + expectError: false, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "bind-subpath-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + mounts, volPath, subPath, err := test.prepare(base) + if err != nil { + os.RemoveAll(base) + t.Fatalf("failed to prepare test %q: %v", test.name, err.Error()) + } + + fm := setupFakeMounter(mounts) + + subpath := Subpath{ + VolumeMountIndex: testSubpath, + Path: subPath, + VolumeName: testVol, + VolumePath: volPath, + PodDir: filepath.Join(base, "pod0"), + ContainerName: testContainer, + } + + _, subpathMount := getTestPaths(base) + bindPathTarget, err := doBindSubPath(fm, subpath, 1) + if test.expectError { + if err == nil { + t.Errorf("test %q failed: expected error, got success", test.name) + } + if bindPathTarget != "" { + t.Errorf("test %q failed: expected empty bindPathTarget, got %v", test.name, bindPathTarget) + } + if err = validateDirNotExists(subpathMount); err != nil { + t.Errorf("test %q failed: %v", test.name, err) + } + } + if !test.expectError { + if err != nil { + t.Errorf("test %q failed: %v", test.name, err) + } + if bindPathTarget != subpathMount { + t.Errorf("test %q failed: expected bindPathTarget %v, got %v", test.name, subpathMount, bindPathTarget) + } + if err = validateFileExists(subpathMount); err != nil { + t.Errorf("test %q failed: %v", test.name, err) + } + } + + os.RemoveAll(base) + } +} + +func TestParseMountInfo(t *testing.T) { + info := + `62 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered +78 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel +80 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw +82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw +83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw +227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered +224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered +76 17 8:1 / /mnt/stateful_partition rw,nosuid,nodev,noexec,relatime - ext4 /dev/sda1 rw,commit=30,data=ordered +80 17 8:1 /var /var rw,nosuid,nodev,noexec,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered +189 80 8:1 /var/lib/kubelet /var/lib/kubelet rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered +818 77 8:40 / /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered +819 78 8:48 / /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered +900 100 8:48 /dir1 /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volume-subpaths/vol1/subpath1/0 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered +901 101 8:1 /dir1 /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volume-subpaths/vol1/subpath1/1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered +902 102 8:1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volumes/kubernetes.io~empty-dir/vol1/dir1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volume-subpaths/vol1/subpath1/0 rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered +903 103 8:1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volumes/kubernetes.io~empty-dir/vol2/dir1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volume-subpaths/vol1/subpath1/1 rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered +178 25 253:0 /etc/bar /var/lib/kubelet/pods/12345/volume-subpaths/vol1/subpath1/0 rw,relatime shared:1 - ext4 /dev/sdb2 rw,errors=remount-ro,data=ordered +698 186 0:41 /tmp1/dir1 /var/lib/kubelet/pods/41135147-e697-11e7-9342-42010a800002/volume-subpaths/vol1/subpath1/0 rw shared:26 - tmpfs tmpfs rw +918 77 8:50 / /var/lib/kubelet/pods/2345/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered +919 78 8:58 / /var/lib/kubelet/pods/2345/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered +920 100 8:50 /dir1 /var/lib/kubelet/pods/2345/volume-subpaths/vol1/subpath1/0 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered +150 23 1:58 / /media/nfs_vol rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 +151 24 1:58 / /media/nfs_bindmount rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs/foo rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 +134 23 0:58 / /var/lib/kubelet/pods/43219158-e5e1-11e7-a392-0e858b8eaf40/volumes/kubernetes.io~nfs/nfs1 rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 +187 23 0:58 / /var/lib/kubelet/pods/1fc5ea21-eff4-11e7-ac80-0e858b8eaf40/volumes/kubernetes.io~nfs/nfs2 rw,relatime shared:96 - nfs4 172.18.4.223:/srv/nfs2 rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 +188 24 0:58 / /var/lib/kubelet/pods/43219158-e5e1-11e7-a392-0e858b8eaf40/volume-subpaths/nfs1/subpath1/0 rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs/foo rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 +347 60 0:71 / /var/lib/kubelet/pods/13195d46-f9fa-11e7-bbf1-5254007a695a/volumes/kubernetes.io~nfs/vol2 rw,relatime shared:170 - nfs 172.17.0.3:/exports/2 rw,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.17.0.3,mountvers=3,mountport=20048,mountproto=udp,local_lock=none,addr=172.17.0.3 +` + tempDir, filename, err := writeFile(info) + if err != nil { + t.Fatalf("cannot create temporary file: %v", err) + } + defer os.RemoveAll(tempDir) + + tests := []struct { + name string + mountPoint string + expectedInfo mountInfo + }{ + { + "simple bind mount", + "/var/lib/kubelet", + mountInfo{ + mountPoint: "/var/lib/kubelet", + optional: []string{"shared:30"}, + }, + }, + } + + infos, err := parseMountInfo(filename) + if err != nil { + t.Fatalf("Cannot parse %s: %s", filename, err) + } + + for _, test := range tests { + found := false + for _, info := range infos { + if info.mountPoint == test.mountPoint { + found = true + if !reflect.DeepEqual(info, test.expectedInfo) { + t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info) + } + break + } + } + if !found { + t.Errorf("Test case %q: mountPoint %s not found", test.name, test.mountPoint) + } + } +} + +func TestSafeOpen(t *testing.T) { + defaultPerm := os.FileMode(0750) + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) error + path string + expectError bool + }{ + { + "directory-does-not-exist", + func(base string) error { + return nil + }, + "test/directory", + true, + }, + { + "directory-exists", + func(base string) error { + return os.MkdirAll(filepath.Join(base, "test/directory"), 0750) + }, + "test/directory", + false, + }, + { + "escape-base-using-dots", + func(base string) error { + return nil + }, + "..", + true, + }, + { + "escape-base-using-dots-2", + func(base string) error { + return os.MkdirAll(filepath.Join(base, "test"), 0750) + }, + "test/../../..", + true, + }, + { + "symlink", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "destination"), defaultPerm); err != nil { + return err + } + return os.Symlink("destination", filepath.Join(base, "test")) + }, + "test", + true, + }, + { + "symlink-nested", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "dir1/dir2"), defaultPerm); err != nil { + return err + } + return os.Symlink("dir1", filepath.Join(base, "dir1/dir2/test")) + }, + "test", + true, + }, + { + "symlink-loop", + func(base string) error { + return os.Symlink("test", filepath.Join(base, "test")) + }, + "test", + true, + }, + { + "symlink-not-exists", + func(base string) error { + return os.Symlink("non-existing", filepath.Join(base, "test")) + }, + "test", + true, + }, + { + "non-directory", + func(base string) error { + return ioutil.WriteFile(filepath.Join(base, "test"), []byte{}, defaultPerm) + }, + "test/directory", + true, + }, + { + "non-directory-final", + func(base string) error { + return ioutil.WriteFile(filepath.Join(base, "test"), []byte{}, defaultPerm) + }, + "test", + false, + }, + { + "escape-with-relative-symlink", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "dir"), defaultPerm); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(base, "exists"), defaultPerm); err != nil { + return err + } + return os.Symlink("../exists", filepath.Join(base, "dir/test")) + }, + "dir/test", + true, + }, + { + "escape-with-relative-symlink-not-exists", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "dir"), defaultPerm); err != nil { + return err + } + return os.Symlink("../not-exists", filepath.Join(base, "dir/test")) + }, + "dir/test", + true, + }, + { + "escape-with-symlink", + func(base string) error { + return os.Symlink("/", filepath.Join(base, "test")) + }, + "test", + true, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "safe-open-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + test.prepare(base) + pathToCreate := filepath.Join(base, test.path) + fd, err := doSafeOpen(pathToCreate, base) + if err != nil && !test.expectError { + t.Errorf("test %q: %s", test.name, err) + } + if err != nil { + glog.Infof("got error: %s", err) + } + if err == nil && test.expectError { + t.Errorf("test %q: expected error, got none", test.name) + } + + syscall.Close(fd) + os.RemoveAll(base) + } +} + +func TestFindExistingPrefix(t *testing.T) { + defaultPerm := os.FileMode(0750) + tests := []struct { + name string + // Function that prepares directory structure for the test under given + // base. + prepare func(base string) error + path string + expectedPath string + expectedDirs []string + expectError bool + }{ + { + "directory-does-not-exist", + func(base string) error { + return nil + }, + "directory", + "", + []string{"directory"}, + false, + }, + { + "directory-exists", + func(base string) error { + return os.MkdirAll(filepath.Join(base, "test/directory"), 0750) + }, + "test/directory", + "test/directory", + []string{}, + false, + }, + { + "follow-symlinks", + func(base string) error { + if err := os.MkdirAll(filepath.Join(base, "destination/directory"), defaultPerm); err != nil { + return err + } + return os.Symlink("destination", filepath.Join(base, "test")) + }, + "test/directory", + "test/directory", + []string{}, + false, + }, + { + "follow-symlink-loop", + func(base string) error { + return os.Symlink("test", filepath.Join(base, "test")) + }, + "test/directory", + "", + nil, + true, + }, + { + "follow-symlink-multiple follow", + func(base string) error { + /* test1/dir points to test2 and test2/dir points to test1 */ + if err := os.MkdirAll(filepath.Join(base, "test1"), defaultPerm); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(base, "test2"), defaultPerm); err != nil { + return err + } + if err := os.Symlink(filepath.Join(base, "test2"), filepath.Join(base, "test1/dir")); err != nil { + return err + } + if err := os.Symlink(filepath.Join(base, "test1"), filepath.Join(base, "test2/dir")); err != nil { + return err + } + return nil + }, + "test1/dir/dir/foo/bar", + "test1/dir/dir", + []string{"foo", "bar"}, + false, + }, + { + "danglink-symlink", + func(base string) error { + return os.Symlink("non-existing", filepath.Join(base, "test")) + }, + // OS returns IsNotExist error both for dangling symlink and for + // non-existing directory. + "test/directory", + "", + []string{"test", "directory"}, + false, + }, + } + + for _, test := range tests { + glog.V(4).Infof("test %q", test.name) + base, err := ioutil.TempDir("", "find-prefix-"+test.name+"-") + if err != nil { + t.Fatalf(err.Error()) + } + test.prepare(base) + path := filepath.Join(base, test.path) + existingPath, dirs, err := findExistingPrefix(base, path) + if err != nil && !test.expectError { + t.Errorf("test %q: %s", test.name, err) + } + if err != nil { + glog.Infof("got error: %s", err) + } + if err == nil && test.expectError { + t.Errorf("test %q: expected error, got none", test.name) + } + + fullExpectedPath := filepath.Join(base, test.expectedPath) + if existingPath != fullExpectedPath { + t.Errorf("test %q: expected path %q, got %q", test.name, fullExpectedPath, existingPath) + } + if !reflect.DeepEqual(dirs, test.expectedDirs) { + t.Errorf("test %q: expected dirs %v, got %v", test.name, test.expectedDirs, dirs) + } + os.RemoveAll(base) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go index 87d1e37481..acad6eae03 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_unsupported.go @@ -20,6 +20,7 @@ package mount import ( "errors" + "os" ) type Mounter struct { @@ -108,3 +109,15 @@ func (mounter *Mounter) MakeFile(pathname string) error { func (mounter *Mounter) ExistsPath(pathname string) bool { return true } + +func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return subPath.Path, nil, nil +} + +func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} + +func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go index b39951add1..9ba4417f97 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows.go @@ -89,10 +89,7 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio cmdLine += fmt.Sprintf(";New-SmbGlobalMapping -RemotePath %s -Credential $Credential", source) if output, err := exec.Command("powershell", "/c", cmdLine).CombinedOutput(); err != nil { - // we don't return error here, even though New-SmbGlobalMapping failed, we still make it successful, - // will return error when Windows 2016 RS3 is ready on azure - glog.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output)) - return os.MkdirAll(target, 0755) + return fmt.Errorf("azureMount: SmbGlobalMapping failed: %v, only SMB mount is supported now, output: %q", err, string(output)) } } @@ -263,6 +260,123 @@ func (mounter *Mounter) ExistsPath(pathname string) bool { return true } +// check whether hostPath is within volume path +// this func will lock all intermediate subpath directories, need to close handle outside of this func after container started +func lockAndCheckSubPath(volumePath, hostPath string) ([]uintptr, error) { + if len(volumePath) == 0 || len(hostPath) == 0 { + return []uintptr{}, nil + } + + finalSubPath, err := filepath.EvalSymlinks(hostPath) + if err != nil { + return []uintptr{}, fmt.Errorf("cannot read link %s: %s", hostPath, err) + } + finalVolumePath, err := filepath.EvalSymlinks(volumePath) + if err != nil { + return []uintptr{}, fmt.Errorf("cannot read link %s: %s", volumePath, err) + } + + return lockAndCheckSubPathWithoutSymlink(finalVolumePath, finalSubPath) +} + +// lock all intermediate subPath directories and check they are all within volumePath +// volumePath & subPath should not contain any symlink, otherwise it will return error +func lockAndCheckSubPathWithoutSymlink(volumePath, subPath string) ([]uintptr, error) { + if len(volumePath) == 0 || len(subPath) == 0 { + return []uintptr{}, nil + } + + // get relative path to volumePath + relSubPath, err := filepath.Rel(volumePath, subPath) + if err != nil { + return []uintptr{}, fmt.Errorf("Rel(%s, %s) error: %v", volumePath, subPath, err) + } + if strings.HasPrefix(relSubPath, "..") { + return []uintptr{}, fmt.Errorf("SubPath %q not within volume path %q", subPath, volumePath) + } + + if relSubPath == "." { + // volumePath and subPath are equal + return []uintptr{}, nil + } + + fileHandles := []uintptr{} + var errorResult error + + currentFullPath := volumePath + dirs := strings.Split(relSubPath, string(os.PathSeparator)) + for _, dir := range dirs { + // lock intermediate subPath directory first + currentFullPath = filepath.Join(currentFullPath, dir) + handle, err := lockPath(currentFullPath) + if err != nil { + errorResult = fmt.Errorf("cannot lock path %s: %s", currentFullPath, err) + break + } + fileHandles = append(fileHandles, handle) + + // make sure intermediate subPath directory does not contain symlink any more + stat, err := os.Lstat(currentFullPath) + if err != nil { + errorResult = fmt.Errorf("Lstat(%q) error: %v", currentFullPath, err) + break + } + if stat.Mode()&os.ModeSymlink != 0 { + errorResult = fmt.Errorf("subpath %q is an unexpected symlink after EvalSymlinks", currentFullPath) + break + } + + if !pathWithinBase(currentFullPath, volumePath) { + errorResult = fmt.Errorf("SubPath %q not within volume path %q", currentFullPath, volumePath) + break + } + } + + return fileHandles, errorResult +} + +// unlockPath unlock directories +func unlockPath(fileHandles []uintptr) { + if fileHandles != nil { + for _, handle := range fileHandles { + syscall.CloseHandle(syscall.Handle(handle)) + } + } +} + +// lockPath locks a directory or symlink, return handle, exec "syscall.CloseHandle(handle)" to unlock the path +func lockPath(path string) (uintptr, error) { + if len(path) == 0 { + return uintptr(syscall.InvalidHandle), syscall.ERROR_FILE_NOT_FOUND + } + pathp, err := syscall.UTF16PtrFromString(path) + if err != nil { + return uintptr(syscall.InvalidHandle), err + } + access := uint32(syscall.GENERIC_READ) + sharemode := uint32(syscall.FILE_SHARE_READ) + createmode := uint32(syscall.OPEN_EXISTING) + flags := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS | syscall.FILE_FLAG_OPEN_REPARSE_POINT) + fd, err := syscall.CreateFile(pathp, access, sharemode, nil, createmode, flags, 0) + return uintptr(fd), err +} + +// Lock all directories in subPath and check they're not symlinks. +func (mounter *Mounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + handles, err := lockAndCheckSubPath(subPath.VolumePath, subPath.Path) + + // Unlock the directories when the container starts + cleanupAction = func() { + unlockPath(handles) + } + return subPath.Path, cleanupAction, err +} + +// No bind-mounts for subpaths are necessary on Windows +func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} + func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error { // Try to mount the disk glog.V(4).Infof("Attempting to formatAndMount disk: %s %s %s", fstype, source, target) @@ -347,3 +461,120 @@ func getAllParentLinks(path string) ([]string, error) { return links, nil } + +// SafeMakeDir makes sure that the created directory does not escape given base directory mis-using symlinks. +func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return doSafeMakeDir(pathname, base, perm) +} + +func doSafeMakeDir(pathname string, base string, perm os.FileMode) error { + glog.V(4).Infof("Creating directory %q within base %q", pathname, base) + + if !pathWithinBase(pathname, base) { + return fmt.Errorf("path %s is outside of allowed base %s", pathname, base) + } + + // Quick check if the directory already exists + s, err := os.Stat(pathname) + if err == nil { + // Path exists + if s.IsDir() { + // The directory already exists. It can be outside of the parent, + // but there is no race-proof check. + glog.V(4).Infof("Directory %s already exists", pathname) + return nil + } + return &os.PathError{Op: "mkdir", Path: pathname, Err: syscall.ENOTDIR} + } + + // Find all existing directories + existingPath, toCreate, err := findExistingPrefix(base, pathname) + if err != nil { + return fmt.Errorf("error opening directory %s: %s", pathname, err) + } + if len(toCreate) == 0 { + return nil + } + + // Ensure the existing directory is inside allowed base + fullExistingPath, err := filepath.EvalSymlinks(existingPath) + if err != nil { + return fmt.Errorf("error opening existing directory %s: %s", existingPath, err) + } + fullBasePath, err := filepath.EvalSymlinks(base) + if err != nil { + return fmt.Errorf("cannot read link %s: %s", base, err) + } + if !pathWithinBase(fullExistingPath, fullBasePath) { + return fmt.Errorf("path %s is outside of allowed base %s", fullExistingPath, err) + } + + // lock all intermediate directories from fullBasePath to fullExistingPath (top to bottom) + fileHandles, err := lockAndCheckSubPathWithoutSymlink(fullBasePath, fullExistingPath) + defer unlockPath(fileHandles) + if err != nil { + return err + } + + glog.V(4).Infof("%q already exists, %q to create", fullExistingPath, filepath.Join(toCreate...)) + currentPath := fullExistingPath + // create the directories one by one, making sure nobody can change + // created directory into symlink by lock that directory immediately + for _, dir := range toCreate { + currentPath = filepath.Join(currentPath, dir) + glog.V(4).Infof("Creating %s", dir) + if err := os.Mkdir(currentPath, perm); err != nil { + return fmt.Errorf("cannot create directory %s: %s", currentPath, err) + } + handle, err := lockPath(currentPath) + if err != nil { + return fmt.Errorf("cannot lock path %s: %s", currentPath, err) + } + defer syscall.CloseHandle(syscall.Handle(handle)) + // make sure newly created directory does not contain symlink after lock + stat, err := os.Lstat(currentPath) + if err != nil { + return fmt.Errorf("Lstat(%q) error: %v", currentPath, err) + } + if stat.Mode()&os.ModeSymlink != 0 { + return fmt.Errorf("subpath %q is an unexpected symlink after Mkdir", currentPath) + } + } + + return nil +} + +// findExistingPrefix finds prefix of pathname that exists. In addition, it +// returns list of remaining directories that don't exist yet. +func findExistingPrefix(base, pathname string) (string, []string, error) { + rel, err := filepath.Rel(base, pathname) + if err != nil { + return base, nil, err + } + + if strings.HasPrefix(rel, "..") { + return base, nil, fmt.Errorf("pathname(%s) is not within base(%s)", pathname, base) + } + + if rel == "." { + // base and pathname are equal + return pathname, []string{}, nil + } + + dirs := strings.Split(rel, string(filepath.Separator)) + + parent := base + currentPath := base + for i, dir := range dirs { + parent = currentPath + currentPath = filepath.Join(parent, dir) + if _, err := os.Lstat(currentPath); err != nil { + if os.IsNotExist(err) { + return parent, dirs[i:], nil + } + return base, nil, err + } + } + + return pathname, []string{}, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows_test.go b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows_test.go index 5855ede9ad..76ef08ccc9 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows_test.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/mount_windows_test.go @@ -20,8 +20,12 @@ package mount import ( "fmt" + "os" "os/exec" + "path/filepath" "testing" + + "github.com/stretchr/testify/assert" ) func TestNormalizeWindowsPath(t *testing.T) { @@ -132,3 +136,413 @@ func TestGetMountRefs(t *testing.T) { } } } + +func TestDoSafeMakeDir(t *testing.T) { + const testingVolumePath = `c:\tmp\DoSafeMakeDirTest` + os.MkdirAll(testingVolumePath, 0755) + defer os.RemoveAll(testingVolumePath) + + tests := []struct { + volumePath string + subPath string + expectError bool + symlinkTarget string + }{ + { + volumePath: testingVolumePath, + subPath: ``, + expectError: true, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `x`), + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\d`), + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `symlink`), + expectError: false, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `symlink\c\d`), + expectError: true, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `symlink\y926`), + expectError: true, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\symlink`), + expectError: false, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\x\symlink`), + expectError: false, + symlinkTarget: filepath.Join(testingVolumePath, `a`), + }, + } + + for _, test := range tests { + if len(test.volumePath) > 0 && len(test.subPath) > 0 && len(test.symlinkTarget) > 0 { + // make all parent sub directories + if parent := filepath.Dir(test.subPath); parent != "." { + os.MkdirAll(parent, 0755) + } + + // make last element as symlink + linkPath := test.subPath + if _, err := os.Stat(linkPath); err != nil && os.IsNotExist(err) { + if err := makeLink(linkPath, test.symlinkTarget); err != nil { + t.Fatalf("unexpected error: %v", fmt.Errorf("mklink link(%q) target(%q) error: %q", linkPath, test.symlinkTarget, err)) + } + } + } + + err := doSafeMakeDir(test.subPath, test.volumePath, os.FileMode(0755)) + if test.expectError { + assert.NotNil(t, err, "Expect error during doSafeMakeDir(%s, %s)", test.subPath, test.volumePath) + continue + } + assert.Nil(t, err, "Expect no error during doSafeMakeDir(%s, %s)", test.subPath, test.volumePath) + if _, err := os.Stat(test.subPath); os.IsNotExist(err) { + t.Errorf("subPath should exists after doSafeMakeDir(%s, %s)", test.subPath, test.volumePath) + } + } +} + +func TestLockAndCheckSubPath(t *testing.T) { + const testingVolumePath = `c:\tmp\LockAndCheckSubPathTest` + + tests := []struct { + volumePath string + subPath string + expectedHandleCount int + expectError bool + symlinkTarget string + }{ + { + volumePath: `c:\`, + subPath: ``, + expectedHandleCount: 0, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: ``, + subPath: `a`, + expectedHandleCount: 0, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a`), + expectedHandleCount: 1, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\d`), + expectedHandleCount: 4, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `symlink`), + expectedHandleCount: 0, + expectError: true, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\symlink`), + expectedHandleCount: 0, + expectError: true, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\d\symlink`), + expectedHandleCount: 2, + expectError: false, + symlinkTarget: filepath.Join(testingVolumePath, `a\b`), + }, + } + + for _, test := range tests { + if len(test.volumePath) > 0 && len(test.subPath) > 0 { + os.MkdirAll(test.volumePath, 0755) + if len(test.symlinkTarget) == 0 { + // make all intermediate sub directories + os.MkdirAll(test.subPath, 0755) + } else { + // make all parent sub directories + if parent := filepath.Dir(test.subPath); parent != "." { + os.MkdirAll(parent, 0755) + } + + // make last element as symlink + linkPath := test.subPath + if _, err := os.Stat(linkPath); err != nil && os.IsNotExist(err) { + if err := makeLink(linkPath, test.symlinkTarget); err != nil { + t.Fatalf("unexpected error: %v", fmt.Errorf("mklink link(%q) target(%q) error: %q", linkPath, test.symlinkTarget, err)) + } + } + } + } + + fileHandles, err := lockAndCheckSubPath(test.volumePath, test.subPath) + unlockPath(fileHandles) + assert.Equal(t, test.expectedHandleCount, len(fileHandles)) + if test.expectError { + assert.NotNil(t, err, "Expect error during LockAndCheckSubPath(%s, %s)", test.volumePath, test.subPath) + continue + } + assert.Nil(t, err, "Expect no error during LockAndCheckSubPath(%s, %s)", test.volumePath, test.subPath) + } + + // remove dir will happen after closing all file handles + assert.Nil(t, os.RemoveAll(testingVolumePath), "Expect no error during remove dir %s", testingVolumePath) +} + +func TestLockAndCheckSubPathWithoutSymlink(t *testing.T) { + const testingVolumePath = `c:\tmp\LockAndCheckSubPathWithoutSymlinkTest` + + tests := []struct { + volumePath string + subPath string + expectedHandleCount int + expectError bool + symlinkTarget string + }{ + { + volumePath: `c:\`, + subPath: ``, + expectedHandleCount: 0, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: ``, + subPath: `a`, + expectedHandleCount: 0, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a`), + expectedHandleCount: 1, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\d`), + expectedHandleCount: 4, + expectError: false, + symlinkTarget: "", + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `symlink`), + expectedHandleCount: 1, + expectError: true, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\symlink`), + expectedHandleCount: 4, + expectError: true, + symlinkTarget: `c:\tmp`, + }, + { + volumePath: testingVolumePath, + subPath: filepath.Join(testingVolumePath, `a\b\c\d\symlink`), + expectedHandleCount: 5, + expectError: true, + symlinkTarget: filepath.Join(testingVolumePath, `a\b`), + }, + } + + for _, test := range tests { + if len(test.volumePath) > 0 && len(test.subPath) > 0 { + os.MkdirAll(test.volumePath, 0755) + if len(test.symlinkTarget) == 0 { + // make all intermediate sub directories + os.MkdirAll(test.subPath, 0755) + } else { + // make all parent sub directories + if parent := filepath.Dir(test.subPath); parent != "." { + os.MkdirAll(parent, 0755) + } + + // make last element as symlink + linkPath := test.subPath + if _, err := os.Stat(linkPath); err != nil && os.IsNotExist(err) { + if err := makeLink(linkPath, test.symlinkTarget); err != nil { + t.Fatalf("unexpected error: %v", fmt.Errorf("mklink link(%q) target(%q) error: %q", linkPath, test.symlinkTarget, err)) + } + } + } + } + + fileHandles, err := lockAndCheckSubPathWithoutSymlink(test.volumePath, test.subPath) + unlockPath(fileHandles) + assert.Equal(t, test.expectedHandleCount, len(fileHandles)) + if test.expectError { + assert.NotNil(t, err, "Expect error during LockAndCheckSubPath(%s, %s)", test.volumePath, test.subPath) + continue + } + assert.Nil(t, err, "Expect no error during LockAndCheckSubPath(%s, %s)", test.volumePath, test.subPath) + } + + // remove dir will happen after closing all file handles + assert.Nil(t, os.RemoveAll(testingVolumePath), "Expect no error during remove dir %s", testingVolumePath) +} + +func TestFindExistingPrefix(t *testing.T) { + const testingVolumePath = `c:\tmp\FindExistingPrefixTest` + + tests := []struct { + base string + pathname string + expectError bool + expectedExistingPath string + expectedToCreateDirs []string + createSubPathBeforeTest bool + }{ + { + base: `c:\tmp\a`, + pathname: `c:\tmp\b`, + expectError: true, + expectedExistingPath: "", + expectedToCreateDirs: []string{}, + createSubPathBeforeTest: false, + }, + { + base: ``, + pathname: `c:\tmp\b`, + expectError: true, + expectedExistingPath: "", + expectedToCreateDirs: []string{}, + createSubPathBeforeTest: false, + }, + { + base: `c:\tmp\a`, + pathname: `d:\tmp\b`, + expectError: true, + expectedExistingPath: "", + expectedToCreateDirs: []string{}, + createSubPathBeforeTest: false, + }, + { + base: testingVolumePath, + pathname: testingVolumePath, + expectError: false, + expectedExistingPath: testingVolumePath, + expectedToCreateDirs: []string{}, + createSubPathBeforeTest: false, + }, + { + base: testingVolumePath, + pathname: filepath.Join(testingVolumePath, `a\b`), + expectError: false, + expectedExistingPath: filepath.Join(testingVolumePath, `a\b`), + expectedToCreateDirs: []string{}, + createSubPathBeforeTest: true, + }, + { + base: testingVolumePath, + pathname: filepath.Join(testingVolumePath, `a\b\c\`), + expectError: false, + expectedExistingPath: filepath.Join(testingVolumePath, `a\b`), + expectedToCreateDirs: []string{`c`}, + createSubPathBeforeTest: false, + }, + { + base: testingVolumePath, + pathname: filepath.Join(testingVolumePath, `a\b\c\d`), + expectError: false, + expectedExistingPath: filepath.Join(testingVolumePath, `a\b`), + expectedToCreateDirs: []string{`c`, `d`}, + createSubPathBeforeTest: false, + }, + } + + for _, test := range tests { + if test.createSubPathBeforeTest { + os.MkdirAll(test.pathname, 0755) + } + + existingPath, toCreate, err := findExistingPrefix(test.base, test.pathname) + if test.expectError { + assert.NotNil(t, err, "Expect error during findExistingPrefix(%s, %s)", test.base, test.pathname) + continue + } + assert.Nil(t, err, "Expect no error during findExistingPrefix(%s, %s)", test.base, test.pathname) + + assert.Equal(t, test.expectedExistingPath, existingPath, "Expect result not equal with findExistingPrefix(%s, %s) return: %q, expected: %q", + test.base, test.pathname, existingPath, test.expectedExistingPath) + + assert.Equal(t, test.expectedToCreateDirs, toCreate, "Expect result not equal with findExistingPrefix(%s, %s) return: %q, expected: %q", + test.base, test.pathname, toCreate, test.expectedToCreateDirs) + + } + // remove dir will happen after closing all file handles + assert.Nil(t, os.RemoveAll(testingVolumePath), "Expect no error during remove dir %s", testingVolumePath) +} + +func TestPathWithinBase(t *testing.T) { + tests := []struct { + fullPath string + basePath string + expectedResult bool + }{ + { + fullPath: `c:\tmp\a\b\c`, + basePath: `c:\tmp`, + expectedResult: true, + }, + { + fullPath: `c:\tmp1`, + basePath: `c:\tmp2`, + expectedResult: false, + }, + { + fullPath: `c:\tmp`, + basePath: `c:\tmp`, + expectedResult: true, + }, + { + fullPath: `c:\tmp`, + basePath: `c:\tmp\a\b\c`, + expectedResult: false, + }, + } + + for _, test := range tests { + result := pathWithinBase(test.fullPath, test.basePath) + assert.Equal(t, result, test.expectedResult, "Expect result not equal with pathWithinBase(%s, %s) return: %q, expected: %q", + test.fullPath, test.basePath, result, test.expectedResult) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go index a6c7869b0d..b695c3fd26 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount.go @@ -22,9 +22,12 @@ import ( "fmt" "os" "path/filepath" + "regexp" + "strconv" "strings" "github.com/golang/glog" + utilio "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/util/nsenter" ) @@ -33,6 +36,13 @@ const ( hostProcMountsPath = "/rootfs/proc/1/mounts" // hostProcMountinfoPath is the default mount info path for rootfs hostProcMountinfoPath = "/rootfs/proc/1/mountinfo" + // hostProcSelfStatusPath is the default path to /proc/self/status on the host + hostProcSelfStatusPath = "/rootfs/proc/self/status" +) + +var ( + // pidRegExp matches "Pid: " in /proc/self/status + pidRegExp = regexp.MustCompile(`\nPid:\t([0-9]*)\n`) ) // Currently, all docker containers receive their own mount namespaces. @@ -270,3 +280,41 @@ func (mounter *NsenterMounter) ExistsPath(pathname string) bool { } return false } + +func (mounter *NsenterMounter) CleanSubPaths(podDir string, volumeName string) error { + return doCleanSubPaths(mounter, podDir, volumeName) +} + +// getPidOnHost returns kubelet's pid in the host pid namespace +func (mounter *NsenterMounter) getPidOnHost(procStatusPath string) (int, error) { + // Get the PID from /rootfs/proc/self/status + statusBytes, err := utilio.ConsistentRead(procStatusPath, maxListTries) + if err != nil { + return 0, fmt.Errorf("error reading %s: %s", procStatusPath, err) + } + matches := pidRegExp.FindSubmatch(statusBytes) + if len(matches) < 2 { + return 0, fmt.Errorf("cannot parse %s: no Pid:", procStatusPath) + } + return strconv.Atoi(string(matches[1])) +} + +func (mounter *NsenterMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + hostPid, err := mounter.getPidOnHost(hostProcSelfStatusPath) + if err != nil { + return "", nil, err + } + glog.V(4).Infof("Kubelet's PID on the host is %d", hostPid) + + // Bind-mount the subpath to avoid using symlinks in subpaths. + newHostPath, err = doBindSubPath(mounter, subPath, hostPid) + + // There is no action when the container starts. Bind-mount will be cleaned + // when container stops by CleanSubPaths. + cleanupAction = nil + return newHostPath, cleanupAction, err +} + +func (mounter *NsenterMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return doSafeMakeDir(pathname, base, perm) +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_test.go b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_test.go index 946c0feb2d..2aee4ad5f9 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_test.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_test.go @@ -18,7 +18,13 @@ limitations under the License. package mount -import "testing" +import ( + "io/ioutil" + "os" + "path" + "strconv" + "testing" +) func TestParseFindMnt(t *testing.T) { tests := []struct { @@ -65,3 +71,121 @@ func TestParseFindMnt(t *testing.T) { } } } + +func TestGetPidOnHost(t *testing.T) { + tempDir, err := ioutil.TempDir("", "get_pid_on_host_tests") + if err != nil { + t.Fatalf(err.Error()) + } + defer os.RemoveAll(tempDir) + + tests := []struct { + name string + procFile string + expectedPid int + expectError bool + }{ + { + name: "valid status file", + procFile: `Name: cat +Umask: 0002 +State: R (running) +Tgid: 15041 +Ngid: 0 +Pid: 15041 +PPid: 22699 +TracerPid: 0 +Uid: 1000 1000 1000 1000 +Gid: 1000 1000 1000 1000 +FDSize: 256 +Groups: 10 135 156 157 158 973 984 1000 1001 +NStgid: 15041 +NSpid: 15041 +NSpgid: 15041 +NSsid: 22699 +VmPeak: 115016 kB +VmSize: 115016 kB +VmLck: 0 kB +VmPin: 0 kB +VmHWM: 816 kB +VmRSS: 816 kB +RssAnon: 64 kB +RssFile: 752 kB +RssShmem: 0 kB +VmData: 312 kB +VmStk: 136 kB +VmExe: 32 kB +VmLib: 2060 kB +VmPTE: 44 kB +VmPMD: 12 kB +VmSwap: 0 kB +HugetlbPages: 0 kB +Threads: 1 +SigQ: 2/60752 +SigPnd: 0000000000000000 +ShdPnd: 0000000000000000 +SigBlk: 0000000000000000 +SigIgn: 0000000000000000 +SigCgt: 0000000000000000 +CapInh: 0000000000000000 +CapPrm: 0000000000000000 +CapEff: 0000000000000000 +CapBnd: 0000003fffffffff +CapAmb: 0000000000000000 +NoNewPrivs: 0 +Seccomp: 0 +Cpus_allowed: ff +Cpus_allowed_list: 0-7 +Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 +Mems_allowed_list: 0 +voluntary_ctxt_switches: 0 +nonvoluntary_ctxt_switches: 0 +`, + expectedPid: 15041, + }, + { + name: "no Pid:", + procFile: `Name: cat +Umask: 0002 +State: R (running) +Tgid: 15041 +Ngid: 0 +PPid: 22699 +`, + expectedPid: 0, + expectError: true, + }, + { + name: "invalid Pid:", + procFile: `Name: cat +Umask: 0002 +State: R (running) +Tgid: 15041 +Ngid: 0 +Pid: invalid +PPid: 22699 +`, + expectedPid: 0, + expectError: true, + }, + } + + for i, test := range tests { + filename := path.Join(tempDir, strconv.Itoa(i)) + err := ioutil.WriteFile(filename, []byte(test.procFile), 0666) + if err != nil { + t.Fatalf(err.Error()) + } + mounter := NsenterMounter{} + pid, err := mounter.getPidOnHost(filename) + if err != nil && !test.expectError { + t.Errorf("Test %q: unexpected error: %s", test.name, err) + } + if err == nil && test.expectError { + t.Errorf("Test %q: expected error, got none", test.name) + } + if pid != test.expectedPid { + t.Errorf("Test %q: expected pid %d, got %d", test.name, test.expectedPid, pid) + } + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go index f4eb692f95..4b29f0ba42 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/util/mount/nsenter_mount_unsupported.go @@ -20,6 +20,7 @@ package mount import ( "errors" + "os" ) type NsenterMounter struct{} @@ -85,3 +86,15 @@ func (*NsenterMounter) MakeFile(pathname string) error { func (*NsenterMounter) ExistsPath(pathname string) bool { return true } + +func (*NsenterMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error { + return nil +} + +func (*NsenterMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error) { + return subPath.Path, nil, nil +} + +func (*NsenterMounter) CleanSubPaths(podDir string, volumeName string) error { + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/removeall/removeall_test.go b/vendor/k8s.io/kubernetes/pkg/util/removeall/removeall_test.go index 22bdd092ed..99eaf7c46e 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/removeall/removeall_test.go +++ b/vendor/k8s.io/kubernetes/pkg/util/removeall/removeall_test.go @@ -79,6 +79,18 @@ func (mounter *fakeMounter) ExistsPath(pathname string) bool { return true } +func (mounter *fakeMounter) PrepareSafeSubpath(subPath mount.Subpath) (newHostPath string, cleanupAction func(), err error) { + return "", nil, nil +} + +func (mounter *fakeMounter) CleanSubPaths(_, _ string) error { + return nil +} + +func (mounter *fakeMounter) SafeMakeDir(_, _ string, _ os.FileMode) error { + return nil +} + func (mounter *fakeMounter) IsLikelyNotMountPoint(file string) (bool, error) { name := path.Base(file) if strings.HasPrefix(name, "mount") { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_common.go b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_common.go index eda0159073..02de0e1c1e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_common.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_dd/azure_common.go @@ -35,9 +35,10 @@ import ( ) const ( - defaultFSType = "ext4" - defaultStorageAccountType = storage.StandardLRS - defaultAzureDiskKind = v1.AzureSharedBlobDisk + defaultFSType = "ext4" + defaultStorageAccountType = storage.StandardLRS + defaultAzureDiskKind = v1.AzureSharedBlobDisk + defaultAzureDataDiskCachingMode = v1.AzureDataDiskCachingNone ) type dataDisk struct { @@ -141,7 +142,7 @@ func normalizeStorageAccountType(storageAccountType string) (storage.SkuName, er func normalizeCachingMode(cachingMode v1.AzureDataDiskCachingMode) (v1.AzureDataDiskCachingMode, error) { if cachingMode == "" { - return v1.AzureDataDiskCachingReadWrite, nil + return defaultAzureDataDiskCachingMode, nil } if !supportedCachingModes.Has(string(cachingMode)) { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go b/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go index 882f496d12..dbbdda0b5c 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/azure_file/azure_provision.go @@ -38,9 +38,9 @@ var _ volume.ProvisionableVolumePlugin = &azureFilePlugin{} // azure cloud provider should implement it type azureCloudProvider interface { // create a file share - CreateFileShare(name, storageAccount, storageType, location string, requestGB int) (string, string, error) + CreateFileShare(shareName, accountName, accountType, location string, requestGiB int) (string, string, error) // delete a file share - DeleteFileShare(accountName, key, name string) error + DeleteFileShare(accountName, accountKey, shareName string) error } type azureFileDeleter struct { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/configmap/configmap.go b/vendor/k8s.io/kubernetes/pkg/volume/configmap/configmap.go index 94b83b7ed7..b798d1c735 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/configmap/configmap.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/configmap/configmap.go @@ -194,6 +194,9 @@ func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } + if err := volumeutil.MakeNestedMountpoints(b.volName, dir, b.pod); err != nil { + return err + } optional := b.source.Optional != nil && *b.source.Optional configMap, err := b.getConfigMap(b.pod.Namespace, b.source.Name) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go b/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go index 0b920b0505..77263d52a1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go @@ -183,6 +183,9 @@ func (b *downwardAPIVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { glog.Errorf("Unable to setup downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) return err } + if err := volumeutil.MakeNestedMountpoints(b.volName, dir, *b.pod); err != nil { + return err + } data, err := CollectData(b.source.Items, b.pod, b.plugin.host, b.source.DefaultMode) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go index 664d0e6b9f..b5220ca47e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path_test.go @@ -376,6 +376,18 @@ func (fftc *fakeFileTypeChecker) GetFileType(_ string) (utilmount.FileType, erro return utilmount.FileType(fftc.desiredType), nil } +func (fftc *fakeFileTypeChecker) PrepareSafeSubpath(subPath utilmount.Subpath) (newHostPath string, cleanupAction func(), err error) { + return "", nil, nil +} + +func (fftc *fakeFileTypeChecker) CleanSubPaths(_, _ string) error { + return nil +} + +func (fftc *fakeFileTypeChecker) SafeMakeDir(_, _ string, _ os.FileMode) error { + return nil +} + func setUp() error { err := os.MkdirAll("/tmp/ExistingFolder", os.FileMode(0755)) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go index 60677df2c9..fbf4b88378 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/portworx/portworx_util.go @@ -30,12 +30,13 @@ import ( ) const ( - osdMgmtPort = "9001" - osdDriverVersion = "v1" - pxdDriverName = "pxd" - pvcClaimLabel = "pvc" - pxServiceName = "portworx-service" - pxDriverName = "pxd-sched" + osdMgmtPort = "9001" + osdDriverVersion = "v1" + pxdDriverName = "pxd" + pvcClaimLabel = "pvc" + pvcNamespaceLabel = "namespace" + pxServiceName = "portworx-service" + pxDriverName = "pxd-sched" ) type PortworxVolumeUtil struct { @@ -80,9 +81,20 @@ func (util *PortworxVolumeUtil) CreateVolume(p *portworxVolumeProvisioner) (stri // Add claim Name as a part of Portworx Volume Labels locator.VolumeLabels[pvcClaimLabel] = p.options.PVC.Name + locator.VolumeLabels[pvcNamespaceLabel] = p.options.PVC.Namespace + + for k, v := range p.options.PVC.Annotations { + if _, present := spec.VolumeLabels[k]; present { + glog.Warningf("not saving annotation: %s=%s in spec labels due to an existing key", k, v) + continue + } + spec.VolumeLabels[k] = v + } + volumeID, err := driver.Create(locator, source, spec) if err != nil { glog.Errorf("Error creating Portworx Volume : %v", err) + return "", 0, nil, err } glog.Infof("Successfully created Portworx volume for PVC: %v", p.options.PVC.Name) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/projected/projected.go b/vendor/k8s.io/kubernetes/pkg/volume/projected/projected.go index 70af142ccb..e75f10af5f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/projected/projected.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/projected/projected.go @@ -191,6 +191,9 @@ func (s *projectedVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } + if err := volumeutil.MakeNestedMountpoints(s.volName, dir, *s.pod); err != nil { + return err + } data, err := s.collectData() if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go b/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go index 67f4556e3f..dbfdfb48ab 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go @@ -193,6 +193,9 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { if err := wrapped.SetUpAt(dir, fsGroup); err != nil { return err } + if err := volumeutil.MakeNestedMountpoints(b.volName, dir, b.pod); err != nil { + return err + } optional := b.source.Optional != nil && *b.source.Optional secret, err := b.getSecret(b.pod.Namespace, b.source.SecretName) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/BUILD b/vendor/k8s.io/kubernetes/pkg/volume/util/BUILD index 48a0b0ee6b..d1cc9cc65a 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/BUILD +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/BUILD @@ -18,6 +18,7 @@ go_library( "fs_unsupported.go", "io_util.go", "metrics.go", + "nested_volumes.go", "util.go", "util_unsupported.go", ] + select({ @@ -63,6 +64,7 @@ go_test( name = "go_default_test", srcs = [ "finalizer_test.go", + "nested_volumes_test.go", "util_test.go", ] + select({ "@io_bazel_rules_go//go/platform:linux_amd64": [ @@ -79,6 +81,7 @@ go_test( "//vendor/github.com/davecgh/go-spew/spew:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", ] + select({ "@io_bazel_rules_go//go/platform:linux_amd64": [ diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes.go b/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes.go new file mode 100644 index 0000000000..02fca9d76e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes.go @@ -0,0 +1,99 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "fmt" + "k8s.io/api/core/v1" + "os" + "path" + "path/filepath" + "sort" + "strings" +) + +// getNestedMountpoints returns a list of mountpoint directories that should be created +// for the volume indicated by name. +// note: the returned list is relative to baseDir +func getNestedMountpoints(name, baseDir string, pod v1.Pod) ([]string, error) { + var retval []string + checkContainer := func(container *v1.Container) error { + var allMountPoints []string // all mount points in this container + var myMountPoints []string // mount points that match name + for _, vol := range container.VolumeMounts { + cleaned := filepath.Clean(vol.MountPath) + allMountPoints = append(allMountPoints, cleaned) + if vol.Name == name { + myMountPoints = append(myMountPoints, cleaned) + } + } + sort.Strings(allMountPoints) + parentPrefix := ".." + string(os.PathSeparator) + // Examine each place where this volume is mounted + for _, myMountPoint := range myMountPoints { + if strings.HasPrefix(myMountPoint, parentPrefix) { + // Don't let a container trick us into creating directories outside of its rootfs + return fmt.Errorf("Invalid container mount point %v", myMountPoint) + } + myMPSlash := myMountPoint + string(os.PathSeparator) + // The previously found nested mountpoint (or "" if none found yet) + prevNestedMP := "" + // examine each mount point to see if it's nested beneath this volume + // (but skip any that are double-nested beneath this volume) + // For example, if this volume is mounted as /dir and other volumes are mounted + // as /dir/nested and /dir/nested/other, only create /dir/nested. + for _, mp := range allMountPoints { + if !strings.HasPrefix(mp, myMPSlash) { + continue // skip -- not nested beneath myMountPoint + } + if prevNestedMP != "" && strings.HasPrefix(mp, prevNestedMP) { + continue // skip -- double nested beneath myMountPoint + } + // since this mount point is nested, remember it so that we can check that following ones aren't nested beneath this one + prevNestedMP = mp + string(os.PathSeparator) + retval = append(retval, mp[len(myMPSlash):]) + } + } + return nil + } + for _, container := range pod.Spec.InitContainers { + if err := checkContainer(&container); err != nil { + return nil, err + } + } + for _, container := range pod.Spec.Containers { + if err := checkContainer(&container); err != nil { + return nil, err + } + } + return retval, nil +} + +// MakeNestedMountpoints creates mount points in baseDir for volumes mounted beneath name +func MakeNestedMountpoints(name, baseDir string, pod v1.Pod) error { + dirs, err := getNestedMountpoints(name, baseDir, pod) + if err != nil { + return err + } + for _, dir := range dirs { + err := os.MkdirAll(path.Join(baseDir, dir), 0755) + if err != nil { + return fmt.Errorf("Unable to create nested volume mountpoints: %v", err) + } + } + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes_test.go b/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes_test.go new file mode 100644 index 0000000000..936c09cdae --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/nested_volumes_test.go @@ -0,0 +1,233 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "io/ioutil" + "os" + "path" + "testing" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" +) + +type testCases struct { + name string + err bool + expected sets.String + volname string + pod v1.Pod +} + +func TestGetNestedMountpoints(t *testing.T) { + var ( + testNamespace = "test_namespace" + testPodUID = types.UID("test_pod_uid") + ) + + tc := []testCases{ + { + name: "Simple Pod", + err: false, + expected: sets.NewString(), + volname: "vol1", + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/dir", Name: "vol1"}, + }, + }, + }, + }, + }, + }, + { + name: "Simple Nested Pod", + err: false, + expected: sets.NewString("nested"), + volname: "vol1", + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/dir", Name: "vol1"}, + {MountPath: "/dir/nested", Name: "vol2"}, + }, + }, + }, + }, + }, + }, + { + name: "Unsorted Nested Pod", + err: false, + expected: sets.NewString("nested", "nested2"), + volname: "vol1", + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/dir/nested/double", Name: "vol3"}, + {MountPath: "/ignore", Name: "vol4"}, + {MountPath: "/dir/nested", Name: "vol2"}, + {MountPath: "/ignore2", Name: "vol5"}, + {MountPath: "/dir", Name: "vol1"}, + {MountPath: "/dir/nested2", Name: "vol3"}, + }, + }, + }, + }, + }, + }, + { + name: "Multiple vol1 mounts Pod", + err: false, + expected: sets.NewString("nested", "nested2"), + volname: "vol1", + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/dir", Name: "vol1"}, + {MountPath: "/dir/nested", Name: "vol2"}, + {MountPath: "/ignore", Name: "vol4"}, + {MountPath: "/other", Name: "vol1"}, + {MountPath: "/other/nested2", Name: "vol3"}, + }, + }, + }, + }, + }, + }, + { + name: "Big Pod", + err: false, + volname: "vol1", + expected: sets.NewString("sub1/sub2/sub3", "sub1/sub2/sub4", "sub1/sub2/sub6", "sub"), + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/mnt", Name: "vol1"}, + {MountPath: "/ignore", Name: "vol2"}, + {MountPath: "/mnt/sub1/sub2/sub3", Name: "vol3"}, + {MountPath: "/mnt/sub1/sub2/sub4", Name: "vol4"}, + {MountPath: "/mnt/sub1/sub2/sub4/skip", Name: "vol5"}, + {MountPath: "/mnt/sub1/sub2/sub4/skip2", Name: "vol5a"}, + {MountPath: "/mnt/sub1/sub2/sub6", Name: "vol6"}, + {MountPath: "/mnt7", Name: "vol7"}, + }, + }, + }, + InitContainers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "/mnt/dir", Name: "vol1"}, + {MountPath: "/mnt/dir_ignore", Name: "vol8"}, + {MountPath: "/ignore", Name: "vol9"}, + {MountPath: "/mnt/dir/sub", Name: "vol11"}, + }, + }, + }, + }, + }, + }, + { + name: "Naughty Pod", + err: true, + expected: nil, + volname: "vol1", + pod: v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + UID: testPodUID, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + VolumeMounts: []v1.VolumeMount{ + {MountPath: "foo/../../dir", Name: "vol1"}, + {MountPath: "foo/../../dir/skip", Name: "vol10"}, + }, + }, + }, + }, + }, + }, + } + for _, test := range tc { + dir, err := ioutil.TempDir("", "TestMakeNestedMountpoints.") + if err != nil { + t.Errorf("Unexpected error trying to create temp directory: %v", err) + return + } + defer os.RemoveAll(dir) + + rootdir := path.Join(dir, "vol") + err = os.Mkdir(rootdir, 0755) + if err != nil { + t.Errorf("Unexpected error trying to create temp root directory: %v", err) + return + } + + dirs, err := getNestedMountpoints(test.volname, rootdir, test.pod) + if test.err { + if err == nil { + t.Errorf("%v: expected error, got nil", test.name) + } + continue + } else { + if err != nil { + t.Errorf("%v: expected no error, got %v", test.name, err) + continue + } + } + actual := sets.NewString(dirs...) + if !test.expected.Equal(actual) { + t.Errorf("%v: unexpected nested directories created:\nexpected: %v\n got: %v", test.name, test.expected, actual) + } + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor.go b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor.go index 543067be6b..e9147012f0 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor.go @@ -100,7 +100,7 @@ type OperationExecutor interface { // UnmountVolume unmounts the volume from the pod specified in // volumeToUnmount and updates the actual state of the world to reflect that. - UnmountVolume(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) error + UnmountVolume(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) error // UnmountDevice unmounts the volumes global mount path from the device (for // attachable volumes only, freeing it for detach. It then updates the @@ -722,10 +722,11 @@ func (oe *operationExecutor) MountVolume( func (oe *operationExecutor) UnmountVolume( volumeToUnmount MountedVolume, - actualStateOfWorld ActualStateOfWorldMounterUpdater) error { + actualStateOfWorld ActualStateOfWorldMounterUpdater, + podsDir string) error { unmountFunc, plugin, err := - oe.operationGenerator.GenerateUnmountVolumeFunc(volumeToUnmount, actualStateOfWorld) + oe.operationGenerator.GenerateUnmountVolumeFunc(volumeToUnmount, actualStateOfWorld, podsDir) if err != nil { return err } @@ -847,7 +848,7 @@ type VolumeStateHandler interface { // Volume is attached, mount/map it MountVolumeHandler(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorld ActualStateOfWorldMounterUpdater, isRemount bool, remountingLogStr string) error // Volume is mounted/mapped, unmount/unmap it - UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) error + UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) error // Volume is not referenced from pod, unmount/unmap and detach it UnmountDeviceHandler(attachedVolume AttachedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, mounter mount.Interface) error // Reconstruct volume from mount path @@ -913,11 +914,12 @@ func (f FilesystemVolumeHandler) MountVolumeHandler(waitForAttachTimeout time.Du // UnmountVolumeHandler unmount a volume if a volume is mounted // This method is handler for filesystem volume -func (f FilesystemVolumeHandler) UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) error { +func (f FilesystemVolumeHandler) UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) error { glog.V(12).Infof(mountedVolume.GenerateMsgDetailed("Starting operationExecutor.UnmountVolume", "")) err := f.oe.UnmountVolume( mountedVolume, - actualStateOfWorld) + actualStateOfWorld, + podsDir) return err } @@ -976,7 +978,7 @@ func (b BlockVolumeHandler) MountVolumeHandler(waitForAttachTimeout time.Duratio // UnmountVolumeHandler unmap a volume if a volume is mapped // This method is handler for block volume -func (b BlockVolumeHandler) UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) error { +func (b BlockVolumeHandler) UnmountVolumeHandler(mountedVolume MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) error { glog.V(12).Infof(mountedVolume.GenerateMsgDetailed("Starting operationExecutor.UnmapVolume", "")) err := b.oe.UnmapVolume( mountedVolume, diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor_test.go b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor_test.go index 4e06b39616..c87bc6788c 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor_test.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_executor_test.go @@ -124,7 +124,7 @@ func TestOperationExecutor_UnmountVolume_ConcurrentUnmountForAllPlugins(t *testi PodUID: pod.UID, } } - oe.UnmountVolume(volumesToUnmount[i], nil /* actualStateOfWorldMounterUpdater */) + oe.UnmountVolume(volumesToUnmount[i], nil /* actualStateOfWorldMounterUpdater */, "" /*podsDir*/) } // Assert @@ -356,7 +356,7 @@ func (fopg *fakeOperationGenerator) GenerateMountVolumeFunc(waitForAttachTimeout return nil }, "", nil } -func (fopg *fakeOperationGenerator) GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) (func() error, string, error) { +func (fopg *fakeOperationGenerator) GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (func() error, string, error) { return func() error { startOperationAndBlock(fopg.ch, fopg.quit) return nil diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go index 2ff4b668f0..43cce820be 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/operationexecutor/operation_generator.go @@ -19,6 +19,7 @@ package operationexecutor import ( "encoding/json" "fmt" + "path" "strings" "time" @@ -86,7 +87,7 @@ type OperationGenerator interface { GenerateMountVolumeFunc(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorldMounterUpdater ActualStateOfWorldMounterUpdater, isRemount bool) (func() error, string, error) // Generates the UnmountVolume function needed to perform the unmount of a volume plugin - GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater) (func() error, string, error) + GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (func() error, string, error) // Generates the AttachVolume function needed to perform attach of a volume plugin GenerateAttachVolumeFunc(volumeToAttach VolumeToAttach, actualStateOfWorld ActualStateOfWorldAttacherUpdater) (func() error, string, error) @@ -608,7 +609,8 @@ func (og *operationGenerator) resizeFileSystem(volumeToMount VolumeToMount, devi func (og *operationGenerator) GenerateUnmountVolumeFunc( volumeToUnmount MountedVolume, - actualStateOfWorld ActualStateOfWorldMounterUpdater) (func() error, string, error) { + actualStateOfWorld ActualStateOfWorldMounterUpdater, + podsDir string) (func() error, string, error) { // Get mountable plugin volumePlugin, err := og.volumePluginMgr.FindPluginByName(volumeToUnmount.PluginName) @@ -623,6 +625,14 @@ func (og *operationGenerator) GenerateUnmountVolumeFunc( } return func() error { + mounter := og.volumePluginMgr.Host.GetMounter(volumeToUnmount.PluginName) + + // Remove all bind-mounts for subPaths + podDir := path.Join(podsDir, string(volumeToUnmount.PodUID)) + if err := mounter.CleanSubPaths(podDir, volumeToUnmount.OuterVolumeSpecName); err != nil { + return volumeToUnmount.GenerateErrorDetailed("error cleaning subPath mounts", err) + } + // Execute unmount unmountErr := volumeUnmounter.TearDown() if unmountErr != nil { diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue.go index 78bdf09901..de7c698813 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue.go @@ -51,7 +51,7 @@ type SchedulingQueue interface { AddIfNotPresent(pod *v1.Pod) error AddUnschedulableIfNotPresent(pod *v1.Pod) error Pop() (*v1.Pod, error) - Update(pod *v1.Pod) error + Update(oldPod, newPod *v1.Pod) error Delete(pod *v1.Pod) error MoveAllToActiveQueue() AssignedPodAdded(pod *v1.Pod) @@ -90,8 +90,9 @@ func (f *FIFO) AddUnschedulableIfNotPresent(pod *v1.Pod) error { return f.FIFO.AddIfNotPresent(pod) } -func (f *FIFO) Update(pod *v1.Pod) error { - return f.FIFO.Update(pod) +// Update updates a pod in the FIFO. +func (f *FIFO) Update(oldPod, newPod *v1.Pod) error { + return f.FIFO.Update(newPod) } func (f *FIFO) Delete(pod *v1.Pod) error { @@ -130,6 +131,15 @@ func NewFIFO() *FIFO { return &FIFO{FIFO: cache.NewFIFO(cache.MetaNamespaceKeyFunc)} } +// NominatedNodeName returns nominated node name of a Pod. +func NominatedNodeName(pod *v1.Pod) string { + nominatedNodeName, ok := pod.Annotations[NominatedNodeAnnotationKey] + if !ok { + return "" + } + return nominatedNodeName +} + // UnschedulablePods is an interface for a queue that is used to keep unschedulable // pods. These pods are not actively reevaluated for scheduling. They are moved // to the active scheduling queue on certain events, such as termination of a pod @@ -138,7 +148,6 @@ type UnschedulablePods interface { Add(pod *v1.Pod) Delete(pod *v1.Pod) Update(pod *v1.Pod) - GetPodsWaitingForNode(nodeName string) []*v1.Pod Get(pod *v1.Pod) *v1.Pod Clear() } @@ -160,6 +169,10 @@ type PriorityQueue struct { activeQ *Heap // unschedulableQ holds pods that have been tried and determined unschedulable. unschedulableQ *UnschedulablePodsMap + // nominatedPods is a map keyed by a node name and the value is a list of + // pods which are nominated to run on the node. These are pods which can be in + // the activeQ or unschedulableQ. + nominatedPods map[string][]*v1.Pod // receivedMoveRequest is set to true whenever we receive a request to move a // pod from the unschedulableQ to the activeQ, and is set to false, when we pop // a pod from the activeQ. It indicates if we received a move request when a @@ -175,11 +188,51 @@ func NewPriorityQueue() *PriorityQueue { pq := &PriorityQueue{ activeQ: newHeap(cache.MetaNamespaceKeyFunc, util.HigherPriorityPod), unschedulableQ: newUnschedulablePodsMap(), + nominatedPods: map[string][]*v1.Pod{}, } pq.cond.L = &pq.lock return pq } +// addNominatedPodIfNeeded adds a pod to nominatedPods if it has a NominatedNodeName and it does not +// already exist in the map. Adding an existing pod is not going to update the pod. +func (p *PriorityQueue) addNominatedPodIfNeeded(pod *v1.Pod) { + nnn := NominatedNodeName(pod) + if len(nnn) > 0 { + for _, np := range p.nominatedPods[nnn] { + if np.UID == pod.UID { + glog.Errorf("Pod %v/%v already exists in the nominated map!", pod.Namespace, pod.Name) + return + } + } + p.nominatedPods[nnn] = append(p.nominatedPods[nnn], pod) + } +} + +// deleteNominatedPodIfExists deletes a pod from the nominatedPods. +func (p *PriorityQueue) deleteNominatedPodIfExists(pod *v1.Pod) { + nnn := NominatedNodeName(pod) + if len(nnn) > 0 { + for i, np := range p.nominatedPods[nnn] { + if np.UID == pod.UID { + p.nominatedPods[nnn] = append(p.nominatedPods[nnn][:i], p.nominatedPods[nnn][i+1:]...) + if len(p.nominatedPods[nnn]) == 0 { + delete(p.nominatedPods, nnn) + } + break + } + } + } +} + +// updateNominatedPod updates a pod in the nominatedPods. +func (p *PriorityQueue) updateNominatedPod(oldPod, newPod *v1.Pod) { + // Even if the nominated node name of the Pod is not changed, we must delete and add it again + // to ensure that its pointer is updated. + p.deleteNominatedPodIfExists(oldPod) + p.addNominatedPodIfNeeded(newPod) +} + // Add adds a pod to the active queue. It should be called only when a new pod // is added so there is no chance the pod is already in either queue. func (p *PriorityQueue) Add(pod *v1.Pod) error { @@ -191,8 +244,10 @@ func (p *PriorityQueue) Add(pod *v1.Pod) error { } else { if p.unschedulableQ.Get(pod) != nil { glog.Errorf("Error: pod %v is already in the unschedulable queue.", pod.Name) + p.deleteNominatedPodIfExists(pod) p.unschedulableQ.Delete(pod) } + p.addNominatedPodIfNeeded(pod) p.cond.Broadcast() } return err @@ -213,6 +268,7 @@ func (p *PriorityQueue) AddIfNotPresent(pod *v1.Pod) error { if err != nil { glog.Errorf("Error adding pod %v to the scheduling queue: %v", pod.Name, err) } else { + p.addNominatedPodIfNeeded(pod) p.cond.Broadcast() } return err @@ -237,10 +293,12 @@ func (p *PriorityQueue) AddUnschedulableIfNotPresent(pod *v1.Pod) error { } if !p.receivedMoveRequest && isPodUnschedulable(pod) { p.unschedulableQ.Add(pod) + p.addNominatedPodIfNeeded(pod) return nil } err := p.activeQ.Add(pod) if err == nil { + p.addNominatedPodIfNeeded(pod) p.cond.Broadcast() } return err @@ -259,8 +317,10 @@ func (p *PriorityQueue) Pop() (*v1.Pod, error) { if err != nil { return nil, err } + pod := obj.(*v1.Pod) + p.deleteNominatedPodIfExists(pod) p.receivedMoveRequest = false - return obj.(*v1.Pod), err + return pod, err } // isPodUpdated checks if the pod is updated in a way that it may have become @@ -279,31 +339,33 @@ func isPodUpdated(oldPod, newPod *v1.Pod) bool { // Update updates a pod in the active queue if present. Otherwise, it removes // the item from the unschedulable queue and adds the updated one to the active // queue. -func (p *PriorityQueue) Update(pod *v1.Pod) error { +func (p *PriorityQueue) Update(oldPod, newPod *v1.Pod) error { p.lock.Lock() defer p.lock.Unlock() // If the pod is already in the active queue, just update it there. - if _, exists, _ := p.activeQ.Get(pod); exists { - err := p.activeQ.Update(pod) + if _, exists, _ := p.activeQ.Get(newPod); exists { + p.updateNominatedPod(oldPod, newPod) + err := p.activeQ.Update(newPod) return err } // If the pod is in the unschedulable queue, updating it may make it schedulable. - if oldPod := p.unschedulableQ.Get(pod); oldPod != nil { - if isPodUpdated(oldPod, pod) { - p.unschedulableQ.Delete(oldPod) - err := p.activeQ.Add(pod) + if usPod := p.unschedulableQ.Get(newPod); usPod != nil { + p.updateNominatedPod(oldPod, newPod) + if isPodUpdated(oldPod, newPod) { + p.unschedulableQ.Delete(usPod) + err := p.activeQ.Add(newPod) if err == nil { p.cond.Broadcast() } return err - } else { - p.unschedulableQ.Update(pod) - return nil } + p.unschedulableQ.Update(newPod) + return nil } // If pod is not in any of the two queue, we put it in the active queue. - err := p.activeQ.Add(pod) + err := p.activeQ.Add(newPod) if err == nil { + p.addNominatedPodIfNeeded(newPod) p.cond.Broadcast() } return err @@ -314,6 +376,7 @@ func (p *PriorityQueue) Update(pod *v1.Pod) error { func (p *PriorityQueue) Delete(pod *v1.Pod) error { p.lock.Lock() defer p.lock.Unlock() + p.deleteNominatedPodIfExists(pod) if _, exists, _ := p.activeQ.Get(pod); exists { return p.activeQ.Delete(pod) } @@ -396,73 +459,34 @@ func (p *PriorityQueue) getUnschedulablePodsWithMatchingAffinityTerm(pod *v1.Pod func (p *PriorityQueue) WaitingPodsForNode(nodeName string) []*v1.Pod { p.lock.RLock() defer p.lock.RUnlock() - pods := p.unschedulableQ.GetPodsWaitingForNode(nodeName) - for _, obj := range p.activeQ.List() { - pod := obj.(*v1.Pod) - if pod.Annotations != nil { - if n, ok := pod.Annotations[NominatedNodeAnnotationKey]; ok && n == nodeName { - pods = append(pods, pod) - } - } + if list, ok := p.nominatedPods[nodeName]; ok { + return list } - return pods + return nil } // UnschedulablePodsMap holds pods that cannot be scheduled. This data structure // is used to implement unschedulableQ. type UnschedulablePodsMap struct { // pods is a map key by a pod's full-name and the value is a pointer to the pod. - pods map[string]*v1.Pod - // nominatedPods is a map keyed by a node name and the value is a list of - // pods' full-names which are nominated to run on the node. - nominatedPods map[string][]string - keyFunc func(*v1.Pod) string + pods map[string]*v1.Pod + keyFunc func(*v1.Pod) string } var _ = UnschedulablePods(&UnschedulablePodsMap{}) -func NominatedNodeName(pod *v1.Pod) string { - nominatedNodeName, ok := pod.Annotations[NominatedNodeAnnotationKey] - if !ok { - return "" - } - return nominatedNodeName -} - // Add adds a pod to the unschedulable pods. func (u *UnschedulablePodsMap) Add(pod *v1.Pod) { podKey := u.keyFunc(pod) if _, exists := u.pods[podKey]; !exists { u.pods[podKey] = pod - nominatedNodeName := NominatedNodeName(pod) - if len(nominatedNodeName) > 0 { - u.nominatedPods[nominatedNodeName] = append(u.nominatedPods[nominatedNodeName], podKey) - } - } -} - -func (u *UnschedulablePodsMap) deleteFromNominated(pod *v1.Pod) { - nominatedNodeName := NominatedNodeName(pod) - if len(nominatedNodeName) > 0 { - podKey := u.keyFunc(pod) - nps := u.nominatedPods[nominatedNodeName] - for i, np := range nps { - if np == podKey { - u.nominatedPods[nominatedNodeName] = append(nps[:i], nps[i+1:]...) - if len(u.nominatedPods[nominatedNodeName]) == 0 { - delete(u.nominatedPods, nominatedNodeName) - } - break - } - } } } // Delete deletes a pod from the unschedulable pods. func (u *UnschedulablePodsMap) Delete(pod *v1.Pod) { podKey := u.keyFunc(pod) - if p, exists := u.pods[podKey]; exists { - u.deleteFromNominated(p) + if _, exists := u.pods[podKey]; exists { delete(u.pods, podKey) } } @@ -470,20 +494,12 @@ func (u *UnschedulablePodsMap) Delete(pod *v1.Pod) { // Update updates a pod in the unschedulable pods. func (u *UnschedulablePodsMap) Update(pod *v1.Pod) { podKey := u.keyFunc(pod) - oldPod, exists := u.pods[podKey] + _, exists := u.pods[podKey] if !exists { u.Add(pod) return } u.pods[podKey] = pod - oldNominateNodeName := NominatedNodeName(oldPod) - nominatedNodeName := NominatedNodeName(pod) - if oldNominateNodeName != nominatedNodeName { - u.deleteFromNominated(oldPod) - if len(nominatedNodeName) > 0 { - u.nominatedPods[nominatedNodeName] = append(u.nominatedPods[nominatedNodeName], podKey) - } - } } // Get returns the pod if a pod with the same key as the key of the given "pod" @@ -496,28 +512,16 @@ func (u *UnschedulablePodsMap) Get(pod *v1.Pod) *v1.Pod { return nil } -// GetPodsWaitingForNode returns a list of unschedulable pods whose NominatedNodeNames -// are equal to the given nodeName. -func (u *UnschedulablePodsMap) GetPodsWaitingForNode(nodeName string) []*v1.Pod { - var pods []*v1.Pod - for _, key := range u.nominatedPods[nodeName] { - pods = append(pods, u.pods[key]) - } - return pods -} - // Clear removes all the entries from the unschedulable maps. func (u *UnschedulablePodsMap) Clear() { u.pods = make(map[string]*v1.Pod) - u.nominatedPods = make(map[string][]string) } // newUnschedulablePodsMap initializes a new object of UnschedulablePodsMap. func newUnschedulablePodsMap() *UnschedulablePodsMap { return &UnschedulablePodsMap{ - pods: make(map[string]*v1.Pod), - nominatedPods: make(map[string][]string), - keyFunc: util.GetPodFullName, + pods: make(map[string]*v1.Pod), + keyFunc: util.GetPodFullName, } } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue_test.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue_test.go index 343b7593bf..702081d97d 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue_test.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/core/scheduling_queue_test.go @@ -18,6 +18,7 @@ package core import ( "reflect" + "sync" "testing" "k8s.io/api/core/v1" @@ -26,19 +27,34 @@ import ( ) var mediumPriority = (lowPriority + highPriority) / 2 -var highPriorityPod, medPriorityPod, unschedulablePod = v1.Pod{ +var highPriorityPod, highPriNominatedPod, medPriorityPod, unschedulablePod = v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "hpp", Namespace: "ns1", + UID: "hppns1", }, Spec: v1.PodSpec{ Priority: &highPriority, }, }, + v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "hpp", + Namespace: "ns1", + UID: "hppns1", + Annotations: map[string]string{ + NominatedNodeAnnotationKey: "node1", + }, + }, + Spec: v1.PodSpec{ + Priority: &highPriority, + }, + }, v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "mpp", Namespace: "ns2", + UID: "mppns2", Annotations: map[string]string{ NominatedNodeAnnotationKey: "node1", "annot2": "val2", }, @@ -51,6 +67,7 @@ var highPriorityPod, medPriorityPod, unschedulablePod = v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "up", Namespace: "ns1", + UID: "upns1", Annotations: map[string]string{ NominatedNodeAnnotationKey: "node1", "annot2": "val2", }, @@ -74,6 +91,12 @@ func TestPriorityQueue_Add(t *testing.T) { q.Add(&medPriorityPod) q.Add(&unschedulablePod) q.Add(&highPriorityPod) + expectedNominatedPods := map[string][]*v1.Pod{ + "node1": {&medPriorityPod, &unschedulablePod}, + } + if !reflect.DeepEqual(q.nominatedPods, expectedNominatedPods) { + t.Errorf("Unexpected nominated map after adding pods. Expected: %v, got: %v", expectedNominatedPods, q.nominatedPods) + } if p, err := q.Pop(); err != nil || p != &highPriorityPod { t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPod.Name, p.Name) } @@ -83,59 +106,134 @@ func TestPriorityQueue_Add(t *testing.T) { if p, err := q.Pop(); err != nil || p != &unschedulablePod { t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePod.Name, p.Name) } + if len(q.nominatedPods) != 0 { + t.Errorf("Expected nomindatePods to be empty: %v", q.nominatedPods) + } +} + +func TestPriorityQueue_AddIfNotPresent(t *testing.T) { + q := NewPriorityQueue() + q.unschedulableQ.Add(&highPriNominatedPod) + q.AddIfNotPresent(&highPriNominatedPod) // Must not add anything. + q.AddIfNotPresent(&medPriorityPod) + q.AddIfNotPresent(&unschedulablePod) + expectedNominatedPods := map[string][]*v1.Pod{ + "node1": {&medPriorityPod, &unschedulablePod}, + } + if !reflect.DeepEqual(q.nominatedPods, expectedNominatedPods) { + t.Errorf("Unexpected nominated map after adding pods. Expected: %v, got: %v", expectedNominatedPods, q.nominatedPods) + } + if p, err := q.Pop(); err != nil || p != &medPriorityPod { + t.Errorf("Expected: %v after Pop, but got: %v", medPriorityPod.Name, p.Name) + } + if p, err := q.Pop(); err != nil || p != &unschedulablePod { + t.Errorf("Expected: %v after Pop, but got: %v", unschedulablePod.Name, p.Name) + } + if len(q.nominatedPods) != 0 { + t.Errorf("Expected nomindatePods to be empty: %v", q.nominatedPods) + } + if q.unschedulableQ.Get(&highPriNominatedPod) != &highPriNominatedPod { + t.Errorf("Pod %v was not found in the unschedulableQ.", highPriNominatedPod.Name) + } +} + +func TestPriorityQueue_AddUnschedulableIfNotPresent(t *testing.T) { + q := NewPriorityQueue() + q.Add(&highPriNominatedPod) + q.AddUnschedulableIfNotPresent(&highPriNominatedPod) // Must not add anything. + q.AddUnschedulableIfNotPresent(&medPriorityPod) // This should go to activeQ. + q.AddUnschedulableIfNotPresent(&unschedulablePod) + expectedNominatedPods := map[string][]*v1.Pod{ + "node1": {&highPriNominatedPod, &medPriorityPod, &unschedulablePod}, + } + if !reflect.DeepEqual(q.nominatedPods, expectedNominatedPods) { + t.Errorf("Unexpected nominated map after adding pods. Expected: %v, got: %v", expectedNominatedPods, q.nominatedPods) + } + if p, err := q.Pop(); err != nil || p != &highPriNominatedPod { + t.Errorf("Expected: %v after Pop, but got: %v", highPriNominatedPod.Name, p.Name) + } + if p, err := q.Pop(); err != nil || p != &medPriorityPod { + t.Errorf("Expected: %v after Pop, but got: %v", medPriorityPod.Name, p.Name) + } + if len(q.nominatedPods) != 1 { + t.Errorf("Expected nomindatePods to have one element: %v", q.nominatedPods) + } + if q.unschedulableQ.Get(&unschedulablePod) != &unschedulablePod { + t.Errorf("Pod %v was not found in the unschedulableQ.", unschedulablePod.Name) + } } func TestPriorityQueue_Pop(t *testing.T) { q := NewPriorityQueue() + wg := sync.WaitGroup{} + wg.Add(1) go func() { - if p, err := q.Pop(); err != nil || p != &highPriorityPod { - t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPod.Name, p.Name) + defer wg.Done() + if p, err := q.Pop(); err != nil || p != &medPriorityPod { + t.Errorf("Expected: %v after Pop, but got: %v", medPriorityPod.Name, p.Name) + } + if len(q.nominatedPods) != 0 { + t.Errorf("Expected nomindatePods to be empty: %v", q.nominatedPods) } }() - q.Add(&highPriorityPod) + q.Add(&medPriorityPod) + wg.Wait() } func TestPriorityQueue_Update(t *testing.T) { q := NewPriorityQueue() - q.Update(&highPriorityPod) + q.Update(nil, &highPriorityPod) if _, exists, _ := q.activeQ.Get(&highPriorityPod); !exists { t.Errorf("Expected %v to be added to activeQ.", highPriorityPod.Name) } - q.Update(&highPriorityPod) + if len(q.nominatedPods) != 0 { + t.Errorf("Expected nomindatePods to be empty: %v", q.nominatedPods) + } + // Update highPriorityPod and add a nominatedNodeName to it. + q.Update(&highPriorityPod, &highPriNominatedPod) if q.activeQ.data.Len() != 1 { t.Error("Expected only one item in activeQ.") } + if len(q.nominatedPods) != 1 { + t.Errorf("Expected one item in nomindatePods map: %v", q.nominatedPods) + } // Updating an unschedulable pod which is not in any of the two queues, should // add the pod to activeQ. - q.Update(&unschedulablePod) + q.Update(&unschedulablePod, &unschedulablePod) if _, exists, _ := q.activeQ.Get(&unschedulablePod); !exists { t.Errorf("Expected %v to be added to activeQ.", unschedulablePod.Name) } - // Updating a pod that is already in unschedulableQ, should move the pod to - // activeQ. - q.Update(&unschedulablePod) + // Updating a pod that is already in activeQ, should not change it. + q.Update(&unschedulablePod, &unschedulablePod) if len(q.unschedulableQ.pods) != 0 { t.Error("Expected unschedulableQ to be empty.") } if _, exists, _ := q.activeQ.Get(&unschedulablePod); !exists { t.Errorf("Expected: %v to be added to activeQ.", unschedulablePod.Name) } - if p, err := q.Pop(); err != nil || p != &highPriorityPod { + if p, err := q.Pop(); err != nil || p != &highPriNominatedPod { t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPod.Name, p.Name) } } func TestPriorityQueue_Delete(t *testing.T) { q := NewPriorityQueue() - q.Update(&highPriorityPod) + q.Update(&highPriorityPod, &highPriNominatedPod) q.Add(&unschedulablePod) - q.Delete(&highPriorityPod) + q.Delete(&highPriNominatedPod) if _, exists, _ := q.activeQ.Get(&unschedulablePod); !exists { t.Errorf("Expected %v to be in activeQ.", unschedulablePod.Name) } - if _, exists, _ := q.activeQ.Get(&highPriorityPod); exists { + if _, exists, _ := q.activeQ.Get(&highPriNominatedPod); exists { t.Errorf("Didn't expect %v to be in activeQ.", highPriorityPod.Name) } + if len(q.nominatedPods) != 1 { + t.Errorf("Expected nomindatePods to have only 'unschedulablePod': %v", q.nominatedPods) + } + q.Delete(&unschedulablePod) + if len(q.nominatedPods) != 0 { + t.Errorf("Expected nomindatePods to be empty: %v", q.nominatedPods) + } } func TestPriorityQueue_MoveAllToActiveQueue(t *testing.T) { @@ -205,6 +303,23 @@ func TestPriorityQueue_AssignedPodAdded(t *testing.T) { } } +func TestPriorityQueue_WaitingPodsForNode(t *testing.T) { + q := NewPriorityQueue() + q.Add(&medPriorityPod) + q.Add(&unschedulablePod) + q.Add(&highPriorityPod) + if p, err := q.Pop(); err != nil || p != &highPriorityPod { + t.Errorf("Expected: %v after Pop, but got: %v", highPriorityPod.Name, p.Name) + } + expectedList := []*v1.Pod{&medPriorityPod, &unschedulablePod} + if !reflect.DeepEqual(expectedList, q.WaitingPodsForNode("node1")) { + t.Error("Unexpected list of nominated Pods for node.") + } + if q.WaitingPodsForNode("node2") != nil { + t.Error("Expected list of nominated Pods for node2 to be empty.") + } +} + func TestUnschedulablePodsMap(t *testing.T) { var pods = []*v1.Pod{ { @@ -246,22 +361,16 @@ func TestUnschedulablePodsMap(t *testing.T) { } var updatedPods = make([]*v1.Pod, len(pods)) updatedPods[0] = pods[0].DeepCopy() - updatedPods[0].Annotations[NominatedNodeAnnotationKey] = "node3" updatedPods[1] = pods[1].DeepCopy() - updatedPods[1].Annotations[NominatedNodeAnnotationKey] = "node3" updatedPods[3] = pods[3].DeepCopy() - delete(updatedPods[3].Annotations, NominatedNodeAnnotationKey) tests := []struct { - podsToAdd []*v1.Pod - expectedMapAfterAdd map[string]*v1.Pod - expectedNominatedAfterAdd map[string][]string - podsToUpdate []*v1.Pod - expectedMapAfterUpdate map[string]*v1.Pod - expectedNominatedAfterUpdate map[string][]string - podsToDelete []*v1.Pod - expectedMapAfterDelete map[string]*v1.Pod - expectedNominatedAfterDelete map[string][]string + podsToAdd []*v1.Pod + expectedMapAfterAdd map[string]*v1.Pod + podsToUpdate []*v1.Pod + expectedMapAfterUpdate map[string]*v1.Pod + podsToDelete []*v1.Pod + expectedMapAfterDelete map[string]*v1.Pod }{ { podsToAdd: []*v1.Pod{pods[0], pods[1], pods[2], pods[3]}, @@ -271,10 +380,6 @@ func TestUnschedulablePodsMap(t *testing.T) { util.GetPodFullName(pods[2]): pods[2], util.GetPodFullName(pods[3]): pods[3], }, - expectedNominatedAfterAdd: map[string][]string{ - "node1": {util.GetPodFullName(pods[0]), util.GetPodFullName(pods[3])}, - "node3": {util.GetPodFullName(pods[2])}, - }, podsToUpdate: []*v1.Pod{updatedPods[0]}, expectedMapAfterUpdate: map[string]*v1.Pod{ util.GetPodFullName(pods[0]): updatedPods[0], @@ -282,19 +387,11 @@ func TestUnschedulablePodsMap(t *testing.T) { util.GetPodFullName(pods[2]): pods[2], util.GetPodFullName(pods[3]): pods[3], }, - expectedNominatedAfterUpdate: map[string][]string{ - "node1": {util.GetPodFullName(pods[3])}, - "node3": {util.GetPodFullName(pods[2]), util.GetPodFullName(pods[0])}, - }, podsToDelete: []*v1.Pod{pods[0], pods[1]}, expectedMapAfterDelete: map[string]*v1.Pod{ util.GetPodFullName(pods[2]): pods[2], util.GetPodFullName(pods[3]): pods[3], }, - expectedNominatedAfterDelete: map[string][]string{ - "node1": {util.GetPodFullName(pods[3])}, - "node3": {util.GetPodFullName(pods[2])}, - }, }, { podsToAdd: []*v1.Pod{pods[0], pods[3]}, @@ -302,20 +399,13 @@ func TestUnschedulablePodsMap(t *testing.T) { util.GetPodFullName(pods[0]): pods[0], util.GetPodFullName(pods[3]): pods[3], }, - expectedNominatedAfterAdd: map[string][]string{ - "node1": {util.GetPodFullName(pods[0]), util.GetPodFullName(pods[3])}, - }, podsToUpdate: []*v1.Pod{updatedPods[3]}, expectedMapAfterUpdate: map[string]*v1.Pod{ util.GetPodFullName(pods[0]): pods[0], util.GetPodFullName(pods[3]): updatedPods[3], }, - expectedNominatedAfterUpdate: map[string][]string{ - "node1": {util.GetPodFullName(pods[0])}, - }, - podsToDelete: []*v1.Pod{pods[0], pods[3]}, - expectedMapAfterDelete: map[string]*v1.Pod{}, - expectedNominatedAfterDelete: map[string][]string{}, + podsToDelete: []*v1.Pod{pods[0], pods[3]}, + expectedMapAfterDelete: map[string]*v1.Pod{}, }, { podsToAdd: []*v1.Pod{pods[1], pods[2]}, @@ -323,24 +413,15 @@ func TestUnschedulablePodsMap(t *testing.T) { util.GetPodFullName(pods[1]): pods[1], util.GetPodFullName(pods[2]): pods[2], }, - expectedNominatedAfterAdd: map[string][]string{ - "node3": {util.GetPodFullName(pods[2])}, - }, podsToUpdate: []*v1.Pod{updatedPods[1]}, expectedMapAfterUpdate: map[string]*v1.Pod{ util.GetPodFullName(pods[1]): updatedPods[1], util.GetPodFullName(pods[2]): pods[2], }, - expectedNominatedAfterUpdate: map[string][]string{ - "node3": {util.GetPodFullName(pods[2]), util.GetPodFullName(updatedPods[1])}, - }, podsToDelete: []*v1.Pod{pods[2], pods[3]}, expectedMapAfterDelete: map[string]*v1.Pod{ util.GetPodFullName(pods[1]): updatedPods[1], }, - expectedNominatedAfterDelete: map[string][]string{ - "node3": {util.GetPodFullName(updatedPods[1])}, - }, }, } @@ -353,10 +434,7 @@ func TestUnschedulablePodsMap(t *testing.T) { t.Errorf("#%d: Unexpected map after adding pods. Expected: %v, got: %v", i, test.expectedMapAfterAdd, upm.pods) } - if !reflect.DeepEqual(upm.nominatedPods, test.expectedNominatedAfterAdd) { - t.Errorf("#%d: Unexpected nominated map after adding pods. Expected: %v, got: %v", - i, test.expectedNominatedAfterAdd, upm.nominatedPods) - } + if len(test.podsToUpdate) > 0 { for _, p := range test.podsToUpdate { upm.Update(p) @@ -365,10 +443,6 @@ func TestUnschedulablePodsMap(t *testing.T) { t.Errorf("#%d: Unexpected map after updating pods. Expected: %v, got: %v", i, test.expectedMapAfterUpdate, upm.pods) } - if !reflect.DeepEqual(upm.nominatedPods, test.expectedNominatedAfterUpdate) { - t.Errorf("#%d: Unexpected nominated map after updating pods. Expected: %v, got: %v", - i, test.expectedNominatedAfterUpdate, upm.nominatedPods) - } } for _, p := range test.podsToDelete { upm.Delete(p) @@ -377,10 +451,6 @@ func TestUnschedulablePodsMap(t *testing.T) { t.Errorf("#%d: Unexpected map after deleting pods. Expected: %v, got: %v", i, test.expectedMapAfterDelete, upm.pods) } - if !reflect.DeepEqual(upm.nominatedPods, test.expectedNominatedAfterDelete) { - t.Errorf("#%d: Unexpected nominated map after deleting pods. Expected: %v, got: %v", - i, test.expectedNominatedAfterDelete, upm.nominatedPods) - } upm.Clear() if len(upm.pods) != 0 { t.Errorf("Expected the map to be empty, but has %v elements.", len(upm.pods)) diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go index b2857e1855..59df935e6e 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go @@ -221,7 +221,7 @@ func NewConfigFactory( if c.skipPodUpdate(pod) { return } - if err := c.podQueue.Update(pod); err != nil { + if err := c.podQueue.Update(oldObj.(*v1.Pod), pod); err != nil { runtime.HandleError(fmt.Errorf("unable to update %T: %v", newObj, err)) } }, diff --git a/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/server/storage/storage_factory.go b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/server/storage/storage_factory.go index 429e14d5ca..4a5e8dcb30 100644 --- a/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/server/storage/storage_factory.go +++ b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/server/storage/storage_factory.go @@ -314,8 +314,10 @@ func (s *DefaultStorageFactory) Backends() []Backend { backends := []Backend{} for server := range servers { backends = append(backends, Backend{ - Server: server, - TLSConfig: tlsConfig, + Server: server, + // We can't share TLSConfig across different backends to avoid races. + // For more details see: http://pr.k8s.io/59338 + TLSConfig: tlsConfig.Clone(), }) } return backends diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go b/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go index cd0855d45a..c7ec9c0763 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/downwardapi_volume.go @@ -46,7 +46,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide podname only ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podname") + pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podinfo/podname") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("%s\n", podName), @@ -61,10 +61,10 @@ var _ = Describe("[sig-storage] Downward API volume", func() { framework.ConformanceIt("should set DefaultMode on files ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) defaultMode := int32(0400) - pod := downwardAPIVolumePodForModeTest(podName, "/etc/podname", nil, &defaultMode) + pod := downwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", nil, &defaultMode) f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--------", + "mode of file \"/etc/podinfo/podname\": -r--------", }) }) @@ -76,10 +76,10 @@ var _ = Describe("[sig-storage] Downward API volume", func() { framework.ConformanceIt("should set mode on item file ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) mode := int32(0400) - pod := downwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil) + pod := downwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", &mode, nil) f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--------", + "mode of file \"/etc/podinfo/podname\": -r--------", }) }) @@ -87,7 +87,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { podName := "metadata-volume-" + string(uuid.NewUUID()) uid := int64(1001) gid := int64(1234) - pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podname") + pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podinfo/podname") pod.Spec.SecurityContext = &v1.PodSecurityContext{ RunAsUser: &uid, FSGroup: &gid, @@ -102,13 +102,13 @@ var _ = Describe("[sig-storage] Downward API volume", func() { uid := int64(1001) gid := int64(1234) mode := int32(0440) /* setting fsGroup sets mode to at least 440 */ - pod := downwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil) + pod := downwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", &mode, nil) pod.Spec.SecurityContext = &v1.PodSecurityContext{ RunAsUser: &uid, FSGroup: &gid, } f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--r-----", + "mode of file \"/etc/podinfo/podname\": -r--r-----", }) }) @@ -123,7 +123,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { labels["key2"] = "value2" podName := "labelsupdate" + string(uuid.NewUUID()) - pod := downwardAPIVolumePodForUpdateTest(podName, labels, map[string]string{}, "/etc/labels") + pod := downwardAPIVolumePodForUpdateTest(podName, labels, map[string]string{}, "/etc/podinfo/labels") containerName := "client-container" By("Creating the pod") podClient.CreateSync(pod) @@ -153,7 +153,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { annotations := map[string]string{} annotations["builder"] = "bar" podName := "annotationupdate" + string(uuid.NewUUID()) - pod := downwardAPIVolumePodForUpdateTest(podName, map[string]string{}, annotations, "/etc/annotations") + pod := downwardAPIVolumePodForUpdateTest(podName, map[string]string{}, annotations, "/etc/podinfo/annotations") containerName := "client-container" By("Creating the pod") @@ -185,7 +185,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide container's cpu limit ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_limit") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/cpu_limit") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("2\n"), @@ -199,7 +199,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide container's memory limit ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_limit") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/memory_limit") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("67108864\n"), @@ -213,7 +213,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide container's cpu request ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_request") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/cpu_request") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("1\n"), @@ -227,7 +227,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide container's memory request ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_request") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/memory_request") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("33554432\n"), @@ -242,7 +242,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide node allocatable (cpu) as default cpu limit if the limit is not set ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/cpu_limit") + pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/podinfo/cpu_limit") f.TestContainerOutputRegexp("downward API volume plugin", pod, 0, []string{"[1-9]"}) }) @@ -255,7 +255,7 @@ var _ = Describe("[sig-storage] Downward API volume", func() { */ framework.ConformanceIt("should provide node allocatable (memory) as default memory limit if the limit is not set ", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/memory_limit") + pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/podinfo/memory_limit") f.TestContainerOutputRegexp("downward API volume plugin", pod, 0, []string{"[1-9]"}) }) @@ -273,7 +273,7 @@ func downwardAPIVolumePodForModeTest(name, filePath string, itemMode, defaultMod VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", }, }, }, @@ -299,7 +299,7 @@ func downwardAPIVolumePodForSimpleTest(name string, filePath string) *v1.Pod { VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", ReadOnly: false, }, }, @@ -340,7 +340,7 @@ func downwardAPIVolumeBaseContainers(name, filePath string) []v1.Container { VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", ReadOnly: false, }, }, @@ -358,7 +358,7 @@ func downwardAPIVolumeDefaultBaseContainer(name, filePath string) []v1.Container VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", }, }, }, @@ -377,7 +377,7 @@ func downwardAPIVolumePodForUpdateTest(name string, labels, annotations map[stri VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", ReadOnly: false, }, }, diff --git a/vendor/k8s.io/kubernetes/test/e2e/common/projected.go b/vendor/k8s.io/kubernetes/test/e2e/common/projected.go index 1019346673..b8b3e964e4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/common/projected.go +++ b/vendor/k8s.io/kubernetes/test/e2e/common/projected.go @@ -866,7 +866,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide podname only", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podname") + pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podinfo/podname") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("%s\n", podName), @@ -882,10 +882,10 @@ var _ = Describe("[sig-storage] Projected", func() { framework.ConformanceIt("should set DefaultMode on files", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) defaultMode := int32(0400) - pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podname", nil, &defaultMode) + pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", nil, &defaultMode) f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--------", + "mode of file \"/etc/podinfo/podname\": -r--------", }) }) @@ -897,10 +897,10 @@ var _ = Describe("[sig-storage] Projected", func() { framework.ConformanceIt("should set mode on item file", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) mode := int32(0400) - pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil) + pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", &mode, nil) f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--------", + "mode of file \"/etc/podinfo/podname\": -r--------", }) }) @@ -908,7 +908,7 @@ var _ = Describe("[sig-storage] Projected", func() { podName := "metadata-volume-" + string(uuid.NewUUID()) uid := int64(1001) gid := int64(1234) - pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podname") + pod := downwardAPIVolumePodForSimpleTest(podName, "/etc/podinfo/podname") pod.Spec.SecurityContext = &v1.PodSecurityContext{ RunAsUser: &uid, FSGroup: &gid, @@ -923,13 +923,13 @@ var _ = Describe("[sig-storage] Projected", func() { uid := int64(1001) gid := int64(1234) mode := int32(0440) /* setting fsGroup sets mode to at least 440 */ - pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil) + pod := projectedDownwardAPIVolumePodForModeTest(podName, "/etc/podinfo/podname", &mode, nil) pod.Spec.SecurityContext = &v1.PodSecurityContext{ RunAsUser: &uid, FSGroup: &gid, } f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ - "mode of file \"/etc/podname\": -r--r-----", + "mode of file \"/etc/podinfo/podname\": -r--r-----", }) }) @@ -945,7 +945,7 @@ var _ = Describe("[sig-storage] Projected", func() { labels["key2"] = "value2" podName := "labelsupdate" + string(uuid.NewUUID()) - pod := projectedDownwardAPIVolumePodForUpdateTest(podName, labels, map[string]string{}, "/etc/labels") + pod := projectedDownwardAPIVolumePodForUpdateTest(podName, labels, map[string]string{}, "/etc/podinfo/labels") containerName := "client-container" By("Creating the pod") podClient.CreateSync(pod) @@ -976,7 +976,7 @@ var _ = Describe("[sig-storage] Projected", func() { annotations := map[string]string{} annotations["builder"] = "bar" podName := "annotationupdate" + string(uuid.NewUUID()) - pod := projectedDownwardAPIVolumePodForUpdateTest(podName, map[string]string{}, annotations, "/etc/annotations") + pod := projectedDownwardAPIVolumePodForUpdateTest(podName, map[string]string{}, annotations, "/etc/podinfo/annotations") containerName := "client-container" By("Creating the pod") @@ -1008,7 +1008,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide container's cpu limit", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_limit") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/cpu_limit") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("2\n"), @@ -1022,7 +1022,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide container's memory limit", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_limit") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/memory_limit") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("67108864\n"), @@ -1036,7 +1036,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide container's cpu request", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_request") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/cpu_request") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("1\n"), @@ -1050,7 +1050,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide container's memory request", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_request") + pod := downwardAPIVolumeForContainerResources(podName, "/etc/podinfo/memory_request") f.TestContainerOutput("downward API volume plugin", pod, 0, []string{ fmt.Sprintf("33554432\n"), @@ -1065,7 +1065,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide node allocatable (cpu) as default cpu limit if the limit is not set", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/cpu_limit") + pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/podinfo/cpu_limit") f.TestContainerOutputRegexp("downward API volume plugin", pod, 0, []string{"[1-9]"}) }) @@ -1078,7 +1078,7 @@ var _ = Describe("[sig-storage] Projected", func() { */ framework.ConformanceIt("should provide node allocatable (memory) as default memory limit if the limit is not set", func() { podName := "downwardapi-volume-" + string(uuid.NewUUID()) - pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/memory_limit") + pod := downwardAPIVolumeForDefaultContainerResources(podName, "/etc/podinfo/memory_limit") f.TestContainerOutputRegexp("downward API volume plugin", pod, 0, []string{"[1-9]"}) }) @@ -1495,7 +1495,7 @@ func projectedDownwardAPIVolumePodForModeTest(name, filePath string, itemMode, d VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", }, }, }, @@ -1521,7 +1521,7 @@ func projectedDownwardAPIVolumePodForUpdateTest(name string, labels, annotations VolumeMounts: []v1.VolumeMount{ { Name: "podinfo", - MountPath: "/etc", + MountPath: "/etc/podinfo", ReadOnly: false, }, }, diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go index ae3bf9ebd9..b2fe577ede 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go @@ -1327,23 +1327,23 @@ func WaitForPodRunningInNamespace(c clientset.Interface, pod *v1.Pod) error { if pod.Status.Phase == v1.PodRunning { return nil } - return waitTimeoutForPodRunningInNamespace(c, pod.Name, pod.Namespace, PodStartTimeout) + return WaitTimeoutForPodRunningInNamespace(c, pod.Name, pod.Namespace, PodStartTimeout) } // Waits default amount of time (PodStartTimeout) for the specified pod to become running. // Returns an error if timeout occurs first, or pod goes in to failed state. func WaitForPodNameRunningInNamespace(c clientset.Interface, podName, namespace string) error { - return waitTimeoutForPodRunningInNamespace(c, podName, namespace, PodStartTimeout) + return WaitTimeoutForPodRunningInNamespace(c, podName, namespace, PodStartTimeout) } // Waits an extended amount of time (slowPodStartTimeout) for the specified pod to become running. // The resourceVersion is used when Watching object changes, it tells since when we care // about changes to the pod. Returns an error if timeout occurs first, or pod goes in to failed state. func waitForPodRunningInNamespaceSlow(c clientset.Interface, podName, namespace string) error { - return waitTimeoutForPodRunningInNamespace(c, podName, namespace, slowPodStartTimeout) + return WaitTimeoutForPodRunningInNamespace(c, podName, namespace, slowPodStartTimeout) } -func waitTimeoutForPodRunningInNamespace(c clientset.Interface, podName, namespace string, timeout time.Duration) error { +func WaitTimeoutForPodRunningInNamespace(c clientset.Interface, podName, namespace string, timeout time.Duration) error { return wait.PollImmediate(Poll, timeout, podRunning(c, podName, namespace)) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD b/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD index c65c4413f9..9eb907bac9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/BUILD @@ -19,6 +19,7 @@ go_library( "persistent_volumes-vsphere.go", "pv_reclaimpolicy.go", "pvc_label_selector.go", + "subpath.go", "volume_io.go", "volume_metrics.go", "volume_provisioning.go", @@ -79,6 +80,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go b/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go new file mode 100644 index 0000000000..e0e86e1ad0 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/subpath.go @@ -0,0 +1,742 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package storage + +import ( + "fmt" + "path/filepath" + "strings" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/rand" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/kubernetes/test/e2e/framework" + imageutils "k8s.io/kubernetes/test/utils/image" + + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var ( + volumePath = "/test-volume" + volumeName = "test-volume" + fileName = "test-file" + retryDuration = 180 + mountImage = imageutils.GetE2EImage(imageutils.Mounttest) +) + +type volInfo struct { + source *v1.VolumeSource + node string +} + +type volSource interface { + createVolume(f *framework.Framework) volInfo + cleanupVolume(f *framework.Framework) +} + +var initVolSources = map[string]func() volSource{ + "hostPath": initHostpath, + "hostPathSymlink": initHostpathSymlink, + "emptyDir": initEmptydir, + "gcePD": initGCEPD, + "gcePDPartitioned": initGCEPDPartition, + "nfs": initNFS, + "nfsPVC": initNFSPVC, + "gluster": initGluster, +} + +var _ = SIGDescribe("Subpath", func() { + var ( + subPath string + subPathDir string + filePathInSubpath string + filePathInVolume string + pod *v1.Pod + vol volSource + ) + + f := framework.NewDefaultFramework("subpath") + + for volType, volInit := range initVolSources { + curVolType := volType + curVolInit := volInit + + Context(fmt.Sprintf("[Volume type: %v]", curVolType), func() { + BeforeEach(func() { + By(fmt.Sprintf("Initializing %s volume", curVolType)) + vol = curVolInit() + subPath = f.Namespace.Name + subPathDir = filepath.Join(volumePath, subPath) + filePathInSubpath = filepath.Join(volumePath, fileName) + filePathInVolume = filepath.Join(subPathDir, fileName) + volInfo := vol.createVolume(f) + pod = testPodSubpath(subPath, curVolType, volInfo.source) + pod.Namespace = f.Namespace.Name + pod.Spec.NodeName = volInfo.node + }) + + AfterEach(func() { + By("Deleting pod") + err := framework.DeletePodWithWait(f, f.ClientSet, pod) + Expect(err).ToNot(HaveOccurred()) + + By("Cleaning up volume") + vol.cleanupVolume(f) + }) + + It("should support non-existent path", func() { + // Write the file in the subPath from container 0 + setWriteCommand(filePathInSubpath, &pod.Spec.Containers[0]) + + // Read it from outside the subPath from container 1 + testReadFile(f, filePathInVolume, pod, 1) + }) + + It("should support existing directory", func() { + // Create the directory + setInitCommand(pod, fmt.Sprintf("mkdir -p %s", subPathDir)) + + // Write the file in the subPath from container 0 + setWriteCommand(filePathInSubpath, &pod.Spec.Containers[0]) + + // Read it from outside the subPath from container 1 + testReadFile(f, filePathInVolume, pod, 1) + }) + + It("should support existing single file", func() { + // Create the file in the init container + setInitCommand(pod, fmt.Sprintf("mkdir -p %s; echo \"mount-tester new file\" > %s", subPathDir, filePathInVolume)) + + // Read it from inside the subPath from container 0 + testReadFile(f, filePathInSubpath, pod, 0) + }) + + It("should fail if subpath directory is outside the volume [Slow]", func() { + // Create the subpath outside the volume + setInitCommand(pod, fmt.Sprintf("ln -s /bin %s", subPathDir)) + + // Pod should fail + testPodFailSupath(f, pod) + }) + + It("should fail if subpath file is outside the volume [Slow]", func() { + // Create the subpath outside the volume + setInitCommand(pod, fmt.Sprintf("ln -s /bin/sh %s", subPathDir)) + + // Pod should fail + testPodFailSupath(f, pod) + }) + + It("should fail if non-existent subpath is outside the volume [Slow]", func() { + // Create the subpath outside the volume + setInitCommand(pod, fmt.Sprintf("ln -s /bin/notanexistingpath %s", subPathDir)) + + // Pod should fail + testPodFailSupath(f, pod) + }) + + It("should fail if subpath with backstepping is outside the volume [Slow]", func() { + // Create the subpath outside the volume + setInitCommand(pod, fmt.Sprintf("ln -s ../ %s", subPathDir)) + + // Pod should fail + testPodFailSupath(f, pod) + }) + + It("should support creating multiple subpath from same volumes [Slow]", func() { + subpathDir1 := filepath.Join(volumePath, "subpath1") + subpathDir2 := filepath.Join(volumePath, "subpath2") + filepath1 := filepath.Join("/test-subpath1", fileName) + filepath2 := filepath.Join("/test-subpath2", fileName) + setInitCommand(pod, fmt.Sprintf("mkdir -p %s; mkdir -p %s", subpathDir1, subpathDir2)) + + addSubpathVolumeContainer(&pod.Spec.Containers[0], v1.VolumeMount{ + Name: volumeName, + MountPath: "/test-subpath1", + SubPath: "subpath1", + }) + addSubpathVolumeContainer(&pod.Spec.Containers[0], v1.VolumeMount{ + Name: volumeName, + MountPath: "/test-subpath2", + SubPath: "subpath2", + }) + + addMultipleWrites(&pod.Spec.Containers[0], filepath1, filepath2) + testMultipleReads(f, pod, 0, filepath1, filepath2) + }) + + It("should support restarting containers [Slow]", func() { + // Create the directory + setInitCommand(pod, fmt.Sprintf("mkdir -p %v", subPathDir)) + + testPodContainerRestart(f, pod, filePathInVolume, filePathInSubpath) + }) + }) + } + + // TODO: add a test case for the same disk with two partitions +}) + +func testPodSubpath(subpath, volumeType string, source *v1.VolumeSource) *v1.Pod { + suffix := strings.ToLower(fmt.Sprintf("%s-%s", volumeType, rand.String(4))) + privileged := true + gracePeriod := int64(1) + return &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("pod-subpath-test-%s", suffix), + }, + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ + { + Name: fmt.Sprintf("init-volume-%s", suffix), + Image: "busybox", + VolumeMounts: []v1.VolumeMount{ + { + Name: volumeName, + MountPath: volumePath, + }, + }, + SecurityContext: &v1.SecurityContext{ + Privileged: &privileged, + }, + }, + }, + Containers: []v1.Container{ + { + Name: fmt.Sprintf("test-container-subpath-%s", suffix), + Image: mountImage, + VolumeMounts: []v1.VolumeMount{ + { + Name: volumeName, + MountPath: volumePath, + SubPath: subpath, + }, + }, + SecurityContext: &v1.SecurityContext{ + Privileged: &privileged, + }, + }, + { + Name: fmt.Sprintf("test-container-volume-%s", suffix), + Image: mountImage, + VolumeMounts: []v1.VolumeMount{ + { + Name: volumeName, + MountPath: volumePath, + }, + }, + SecurityContext: &v1.SecurityContext{ + Privileged: &privileged, + }, + }, + }, + RestartPolicy: v1.RestartPolicyNever, + TerminationGracePeriodSeconds: &gracePeriod, + Volumes: []v1.Volume{ + { + Name: volumeName, + VolumeSource: *source, + }, + }, + }, + } +} + +func setInitCommand(pod *v1.Pod, command string) { + pod.Spec.InitContainers[0].Command = []string{"/bin/sh", "-ec", command} +} + +func setWriteCommand(file string, container *v1.Container) { + container.Args = []string{ + fmt.Sprintf("--new_file_0644=%v", file), + fmt.Sprintf("--file_mode=%v", file), + } +} + +func addSubpathVolumeContainer(container *v1.Container, volumeMount v1.VolumeMount) { + existingMounts := container.VolumeMounts + container.VolumeMounts = append(existingMounts, volumeMount) +} + +func addMultipleWrites(container *v1.Container, file1 string, file2 string) { + container.Args = []string{ + fmt.Sprintf("--new_file_0644=%v", file1), + fmt.Sprintf("--new_file_0666=%v", file2), + } +} + +func testMultipleReads(f *framework.Framework, pod *v1.Pod, containerIndex int, file1 string, file2 string) { + By(fmt.Sprintf("Creating pod %s", pod.Name)) + f.TestContainerOutput("multi_subpath", pod, containerIndex, []string{ + "content of file \"" + file1 + "\": mount-tester new file", + "content of file \"" + file2 + "\": mount-tester new file", + }) +} + +func setReadCommand(file string, container *v1.Container) { + container.Args = []string{ + fmt.Sprintf("--file_content_in_loop=%v", file), + fmt.Sprintf("--retry_time=%d", retryDuration), + } +} + +func testReadFile(f *framework.Framework, file string, pod *v1.Pod, containerIndex int) { + setReadCommand(file, &pod.Spec.Containers[containerIndex]) + + By(fmt.Sprintf("Creating pod %s", pod.Name)) + f.TestContainerOutput("subpath", pod, containerIndex, []string{ + "content of file \"" + file + "\": mount-tester new file", + }) +} + +func testPodFailSupath(f *framework.Framework, pod *v1.Pod) { + By(fmt.Sprintf("Creating pod %s", pod.Name)) + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) + Expect(err).ToNot(HaveOccurred()) + defer func() { + framework.DeletePodWithWait(f, f.ClientSet, pod) + }() + err = framework.WaitTimeoutForPodRunningInNamespace(f.ClientSet, pod.Name, pod.Namespace, time.Minute) + Expect(err).To(HaveOccurred()) + + By("Checking for subpath error event") + selector := fields.Set{ + "involvedObject.kind": "Pod", + "involvedObject.name": pod.Name, + "involvedObject.namespace": f.Namespace.Name, + "reason": "Failed", + }.AsSelector().String() + options := metav1.ListOptions{FieldSelector: selector} + events, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(options) + Expect(err).NotTo(HaveOccurred()) + Expect(len(events.Items)).NotTo(Equal(0)) + Expect(events.Items[0].Message).To(ContainSubstring("subPath")) +} + +func testPodContainerRestart(f *framework.Framework, pod *v1.Pod, fileInVolume, fileInSubpath string) { + pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure + + // Add liveness probe to subpath container + pod.Spec.Containers[0].Image = "busybox" + pod.Spec.Containers[0].Command = []string{"/bin/sh", "-ec", "sleep 100000"} + pod.Spec.Containers[0].LivenessProbe = &v1.Probe{ + Handler: v1.Handler{ + Exec: &v1.ExecAction{ + Command: []string{"cat", fileInSubpath}, + }, + }, + InitialDelaySeconds: 15, + FailureThreshold: 1, + PeriodSeconds: 2, + } + + // Set volume container to write file + writeCmd := fmt.Sprintf("echo test > %v", fileInVolume) + pod.Spec.Containers[1].Image = "busybox" + pod.Spec.Containers[1].Command = []string{"/bin/sh", "-ec", fmt.Sprintf("%v; sleep 100000", writeCmd)} + + // Start pod + By(fmt.Sprintf("Creating pod %s", pod.Name)) + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) + Expect(err).ToNot(HaveOccurred()) + + err = framework.WaitTimeoutForPodRunningInNamespace(f.ClientSet, pod.Name, pod.Namespace, time.Minute) + Expect(err).ToNot(HaveOccurred()) + + By("Failing liveness probe") + out, err := podContainerExec(pod, 1, fmt.Sprintf("rm %v", fileInVolume)) + framework.Logf("Pod exec output: %v", out) + Expect(err).ToNot(HaveOccurred()) + + // Check that container has restarted + By("Waiting for container to restart") + restarts := int32(0) + err = wait.PollImmediate(10*time.Second, 2*time.Minute, func() (bool, error) { + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + for _, status := range pod.Status.ContainerStatuses { + if status.Name == pod.Spec.Containers[0].Name { + framework.Logf("Container %v, restarts: %v", status.Name, status.RestartCount) + restarts = status.RestartCount + if restarts > 0 { + framework.Logf("Container has restart count: %v", restarts) + return true, nil + } + } + } + return false, nil + }) + Expect(err).ToNot(HaveOccurred()) + + // Fix liveness probe + By("Rewriting the file") + writeCmd = fmt.Sprintf("echo test-after > %v", fileInVolume) + out, err = podContainerExec(pod, 1, writeCmd) + framework.Logf("Pod exec output: %v", out) + Expect(err).ToNot(HaveOccurred()) + + // Wait for container restarts to stabilize + By("Waiting for container to stop restarting") + stableCount := int(0) + stableThreshold := int(time.Minute / framework.Poll) + err = wait.PollImmediate(framework.Poll, 2*time.Minute, func() (bool, error) { + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + for _, status := range pod.Status.ContainerStatuses { + if status.Name == pod.Spec.Containers[0].Name { + if status.RestartCount == restarts { + stableCount++ + if stableCount > stableThreshold { + framework.Logf("Container restart has stabilized") + return true, nil + } + } else { + restarts = status.RestartCount + stableCount = 0 + framework.Logf("Container has restart count: %v", restarts) + } + break + } + } + return false, nil + }) + Expect(err).ToNot(HaveOccurred()) + + // Verify content of file in subpath + out, err = podContainerExec(pod, 0, fmt.Sprintf("cat %v", fileInSubpath)) + framework.Logf("Pod exec output: %v", out) + Expect(err).ToNot(HaveOccurred()) + Expect(strings.TrimSpace(out)).To(BeEquivalentTo("test-after")) +} + +func podContainerExec(pod *v1.Pod, containerIndex int, bashExec string) (string, error) { + return framework.RunKubectl("exec", fmt.Sprintf("--namespace=%s", pod.Namespace), pod.Name, "--container", pod.Spec.Containers[containerIndex].Name, "--", "/bin/sh", "-c", bashExec) +} + +type hostpathSource struct { +} + +func initHostpath() volSource { + return &hostpathSource{} +} + +func (s *hostpathSource) createVolume(f *framework.Framework) volInfo { + return volInfo{ + source: &v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{ + Path: "/tmp", + }, + }, + } +} + +func (s *hostpathSource) cleanupVolume(f *framework.Framework) { +} + +type hostpathSymlinkSource struct { +} + +func initHostpathSymlink() volSource { + return &hostpathSymlinkSource{} +} + +func (s *hostpathSymlinkSource) createVolume(f *framework.Framework) volInfo { + nodes := framework.GetReadySchedulableNodesOrDie(f.ClientSet) + Expect(len(nodes.Items)).NotTo(BeZero(), "No available nodes for scheduling") + + node0 := &nodes.Items[0] + sourcePath := fmt.Sprintf("/tmp/%v", f.Namespace.Name) + targetPath := fmt.Sprintf("/tmp/%v-link", f.Namespace.Name) + cmd := fmt.Sprintf("mkdir %v -m 777 && ln -s %v %v", sourcePath, sourcePath, targetPath) + privileged := true + + // Launch pod to initialize hostpath directory and symlink + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("hostpath-symlink-prep-%s", f.Namespace.Name), + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: fmt.Sprintf("init-volume-%s", f.Namespace.Name), + Image: "busybox", + Command: []string{"/bin/sh", "-ec", cmd}, + VolumeMounts: []v1.VolumeMount{ + { + Name: volumeName, + MountPath: "/tmp", + }, + }, + SecurityContext: &v1.SecurityContext{ + Privileged: &privileged, + }, + }, + }, + RestartPolicy: v1.RestartPolicyNever, + Volumes: []v1.Volume{ + { + Name: volumeName, + VolumeSource: v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{ + Path: "/tmp", + }, + }, + }, + }, + NodeName: node0.Name, + }, + } + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) + Expect(err).ToNot(HaveOccurred()) + + err = framework.WaitForPodSuccessInNamespace(f.ClientSet, pod.Name, pod.Namespace) + Expect(err).ToNot(HaveOccurred()) + + err = framework.DeletePodWithWait(f, f.ClientSet, pod) + Expect(err).ToNot(HaveOccurred()) + + return volInfo{ + source: &v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{ + Path: targetPath, + }, + }, + node: node0.Name, + } +} + +func (s *hostpathSymlinkSource) cleanupVolume(f *framework.Framework) { +} + +type emptydirSource struct { +} + +func initEmptydir() volSource { + return &emptydirSource{} +} + +func (s *emptydirSource) createVolume(f *framework.Framework) volInfo { + return volInfo{ + source: &v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + } +} + +func (s *emptydirSource) cleanupVolume(f *framework.Framework) { +} + +type gcepdSource struct { + diskName string +} + +func initGCEPD() volSource { + framework.SkipUnlessProviderIs("gce", "gke") + return &gcepdSource{} +} + +func (s *gcepdSource) createVolume(f *framework.Framework) volInfo { + var err error + + framework.Logf("Creating GCE PD volume") + s.diskName, err = framework.CreatePDWithRetry() + framework.ExpectNoError(err, "Error creating PD") + + return volInfo{ + source: &v1.VolumeSource{ + GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{PDName: s.diskName}, + }, + } +} + +func (s *gcepdSource) cleanupVolume(f *framework.Framework) { + if s.diskName != "" { + err := framework.DeletePDWithRetry(s.diskName) + framework.ExpectNoError(err, "Error deleting PD") + } +} + +type gcepdPartitionSource struct { + diskName string +} + +func initGCEPDPartition() volSource { + // Need to manually create, attach, partition, detach the GCE PD + // with disk name "subpath-partitioned-disk" before running this test + manual := true + if manual { + framework.Skipf("Skipping manual GCE PD partition test") + } + framework.SkipUnlessProviderIs("gce", "gke") + return &gcepdPartitionSource{diskName: "subpath-partitioned-disk"} +} + +func (s *gcepdPartitionSource) createVolume(f *framework.Framework) volInfo { + // TODO: automate partitioned of GCE PD once it supports raw block volumes + // framework.Logf("Creating GCE PD volume") + // s.diskName, err = framework.CreatePDWithRetry() + // framework.ExpectNoError(err, "Error creating PD") + + return volInfo{ + source: &v1.VolumeSource{ + GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ + PDName: s.diskName, + Partition: 1, + }, + }, + } +} + +func (s *gcepdPartitionSource) cleanupVolume(f *framework.Framework) { + if s.diskName != "" { + // err := framework.DeletePDWithRetry(s.diskName) + // framework.ExpectNoError(err, "Error deleting PD") + } +} + +type nfsSource struct { + serverPod *v1.Pod +} + +func initNFS() volSource { + return &nfsSource{} +} + +func (s *nfsSource) createVolume(f *framework.Framework) volInfo { + var serverIP string + + framework.Logf("Creating NFS server") + _, s.serverPod, serverIP = framework.NewNFSServer(f.ClientSet, f.Namespace.Name, []string{"-G", "777", "/exports"}) + + return volInfo{ + source: &v1.VolumeSource{ + NFS: &v1.NFSVolumeSource{ + Server: serverIP, + Path: "/exports", + }, + }, + } +} + +func (s *nfsSource) cleanupVolume(f *framework.Framework) { + if s.serverPod != nil { + framework.DeletePodWithWait(f, f.ClientSet, s.serverPod) + } +} + +type glusterSource struct { + serverPod *v1.Pod +} + +func initGluster() volSource { + framework.SkipUnlessNodeOSDistroIs("gci", "ubuntu") + return &glusterSource{} +} + +func (s *glusterSource) createVolume(f *framework.Framework) volInfo { + framework.Logf("Creating GlusterFS server") + _, s.serverPod, _ = framework.NewGlusterfsServer(f.ClientSet, f.Namespace.Name) + + return volInfo{ + source: &v1.VolumeSource{ + Glusterfs: &v1.GlusterfsVolumeSource{ + EndpointsName: "gluster-server", + Path: "test_vol", + }, + }, + } +} + +func (s *glusterSource) cleanupVolume(f *framework.Framework) { + if s.serverPod != nil { + framework.DeletePodWithWait(f, f.ClientSet, s.serverPod) + err := f.ClientSet.CoreV1().Endpoints(f.Namespace.Name).Delete("gluster-server", nil) + Expect(err).NotTo(HaveOccurred(), "Gluster delete endpoints failed") + } +} + +// TODO: need a better way to wrap PVC. A generic framework should support both static and dynamic PV. +// For static PV, can reuse createVolume methods for inline volumes +type nfsPVCSource struct { + serverPod *v1.Pod + pvc *v1.PersistentVolumeClaim + pv *v1.PersistentVolume +} + +func initNFSPVC() volSource { + return &nfsPVCSource{} +} + +func (s *nfsPVCSource) createVolume(f *framework.Framework) volInfo { + var serverIP string + + framework.Logf("Creating NFS server") + _, s.serverPod, serverIP = framework.NewNFSServer(f.ClientSet, f.Namespace.Name, []string{"-G", "777", "/exports"}) + + pvConfig := framework.PersistentVolumeConfig{ + NamePrefix: "nfs-", + StorageClassName: f.Namespace.Name, + PVSource: v1.PersistentVolumeSource{ + NFS: &v1.NFSVolumeSource{ + Server: serverIP, + Path: "/exports", + }, + }, + } + pvcConfig := framework.PersistentVolumeClaimConfig{ + StorageClassName: &f.Namespace.Name, + } + + framework.Logf("Creating PVC and PV") + pv, pvc, err := framework.CreatePVCPV(f.ClientSet, pvConfig, pvcConfig, f.Namespace.Name, false) + Expect(err).NotTo(HaveOccurred(), "PVC, PV creation failed") + + err = framework.WaitOnPVandPVC(f.ClientSet, f.Namespace.Name, pv, pvc) + Expect(err).NotTo(HaveOccurred(), "PVC, PV failed to bind") + + s.pvc = pvc + s.pv = pv + + return volInfo{ + source: &v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvc.Name, + }, + }, + } +} + +func (s *nfsPVCSource) cleanupVolume(f *framework.Framework) { + if s.pvc != nil || s.pv != nil { + if errs := framework.PVPVCCleanup(f.ClientSet, f.Namespace.Name, s.pv, s.pvc); len(errs) != 0 { + framework.Failf("Failed to delete PVC or PV: %v", utilerrors.NewAggregate(errs)) + } + } + if s.serverPod != nil { + framework.DeletePodWithWait(f, f.ClientSet, s.serverPod) + } +} diff --git a/vendor/k8s.io/kubernetes/test/images/Makefile b/vendor/k8s.io/kubernetes/test/images/Makefile index 0140d3234c..bbb15fb80d 100644 --- a/vendor/k8s.io/kubernetes/test/images/Makefile +++ b/vendor/k8s.io/kubernetes/test/images/Makefile @@ -15,7 +15,7 @@ REGISTRY ?= gcr.io/kubernetes-e2e-test-images GOARM=7 QEMUVERSION=v2.9.1 -GOLANG_VERSION=1.9.2 +GOLANG_VERSION=1.9.3 export ifndef WHAT From cbbdfa0e5e9a4ec6b3fcd499b7b8a8cf2fe3eb77 Mon Sep 17 00:00:00 2001 From: Serguei Bezverkhi Date: Sat, 24 Mar 2018 09:06:14 -0400 Subject: [PATCH 2/3] Refactor external-provisioner --- cmd/csi-provisioner/csi-provisioner.go | 18 +++++- main.go | 7 --- pkg/controller/controller.go | 84 +++++++++++++++++--------- pkg/controller/controller_test.go | 2 +- 4 files changed, 72 insertions(+), 39 deletions(-) delete mode 100644 main.go diff --git a/cmd/csi-provisioner/csi-provisioner.go b/cmd/csi-provisioner/csi-provisioner.go index 86d41c6b23..15b7f46546 100644 --- a/cmd/csi-provisioner/csi-provisioner.go +++ b/cmd/csi-provisioner/csi-provisioner.go @@ -28,6 +28,8 @@ import ( ctrl "github.com/kubernetes-csi/external-provisioner/pkg/controller" "github.com/kubernetes-incubator/external-storage/lib/controller" + "google.golang.org/grpc" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -38,7 +40,7 @@ var ( provisioner = flag.String("provisioner", "", "Name of the provisioner. The provisioner will only provision volumes for claims that request a StorageClass with a provisioner field set equal to this name.") master = flag.String("master", "", "Master URL to build a client config from. Either this or kubeconfig needs to be set if the provisioner is being run out of cluster.") kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file. Either this or master needs to be set if the provisioner is being run out of cluster.") - csiEndpoint = flag.String("csi-address", "", "The gRPC endpoint for Target CSI Volume") + csiEndpoint = flag.String("csi-address", "/run/csi/socket", "The gRPC endpoint for Target CSI Volume") connectionTimeout = flag.Duration("connection-timeout", 10*time.Second, "Timeout for waiting for CSI driver socket.") volumeNamePrefix = flag.String("volume-name-prefix", "kubernetes-dynamic-pv", "Prefix to apply to the name of a created volume") volumeNameUUIDLength = flag.Int("volume-name-uuid-length", 16, "Length in characters for the generated uuid of a created volume") @@ -87,9 +89,21 @@ func init() { timeStamp := time.Now().UnixNano() / int64(time.Millisecond) identity := strconv.FormatInt(timeStamp, 10) + "-" + strconv.Itoa(rand.Intn(10000)) + "-" + *provisioner + // Provisioner will stay in Init until driver opens csi socket, once it's done + // controller will exit this loop and proceed normally. + socketDown := true + grpcClient := &grpc.ClientConn{} + for socketDown { + grpcClient, err = ctrl.Connect(*csiEndpoint, *connectionTimeout) + if err == nil { + socketDown = false + continue + } + time.Sleep(10 * time.Second) + } // Create the provisioner: it implements the Provisioner interface expected by // the controller - csiProvisioner := ctrl.NewCSIProvisioner(clientset, *csiEndpoint, *connectionTimeout, identity, *volumeNamePrefix, *volumeNameUUIDLength) + csiProvisioner := ctrl.NewCSIProvisioner(clientset, *csiEndpoint, *connectionTimeout, identity, *volumeNamePrefix, *volumeNameUUIDLength, grpcClient) provisionController = controller.NewProvisionController( clientset, *provisioner, diff --git a/main.go b/main.go deleted file mode 100644 index c52faee5b6..0000000000 --- a/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "fmt" - -func main() { - fmt.Printf("This is the external-provisioner main... .\n") -} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index bae9d8e40d..efe5dd2d41 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -44,10 +44,11 @@ const ( secretNamespaceKey = "csiProvisionerSecretNamespace" ) +// CSIProvisioner struct type csiProvisioner struct { client kubernetes.Interface csiClient csi.ControllerClient - driverName string + grpcClient *grpc.ClientConn timeout time.Duration identity string volumeNamePrefix string @@ -80,7 +81,7 @@ func logGRPC(ctx context.Context, method string, req, reply interface{}, cc *grp return err } -func connect(address string, timeout time.Duration) (*grpc.ClientConn, error) { +func Connect(address string, timeout time.Duration) (*grpc.ClientConn, error) { glog.V(2).Infof("Connecting to %s", address) dialOptions := []grpc.DialOption{ grpc.WithInsecure(), @@ -102,7 +103,7 @@ func connect(address string, timeout time.Duration) (*grpc.ClientConn, error) { for { if !conn.WaitForStateChange(ctx, conn.GetState()) { glog.V(4).Infof("Connection timed out") - return conn, nil // return nil, subsequent GetPluginInfo will show the real connection error + return conn, fmt.Errorf("Connection timed out") } if conn.GetState() == connectivity.Ready { glog.V(3).Infof("Connected") @@ -185,34 +186,19 @@ func supportsControllerCreateVolume(conn *grpc.ClientConn, timeout time.Duration return false, nil } -func NewCSIProvisioner(client kubernetes.Interface, csiEndpoint string, connectionTimeout time.Duration, identity string, volumeNamePrefix string, volumeNameUUIDLength int) controller.Provisioner { - grpcClient, err := connect(csiEndpoint, connectionTimeout) - if err != nil || grpcClient == nil { - glog.Fatalf("failed to connect to csi endpoint :%v", err) - } - ok, err := supportsPluginControllerService(grpcClient, connectionTimeout) - if err != nil { - glog.Fatalf("failed to get support info :%v", err) - } - if !ok { - glog.Fatalf("no plugin controller service support detected") - } - ok, err = supportsControllerCreateVolume(grpcClient, connectionTimeout) - if err != nil { - glog.Fatalf("failed to get support info :%v", err) - } - if !ok { - glog.Fatalf("no create/delete volume support detected") - } - driver, err := getDriverName(grpcClient, connectionTimeout) - if err != nil { - glog.Fatalf("failed to get driver info :%v", err) - } +// NewCSIProvisioner creates new CSI provisioner +func NewCSIProvisioner(client kubernetes.Interface, + csiEndpoint string, + connectionTimeout time.Duration, + identity string, + volumeNamePrefix string, + volumeNameUUIDLength int, + grpcClient *grpc.ClientConn) controller.Provisioner { csiClient := csi.NewControllerClient(grpcClient) provisioner := &csiProvisioner{ client: client, - driverName: driver, + grpcClient: grpcClient, csiClient: csiClient, timeout: connectionTimeout, identity: identity, @@ -222,10 +208,45 @@ func NewCSIProvisioner(client kubernetes.Interface, csiEndpoint string, connecti return provisioner } +// This function get called before any attepmt to communicate with the driver. +// Before initiating Create/Delete API calls provisioner checks if Capabilities: +// PluginControllerService, ControllerCreateVolume sre supported and gets the driver name. +func checkDriverState(grpcClient *grpc.ClientConn, timeout time.Duration) (string, error) { + ok, err := supportsPluginControllerService(grpcClient, timeout) + if err != nil { + glog.Errorf("failed to get support info :%v", err) + return "", err + } + if !ok { + glog.Errorf("no plugin controller service support detected") + return "", fmt.Errorf("no plugin controller service support detected") + } + ok, err = supportsControllerCreateVolume(grpcClient, timeout) + if err != nil { + glog.Errorf("failed to get support info :%v", err) + return "", err + } + if !ok { + glog.Error("no create/delete volume support detected") + return "", fmt.Errorf("no create/delete volume support detected") + } + driverName, err := getDriverName(grpcClient, timeout) + if err != nil { + glog.Errorf("failed to get driver info :%v", err) + return "", err + } + return driverName, nil +} + func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) { if options.PVC.Spec.Selector != nil { return nil, fmt.Errorf("claim Selector is not supported") } + + driverName, err := checkDriverState(p.grpcClient, p.timeout) + if err != nil { + return nil, err + } // create random share name share := fmt.Sprintf("%s-%s", p.volumeNamePrefix, strings.Replace(string(uuid.NewUUID()), "-", "", -1)[0:p.volumeNameUUIDLength]) capacity := options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] @@ -283,7 +304,7 @@ func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis // TODO wait for CSI VolumeSource API PersistentVolumeSource: v1.PersistentVolumeSource{ CSI: &v1.CSIPersistentVolumeSource{ - Driver: p.driverName, + Driver: driverName, VolumeHandle: p.volumeIdToHandle(rep.Volume.Id), VolumeAttributes: volumeAttributes, }, @@ -304,6 +325,11 @@ func (p *csiProvisioner) Delete(volume *v1.PersistentVolume) error { } volumeId := p.volumeHandleToId(volume.Spec.CSI.VolumeHandle) + _, err := checkDriverState(p.grpcClient, p.timeout) + if err != nil { + return err + } + req := csi.DeleteVolumeRequest{ VolumeId: volumeId, } @@ -322,7 +348,7 @@ func (p *csiProvisioner) Delete(volume *v1.PersistentVolume) error { ctx, cancel := context.WithTimeout(context.Background(), p.timeout) defer cancel() - _, err := p.csiClient.DeleteVolume(ctx, &req) + _, err = p.csiClient.DeleteVolume(ctx, &req) return err } diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 5272a282db..afb6ac7de8 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -36,7 +36,7 @@ type csiConnection struct { } func New(address string, timeout time.Duration) (csiConnection, error) { - conn, err := connect(address, timeout) + conn, err := Connect(address, timeout) if err != nil { return csiConnection{}, err } From 9954d5050a8b1767d457f9f5fa1a697c448642ac Mon Sep 17 00:00:00 2001 From: Serguei Bezverkhi Date: Mon, 26 Mar 2018 14:06:02 -0400 Subject: [PATCH 3/3] Adding unit test --- pkg/controller/controller_test.go | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index afb6ac7de8..dc8efc5d10 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -70,6 +70,64 @@ func createMockServer(t *testing.T) (*gomock.Controller, return mockController, drv, identityServer, controllerServer, csiConn, nil } +func TestGetPluginName(t *testing.T) { + test := struct { + name string + output []*csi.GetPluginInfoResponse + }{ + name: "success", + output: []*csi.GetPluginInfoResponse{ + { + Name: "csi/example-1", + VendorVersion: "0.2.0", + Manifest: map[string]string{ + "hello": "world", + }, + }, + { + Name: "csi/example-2", + VendorVersion: "0.2.0", + Manifest: map[string]string{ + "hello": "world", + }, + }, + }, + } + + mockController, driver, identityServer, _, csiConn, err := createMockServer(t) + if err != nil { + t.Fatal(err) + } + defer mockController.Finish() + defer driver.Stop() + + in := &csi.GetPluginInfoRequest{} + out := test.output[0] + + identityServer.EXPECT().GetPluginInfo(gomock.Any(), in).Return(out, nil).Times(1) + oldName, err := getDriverName(csiConn.conn, timeout) + if err != nil { + t.Errorf("test %q: Failed to get driver's name", test.name) + } + if oldName != test.output[0].Name { + t.Errorf("test %s: failed, expected %s got %s", test.name, test.output[0].Name, oldName) + } + + out = test.output[1] + identityServer.EXPECT().GetPluginInfo(gomock.Any(), in).Return(out, nil).Times(1) + newName, err := getDriverName(csiConn.conn, timeout) + if err != nil { + t.Errorf("test %s: Failed to get driver's name", test.name) + } + if newName != test.output[1].Name { + t.Errorf("test %q: failed, expected %s got %s", test.name, test.output[1].Name, newName) + } + + if oldName == newName { + t.Errorf("test: %s failed, driver's names should not match", test.name) + } +} + func TestSupportsControllerCreateVolume(t *testing.T) { tests := []struct {